*REST API › Guides*

# Responses

> Successful responses wrap their payload in `data`; lists add `pagination`; a few operations add `meta`; errors are RFC 9457 problems. API responses share one set of headers.

## Envelope variants

### List

A list returns its records in `data` and the paging state in `pagination`. `nextCursor` is `null` on the last page. `total` appears only when you ask for it with [`includeTotal`](https://docs.filmo.io/rest-api/endpoint-reference/orders/list-orders#param-includeTotal).

*GET /api/v1/orders?limit=1 (trimmed to a few fields)*

```json
{
  "data": [
    {
      "id": "5e8d1a9c",
      "orderNumber": "ORD-0412",
      "status": "reserved",
      "startDate": "2026-10-17T08:00:00.000Z",
      "endDate": "2026-10-19T17:00:00.000Z",
      "contact": { "id": "c71f40b2", "name": "Acme Rentals" },
      "grossPrice": "1234.50"
    }
  ],
  "pagination": { "nextCursor": "opaque-cursor", "hasMore": true }
}
```

### Single resource

A detail read, a create and an update return the resource in `data`. Operations that create a resource answer 201; reads and updates answer 200.

### Resource with meta

A few operations also tell you what the call did to other records, in `meta`. [`POST /api/v1/orders/{orderId}/reserve`](https://docs.filmo.io/rest-api/endpoint-reference/orders/reserve-an-order) reports `meta.tasksCreated`, the delivery and return tasks the reservation created; [`POST /api/v1/orders/{orderId}/cancel`](https://docs.filmo.io/rest-api/endpoint-reference/orders/cancel-an-order) reports `meta.tasksDeleted`. Both return the full order in `data`.

### No body

Most deletes and the two archive operations ([`PUT /api/v1/orders/{orderId}/archive`](https://docs.filmo.io/rest-api/endpoint-reference/orders/archive-or-restore-an-order) and [`PUT /api/v1/projects/{projectId}/archive`](https://docs.filmo.io/rest-api/endpoint-reference/projects/archive-or-restore-a-project)) answer 204 with no body. Four deletes answer 200 and return the record they changed instead: [`DELETE /api/v1/contacts/{contactId}/addresses/{addressId}`](https://docs.filmo.io/rest-api/endpoint-reference/contacts/remove-an-address-from-a-contact) and [`DELETE /api/v1/contacts/{contactId}/related-contacts/{relatedContactId}`](https://docs.filmo.io/rest-api/endpoint-reference/contacts/unrelate-two-contacts) return the contact, [`DELETE /api/v1/tags/{tagId}/assignments`](https://docs.filmo.io/rest-api/endpoint-reference/tags/remove-a-tag-from-an-entity) returns the result of the unassignment and [`DELETE /api/v1/projects/{projectId}/orders/{orderId}`](https://docs.filmo.io/rest-api/endpoint-reference/projects/unlink-an-order-from-a-project) returns the project. A conditional read whose `ETag` is current answers 304, also without a body.

### Batch results

[`POST /api/v1/orders/line-items/returns`](https://docs.filmo.io/rest-api/endpoint-reference/orders/return-order-lines) is a batch. It answers 200 with one result per element, in request order. With `atomic: false` it answers 207 and each element carries its own `status` and `error`. See the retry table in [Errors](https://docs.filmo.io/rest-api/guides/errors#retry).

### Errors

Errors are `application/problem+json` and carry `type`, `title`, `status`, `code`, `detail` and `requestId`, plus `errors`, `requiredScope`, `requiredAddon` or `retryAfter` when they apply. They are described in [Errors](https://docs.filmo.io/rest-api/guides/errors).

## Response headers

These headers come from the OpenAPI document, plus the standard `Date`.

| Header | Where | What it tells you |
| --- | --- | --- |
| `X-Request-Id` | Every API response. Not the OAuth endpoints, and not the 401 of the MCP discovery | The identifier of the request (`req_…`), generated by the server. Error bodies repeat it as `requestId`; the 401 of the MCP endpoint carries it only in the body. Log it and quote it to support. |
| `RateLimit-Limit` | Every response that consumed quota (all but a 401 and a 403 `insufficient_scope`) | Requests allowed per minute by the tightest quota the request consumed. |
| `RateLimit-Remaining` | Same | Requests left in the current one-minute window of that quota. |
| `RateLimit-Reset` | Same | Seconds until that window resets. |
| `Retry-After` | 429 responses | Seconds to wait before retrying; the 429 problem repeats the value in `retryAfter`. See Rate limits. |
| `ETag` | Detail reads and the writes that return the resource | A strong tag of the representation. Send it back as `If-Match` on a write, or as `If-None-Match` on a read. |
| `Content-Language` | Error responses | The language of `detail` and `errors[].message`, negotiated from `Accept-Language`. |
| `Idempotent-Replay` | Declared by the write operations; present on a response replayed for a repeated `Idempotency-Key` | `true` when this is the stored response of the first attempt, not a new execution. It is absent on the first execution, and a stored error is replayed too. |
| `Date` | Every response | The time on Filmo's servers. Use it, not your own clock, whenever you compute a window for incremental reads. |
| `Deprecation`, `Sunset`, `Link` | Responses of a deprecated operation | Announce that the operation is deprecated, the day it will be removed, and where the notice lives (`rel="deprecation"`). |

The quota headers are explained in [Rate limits](https://docs.filmo.io/rest-api/guides/rate-limits), `Idempotent-Replay` in [Idempotency](https://docs.filmo.io/rest-api/guides/idempotency) and `ETag` in [Concurrency](https://docs.filmo.io/rest-api/guides/concurrency).

## Conditional reads

Detail reads return an `ETag`. Send the one you already hold in `If-None-Match`: if it is still current, the answer is 304 with no body and the `ETag` header, and your copy is current. If the resource changed, you get the full 200 with a new `ETag`.

```bash
# First read: note the ETag header.
curl -sS -D - -o /dev/null "https://app.filmo.io/api/v1/account" \
  -H "Authorization: Bearer $FILMO_API_KEY"

# Later: ask only for a newer version (paste the ETag you received, quotes included).
curl -sS -i "https://app.filmo.io/api/v1/account" \
  -H "Authorization: Bearer $FILMO_API_KEY" \
  -H 'If-None-Match: "<the ETag you received>"'
```

## Warnings in meta

An operation marked deprecated carries `Deprecation` and `Sunset` headers, and every JSON body it returns carries `meta.warnings[]` with an entry whose `code` is `deprecated`. Log those warnings and alert on them: the sunset day is at least six months after the deprecation takes effect. Entries with other codes may be added later; ignore the ones you do not know.

```json
{ "data": { "id": "5e8d1a9c" }, "meta": { "warnings": [{ "code": "deprecated" }] } }
```

## Statuses in use

| Status | Meaning |
| --- | --- |
| 200 | Success. Reads, updates, actions and queries. |
| 201 | A resource was created. |
| 204 | Success with no body: most deletes and the archive operations. Four deletes answer 200 with the changed record. |
| 207 | Partial result of a batch: only `POST /api/v1/orders/line-items/returns` with `atomic: false`. Read the `status` of every element. |
| 304 | Not modified: the `ETag` you sent in `If-None-Match` is current. |
| 400 | `validation_error`: the query or the body is invalid. |
| 401 | The key is missing or unusable: `unauthorized` and the `api_key_*` codes. |
| 402 | `addon_required`: the account lacks the add-on of that module. |
| 403 | `insufficient_scope` or `forbidden`. |
| 404 | `not_found`: it does not exist, or it is outside the tenancy of the key. |
| 409 | `conflict` (its cause is in `errors[0].code`), `contact_in_use`, `address_in_use` or `insufficient_stock`. |
| 412 | `precondition_failed`: `If-Match` did not match. |
| 422 | `idempotency_key_reused`. |
| 429 | `rate_limited`. |
| 500 | `internal_error`. |
| 503 | `service_unavailable`: the feature is switched off for the account. |

## Tolerate what you do not know

Within v1, Filmo adds properties to responses and values to unions such as statuses without notice. Ignore properties you do not use, treat an unknown enum value as unknown rather than as an error, and do not validate responses with a schema that rejects extra properties. Generated clients with closed enums break on additive changes: see [Versioning](https://docs.filmo.io/rest-api/guides/versioning).

---

Canonical URL: https://docs.filmo.io/rest-api/guides/responses  
Last updated: 2026-10-09