Change history
Every change to this page, newest first. Expand an entry to see what changed.
- 2 Oct 2026 · +2 −0 lines
Show changes
⋯ | `Wandura-API-Status` | all | API status. `beta` today, on every response, success or error. | | `Wandura-Version` | all | The dated API version (YYYY-MM-DD) this response was produced in: the version pinned to your API key, or the one you sent in the `Wandura-Version` request header. Keys created before dated versions existed use `2026-10-02`. | + | `Wandura-Request-Id` | all | An opaque id for this request (`req_` followed by 26 characters). Every response carries it, errors included, and error bodies repeat it as `request_id`. Log it, and quote it when you contact Wandura about a request: it finds the exact request in our logs. Do not parse it. | + | `Cache-Control` | all | Always `no-store`. Do not cache these responses in shared caches. | | `Deprecation` | 200 | Present only when this endpoint, or the dated version serving this response, is deprecated (RFC 9745): `@<unix seconds>` of the deprecation date. Log it in your monitoring. | | `Sunset` | 200 | Present only when a deprecated endpoint or dated version has a date when it stops working (RFC 8594), as an HTTP date. | ⋯
- 2 Oct 2026 · +3 −4 lines
Show changes
⋯ ## Description - A film is included when your organisation has an active streaming licence for it, today (UTC) is inside the licence window, and the film is published. For each included film, all published episodes are returned, plus a placeholder row for each planned episode that is not published yet. Films arrive sorted by `display_order`. There is no pagination. See [Catalog](../concepts/catalog.md). + A film is included when your organisation has an active streaming licence for it, today (UTC) is inside the licence window, and the film is published. For each included film, all published episodes are returned, plus a placeholder row for each planned episode that is not published yet. Films arrive sorted by `display_order`. Without `limit` and `cursor` you receive the whole catalog in one response; with `limit` you receive pages of films, each with all their episodes, until `next_cursor` is `null`. Pages are not one consistent snapshot: see [Canonical API behaviour · Pagination](behaviour.md#pagination) before you page. See [Catalog](../concepts/catalog.md). ## Request parameters ⋯ | `cursor` | query | string | No | Optional. The `next_cursor` (or the cursor inside `links.next`) of the previous page. Opaque; pass it back unchanged. With a cursor and no `limit` the page size is 50. | | `Wandura-Version` | header | string | No | Optional. A dated API version (YYYY-MM-DD) to use for this request instead of the version pinned to your API key. Unknown or retired values answer 400 with `error_code` `unsupported_version`. | - - This endpoint takes no query parameters. + | `Wandura-Simulate` | header | string | No | Optional, test organisations only. Asks Wandura to answer with a simulated error so you can test how your app handles it, for example `rate_limited`, `service_unavailable` or `not_entitled:outside_window`. The simulated response has the same status, body and headers as the real one, plus a `Wandura-Simulated` header naming the scenario. It issues no ticket and does not count against your rate limits, except `partial_batch`, whose first item is a real ticket. Simulated responses have their own limit of 300 per minute per organisation. Keys of production organisations ignore this header completely. An unknown value, or a scenario this endpoint does not support, is ignored and the request runs normally. See the Testing guide for the list of scenarios. | ## Request example ⋯ The two `403` responses carry no `error_code`. Tell them apart by `error`: it is exactly `org_suspended` when your organisation is suspended, and any other text means the key lacks `metadata:read`. This is the one case where you compare `error`; compare the whole string. - See [Errors](../concepts/errors.md#catalog-errors) for what to do in each case. + What to do in each case: [Errors](../concepts/errors.md#catalog-errors).
- 2 Oct 2026 · +1 −1 lines
Show changes
⋯ | 403 | none (`error` is `org_suspended`) | Your organisation's access is suspended. | | 429 | `rate_limited` | The rate limit for the catalog was reached. | - | 503 | `service_unavailable` | Wandura could not verify the API key in time. The key is not wrong: retry after `Retry-After` seconds, with backoff. | + | 503 | `service_unavailable` | Wandura could not verify the API key or read the catalog in time. Nothing is wrong on your side: retry after `Retry-After` seconds, with backoff. | The two `403` responses carry no `error_code`. Tell them apart by `error`: it is exactly `org_suspended` when your organisation is suspended, and any other text means the key lacks `metadata:read`. This is the one case where you compare `error`; compare the whole string. ⋯
- 2 Oct 2026 · +11 −1 lines
Show changes
⋯ |---|---|---|---|---| | `Authorization` | header | string | Yes | `Bearer <API key>` for a key with the `metadata:read` scope. | + | `limit` | query | integer | No | Optional. Films per page, 1 to 200. Omit it (and `cursor`) to receive the whole catalog in one response. | + | `cursor` | query | string | No | Optional. The `next_cursor` (or the cursor inside `links.next`) of the previous page. Opaque; pass it back unchanged. With a cursor and no `limit` the page size is 50. | + | `Wandura-Version` | header | string | No | Optional. A dated API version (YYYY-MM-DD) to use for this request instead of the version pinned to your API key. Unknown or retired values answer 400 with `error_code` `unsupported_version`. | This endpoint takes no query parameters. ⋯ | `synopsis` | string or null | Episode description. Often `null`. | | `duration_ms` | integer or null | Duration in milliseconds. | - | `poster_uri` | string or null | Episode thumbnail reference. Not guaranteed to be a directly loadable URL. | + | `poster_uri` | string or null | Episode thumbnail reference. Not guaranteed to be a directly loadable URL — use `poster_url`. | + | `poster_url` | string or null | The episode image as an absolute `https` URL you can load directly, or `null` (then use the film's `poster_url`). | | `status` | string | `published`, or `planned` for a placeholder row. | | `stream_ready` | boolean | `true` when a ticket can be issued for the episode. Always `false` on placeholder rows. | ⋯ |---|---|---| | `Wandura-API-Status` | all | API status. `beta` today, on every response, success or error. | + | `Wandura-Version` | all | The dated API version (YYYY-MM-DD) this response was produced in: the version pinned to your API key, or the one you sent in the `Wandura-Version` request header. Keys created before dated versions existed use `2026-10-02`. | + | `Deprecation` | 200 | Present only when this endpoint, or the dated version serving this response, is deprecated (RFC 9745): `@<unix seconds>` of the deprecation date. Log it in your monitoring. | + | `Sunset` | 200 | Present only when a deprecated endpoint or dated version has a date when it stops working (RFC 8594), as an HTTP date. | + | `Link` | 200 | Present with `Deprecation`: `<https://docs.wandura.ai/…>; rel="deprecation"` (and `rel="sunset"`) pointing to the page that explains what to use instead. | | `Retry-After` | 429, 503 | Seconds to wait before retrying. Sent with 429 and with retryable 503 responses. | | `X-RateLimit-Limit` | 429 | Requests (for playback, tickets) allowed per window for this endpoint group and your organisation. | ⋯ | Status | `error_code` | When | |---|---|---| + | 400 | `invalid_request` | `limit` is not a whole number from 1 to 200, or `cursor` is not a value this endpoint returned. | + | 400 | `unsupported_version` | The `Wandura-Version` header, or the version pinned to your key, is unknown or retired. The body adds `supported_versions` and `latest_version` (and `upgrade_to` when your pin was retired). | | 401 | none | The `Authorization: Bearer` header is missing, or the key is unknown or revoked. | | 403 | none | The key lacks the `metadata:read` scope. | ⋯
- 2 Oct 2026 · +14 −5 lines
Show changes
⋯ | Name | In | Type | Required | Description | |---|---|---|---|---| - | `Authorization` | header | string | Yes | `Bearer <API key>`. | + | `Authorization` | header | string | Yes | `Bearer <API key>` for a key with the `metadata:read` scope. | This endpoint takes no query parameters. ⋯ | `planned_episodes` | integer or null | Total number of episodes planned. `null` when not set: then the film gets no placeholder rows, and `episodes` lists only its published episodes. | | `free_until_episode` | integer or null | Episodes with `episode_no` up to and including this number are free. `0` means no free episode. `null` means no number is set for the film: treat every episode as paid, and ask Wandura if you expected free episodes. | - | `audience` | string or null | `women`, `men`, `lgbtq`, or `null` if unclassified. | - | `form` | string or null | `live_action`, `anime`, or `null` if unclassified. | - | `setting` | string or null | `modern`, `city`, `fantasy`, `campus`, `palace`, or `null` if unclassified. | + | `audience` | string or null | `women`, `men`, `lgbtq`, or `null` if unclassified. New values may be added. | + | `form` | string or null | `live_action`, `anime`, or `null` if unclassified. New values may be added. | + | `setting` | string or null | `modern`, `city`, `fantasy`, `campus`, `palace`, or `null` if unclassified. New values may be added. | ### Episode fields (`episodes[]`) ⋯ ``` + ## Response headers {#response-headers} + + | Header | Responses | Description | + |---|---|---| + | `Wandura-API-Status` | all | API status. `beta` today, on every response, success or error. | + | `Retry-After` | 429, 503 | Seconds to wait before retrying. Sent with 429 and with retryable 503 responses. | + | `X-RateLimit-Limit` | 429 | Requests (for playback, tickets) allowed per window for this endpoint group and your organisation. | + | `X-RateLimit-Window` | 429 | Window length in seconds. | + ## Errors {#errors} ⋯ | 403 | none | The key lacks the `metadata:read` scope. | | 403 | none (`error` is `org_suspended`) | Your organisation's access is suspended. | - | 429 | `rate_limited` | The rate limit for the catalog and creatives endpoints was reached. | + | 429 | `rate_limited` | The rate limit for the catalog was reached. | | 503 | `service_unavailable` | Wandura could not verify the API key in time. The key is not wrong: retry after `Retry-After` seconds, with backoff. | ⋯
- 1 Oct 2026 · +10 −7 lines
Show changes
⋯ | Field | Type | Description | |---|---|---| - | `id` | string (UUID) | Film ID. Use it as `film_ref` in playback. | + | `id` | string (UUID) | Film ID. It never changes: use it as your primary key, and as `film_ref` in playback. | | `title` | string | Film title. | - | `slug` | string | URL-safe film identifier. Also accepted as `film_ref` in playback. | + | `slug` | string | URL-safe film identifier, unique across films. Wandura does not change it after the film is created. Also accepted as `film_ref` in playback. | | `synopsis_short` | string or null | Short description for cards. Length varies. | | `synopsis_full` | string or null | Full description for detail pages. | | `genres` | array of strings | Genre labels. Can be empty. | - | `language` | string or null | Language of the film. | + | `language` | string or null | Language of the film, as free text written by Wandura's content team (for example `en` or `English`). It is not a fixed list of codes: display it, do not parse it. | | `poster_url` | string or null | Film poster URL. | | `status` | string | Always `published`. | | `display_order` | integer | Display position, smallest first. The array is already sorted by it. | - | `planned_episodes` | integer or null | Total number of episodes planned. | - | `free_until_episode` | integer or null | Episodes with `episode_no` up to and including this number are free. | + | `planned_episodes` | integer or null | Total number of episodes planned. `null` when not set: then the film gets no placeholder rows, and `episodes` lists only its published episodes. | + | `free_until_episode` | integer or null | Episodes with `episode_no` up to and including this number are free. `0` means no free episode. `null` means no number is set for the film: treat every episode as paid, and ask Wandura if you expected free episodes. | | `audience` | string or null | `women`, `men`, `lgbtq`, or `null` if unclassified. | | `form` | string or null | `live_action`, `anime`, or `null` if unclassified. | ⋯ | `stream_ready` | boolean | `true` when a ticket can be issued for the episode. Always `false` on placeholder rows. | - Episodes are grouped by film ID and sorted by `episode_no` within each film. Take the film order from `films`. + Within a film, each `episode_no` appears once, so `film_id` + `episode_no` identifies an episode. Episodes are grouped by film ID and sorted by `episode_no` within each film. Take the film order from `films`. If your organisation has no current licences, both arrays are empty. ⋯ ``` - ## Errors + ## Errors {#errors} | Status | `error_code` | When | ⋯ | 403 | none (`error` is `org_suspended`) | Your organisation's access is suspended. | | 429 | `rate_limited` | The rate limit for the catalog and creatives endpoints was reached. | + | 503 | `service_unavailable` | Wandura could not verify the API key in time. The key is not wrong: retry after `Retry-After` seconds, with backoff. | + The two `403` responses carry no `error_code`. Tell them apart by `error`: it is exactly `org_suspended` when your organisation is suspended, and any other text means the key lacks `metadata:read`. This is the one case where you compare `error`; compare the whole string. + See [Errors](../concepts/errors.md#catalog-errors) for what to do in each case.
- 29 Sept 2026 · Page created