On this page
The Delivery API uses standard HTTP status codes and adds a machine-readable code to most errors. The catalog and playback endpoints return a flat error object with an error_code string; the creatives endpoints return an envelope with a numeric code. This page lists every error each endpoint returns today, what it means and what to do.
Error formats
Catalog and playback
{
"error": "Episode not found or not ready to stream",
"error_code": "not_ready"
}| Field | Type | Description |
|---|---|---|
error |
string | Human-readable message. Log it, but do not parse it, except for the catalog 403 below. |
error_code |
string | Machine-readable code. Branch on this. Absent on some errors, listed below as "none". |
reason |
string | Only with not_entitled: the detailed reason, for logs and support. |
fields |
array of strings | Only with invalid_device_info: which device values were rejected. |
protection |
string | Only with sdk_required: the protection level of the episode. |
Creatives
{
"code": 4011,
"message": "Invalid or revoked API key",
"server_time": 1790679032
}| Field | Type | Description |
|---|---|---|
code |
integer | 0 on success, a four-digit error code otherwise. The first three digits are the HTTP status. |
message |
string | Human-readable message. Do not parse it. |
server_time |
integer | Server time in Unix epoch seconds. |
The one exception is 429: the creatives endpoints return it in the flat format, with error_code rate_limited. See Rate limits.
Handle errors by code
- Branch on
error_code(orcodefor creatives), not on the HTTP status alone. Several different situations share a status. - Always keep a default branch. Wandura may add new codes within
v1, and an app without a default branch shows a blank screen when one appears. - Never show
errorormessagetext to viewers. Map codes to your own copy.
Catalog errors
GET /api/delivery/v1/catalog
| Status | error_code |
Message | Meaning | What to do |
|---|---|---|---|---|
| 401 | none | Missing Bearer API key |
No Authorization: Bearer header. |
Fix the request. Do not retry. |
| 401 | none | Invalid or revoked API key |
The key is unknown or revoked. | Check the key. Do not retry. |
| 403 | none | This API key does not have the metadata:read scope |
The key lacks the scope. | Use a key with metadata:read. |
| 403 | none | org_suspended |
Your organisation's access is suspended. | Contact Wandura. Do not retry. |
| 429 | rate_limited |
Rate limit reached. | Wait for Retry-After. |
|
| 503 | service_unavailable |
Could not verify the API key right now — retry |
Wandura could not check the key in time. The key is not wrong. | Retry after Retry-After seconds, with backoff. Do not rotate the key. |
Playback errors
POST /api/delivery/v1/playback
| Status | error_code |
Meaning | What to do |
|---|---|---|---|
| 400 | none | The body is not valid JSON, or has neither episode_id nor film_ref with a numeric episode_no. |
Fix the request. |
| 400 | invalid_request |
Only one of union_info and drm_kek was sent. |
Send both. |
| 400 | invalid_device_info |
A device value looks empty or invalid, for example the string "(null)". fields names the bad values. |
Fix how your app reads the values from the Player SDK. |
| 401 | none | Missing, invalid or revoked API key. | Check the key. Do not retry. |
| 403 | none | The key lacks the playback scope. |
Use a playback key: create one on Developers → Stream films in an app. |
| 403 | not_entitled |
Your organisation is not licensed to stream this film right now. reason gives the detail. |
Show your locked or unavailable state. Do not retry. |
| 404 | not_ready |
The episode or film is unknown, not published, or not ready to stream. | Show "not available yet". Refresh your catalog. |
| 409 | sdk_required |
The episode is encrypted and the request had no device values. | Resend with union_info and drm_kek. |
| 429 | rate_limited |
Rate limit reached. | Wait for Retry-After. |
| 502 | none | Wandura could not prepare the stream or sign the play token. | Retry with backoff. |
| 503 | not_ready |
No playable version of this episode is available right now. | Show "not available yet". Retry later. |
| 503 | service_unavailable |
Wandura could not check the API key in time. The key is not wrong. | Retry after Retry-After seconds, with backoff. Do not rotate the key. |
| 503 | service_unavailable |
The video provider did not answer in time (playback only). Nothing is wrong with the episode or your key. | Retry after Retry-After seconds (2), with backoff. |
not_entitled reasons
With not_entitled, the reason field says why. Log it and quote it to support, but do not build different screens for each reason: they all mean "not licensed right now", and new reasons may be added.
reason |
Meaning |
|---|---|
org_suspended |
Your organisation's access is suspended. |
entitlement_not_found |
Your organisation has no licence for this film. |
entitlement_suspended |
Your licence for this film is suspended. |
streaming_disabled |
Your licence for this film does not include streaming. |
outside_window |
Today is outside your licence window for this film. |
Creatives errors
GET /api/delivery/v1/creatives and GET /api/delivery/v1/creatives/{id}
| Status | code |
Message | Meaning | What to do |
|---|---|---|---|---|
| 401 | 4010 | Missing Bearer API key |
No Authorization: Bearer header. |
Fix the request. |
| 401 | 4011 | Invalid or revoked API key |
The key is unknown or revoked. | Check the key. Do not retry. |
| 403 | 4030 | This API key does not have the creatives:export scope |
The key lacks the scope. | Use a key with creatives:export. |
| 403 | 4031 | org_suspended |
Your organisation's access is suspended. | Contact Wandura. |
| 404 | 4040 | Creative not found |
GET /creatives/{id} only. The creative does not exist, belongs to another organisation or is not approved. |
Remove it from your active set. |
| 422 | 4220 | limit must be an integer between 1 and 100 |
List only. Bad limit. |
Fix the request. |
| 422 | 4221 | updated_since must be epoch seconds |
List only. Bad updated_since. |
Fix the request. |
| 422 | 4222 | cursor is not valid |
List only. The cursor was changed or truncated. | Restart from your last checkpoint. |
| 429 | none (flat body, error_code rate_limited) |
Rate limit reached. | Wait for Retry-After. |
|
| 503 | 5030 | The creative feed is temporarily unavailable |
Temporary problem on Wandura's side. | Retry with backoff. |
| 503 | 5031 | Could not verify the API key right now — retry |
Wandura could not check the key in time. The key is not wrong. | Retry with backoff. Do not rotate the key. |
Retry guidance
| Situation | Retry? |
|---|---|
400, 401, 403, 409, 422 |
No. Fix the request, the key or the licence first. |
404 / not_ready |
Not immediately. Refresh your catalog and try again later. |
429 |
Yes, after the number of seconds in Retry-After. |
502, 503, other 5xx |
Yes, with exponential backoff and a cap, for example 1 s, 2 s, 4 s, then give up. |
During playback, request a fresh ticket once when the Player SDK fails, then follow this table. See Playback.
Getting help
If an error persists, contact support with the details listed in Support.
Updated 1 Oct 2026 · Change history (5)