Bản lưu ngày / Snapshot of 2026-10-05 · Xem bản mới nhất / See the latest version
WanduraDocsBeta
BetaThese docs are in beta and change often. Something wrong, unclear or missing? Tell us.
Concepts

Errors

Markdown
On this page

TL;DR — Branch on error_code (creatives: the numeric code), never on the message. Keep a default branch: an unknown code is handled by its HTTP status class (429 and 5xx retry, other 4xx do not). This page lists every status and code each endpoint returns, with what your app shows and what your backend does. When to retry, and how: the retry policy.

Error formats

Flat format

Catalog, playback, configuration and open video use a flat object:

{
  "error": "Episode not found or not ready to stream",
  "error_code": "not_ready"
}
Field Type Description
error string A message for your logs. Do not show it to viewers and do not parse it, except where a row below says the code is in error.
error_code string The machine-readable code. Branch on it. Absent on a few errors (shown as none below).
reason string With not_entitled, and with 429 prefetch_shed: the detail.
fields array of strings With invalid_device_info: the device values that were rejected.
protection string With sdk_required: the protection level of the episode.
supported_versions, latest_version, upgrade_to With unsupported_version: what you can send instead.

A few 4xx answers carry no error_code and put a stable code in error instead: org_suspended, app_not_registered, collection_not_found and video_not_found. Compare the whole string.

Creatives envelope

The creatives endpoints wrap errors in an envelope with a numeric code. Errors have no data field:

{
  "code": 4011,
  "message": "Invalid or revoked API key",
  "server_time": 1790679032
}

code is four digits: the first three are the HTTP status. Two creatives answers use the flat format instead: 429 rate_limited and 400 unsupported_version.

Request id

Every response carries a Wandura-Request-Id header (for example req_01J9Z3W2N8V4K7D5QX6T0B1C2M), and every JSON error body, flat or envelope, a request_id field with the same value. Log it, and quote it when you contact support: it finds the exact request in Wandura's logs.

Handle errors by code

You received Do
A code listed on this page Follow its row.
An unknown error_code with 429 Wait Retry-After, then retry.
An unknown error_code with another 4xx Do not retry. Show a generic error and alert your engineers.
An unknown error_code with a 5xx Retry with backoff, like 503.
No body, or a body that is not JSON Decide by status class, the same way.

New codes can appear within v1 at any time; an app without a default branch shows a blank screen when one does. Never show error or message to viewers: map codes to your own text.

Retry-After

Sent with every 429, and with the 503s marked "after Retry-After" below. Never retry sooner. 503 not_ready, creatives 503s, 502 and 500 carry none: use backoff.

Messages for viewers

The "Your app shows" column below uses these four messages. Use your own wording.

Message When
Unavailable — "This title is no longer available" The licence is not active.
Not yet — "Not available yet" The episode is not playable right now.
Busy — "Busy, try again in a moment" Retried and still failing temporarily.
Broken — "Couldn't load this episode" A problem in your integration. Alert your engineers.

Every endpoint

Every path

Status Code When Retry? Do
404 not_found Unknown path under /api/delivery/v1/, any method. No Wandura-Version header. No Fix the path.
405 none (empty body) A real path with the wrong method, for example GET /playback. The Allow header lists the right one. No Fix the method.

Catalog

GET /api/delivery/v1/catalog

Status Code When Retry? Your app shows Your backend does
400 invalid_request limit is not 1–200, or cursor was changed. No — Fix the request. Restart the walk from page one.
400 unsupported_version The Wandura-Version header, or your key's pin, is unknown or retired. No — Send a supported version; see Migrating versions.
401 none Header missing, or key unknown or revoked. No — Check the key. Keep your previous catalog.
403 none The key lacks metadata:read. No — Use a key with that scope.
403 org_suspended (in error) Your organisation is suspended. No — Keep your copy, stop selling, contact Wandura.
429 rate_limited Catalog limit reached. After Retry-After — Wait, then find the loop.
503 service_unavailable Wandura could not check the key in time. The key is fine. After Retry-After — Retry. Never rotate the key for this.
503 service_unavailable Wandura could not read the catalog in time (Could not read the catalog in time — retry). After Retry-After — Retry. Never treat it as an empty catalog.

List series

GET /api/delivery/v1/series

Status Code When Retry? Your backend does
400 unsupported_version (flat) Unknown or retired dated version. No Send a supported version.
401 4010 No Authorization: Bearer header. No Fix the request.
401 4011 Key unknown or revoked. No Check the key.
403 4030 The key lacks metadata:read. No Use a key with that scope.
403 4031 Your organisation is suspended. No Contact Wandura.
422 4220 limit is not 1–100, updated_since is not epoch seconds, or cursor is not a value this endpoint returned. No Fix the request; restart from your last checkpoint.
429 rate_limited (flat) Catalog limit reached (shared with the catalog). After Retry-After Wait; sync less often.
503 5030 The list is temporarily unavailable. Backoff Retry; keep your checkpoint.
503 5031 Wandura could not check the key in time. Backoff Retry. Do not rotate the key.

Get series metadata

GET /api/delivery/v1/series/{code}

Status Code When Retry? Your backend does
400 unsupported_version (flat) Unknown or retired dated version. No Send a supported version.
401 4010 No Authorization: Bearer header. No Fix the request.
401 4011 Key unknown or revoked. No Check the key.
403 4030 The key lacks metadata:read. No Use a key with that scope.
403 4031 Your organisation is suspended. No Contact Wandura.
404 4040 No such series, or your organisation may not stream it (the same answer on purpose). No Stop showing it; check the list.
429 rate_limited (flat) Catalog limit reached (shared with the catalog). After Retry-After Wait.
503 5030 The series is temporarily unavailable. Backoff Retry.
503 5031 Wandura could not check the key in time. Backoff Retry.

List playlists

GET /api/delivery/v1/playlists

Status Code When Retry? Your backend does
400 unsupported_version (flat) Unknown or retired dated version. No Send a supported version.
401 4010 No Authorization: Bearer header. No Fix the request.
401 4011 Key unknown or revoked. No Check the key.
403 4030 The key lacks metadata:read. No Use a key with that scope.
403 4031 Your organisation is suspended. No Contact Wandura.
403 4032 Your organisation licenses films, not video. No Use List series.
404 4040 The category is not in the library. No Check the Category slug.
422 4220 limit is not 1–100, updated_since is not epoch seconds, category is not a slug, or cursor is not a value this endpoint returned. No Fix the request; restart from your last checkpoint.
429 rate_limited (flat) Catalog limit reached (shared with the catalog). After Retry-After Wait; sync less often.
503 5030 The list is temporarily unavailable. Backoff Retry; keep your checkpoint.
503 5031 Wandura could not check the key in time. Backoff Retry. Do not rotate the key.

Get playlist metadata

GET /api/delivery/v1/playlists/{code}

Status Code When Retry? Your backend does
400 unsupported_version (flat) Unknown or retired dated version. No Send a supported version.
401 4010 No Authorization: Bearer header. No Fix the request.
401 4011 Key unknown or revoked. No Check the key.
403 4030 The key lacks metadata:read. No Use a key with that scope.
403 4031 Your organisation is suspended. No Contact Wandura.
403 4032 Your organisation licenses films, not video. No Use Get series metadata.
404 4040 No such playlist, or it is no longer in the library (the same answer on purpose). No Stop showing it; check the list.
429 rate_limited (flat) Catalog limit reached (shared with the catalog). After Retry-After Wait.
503 5030 The playlist is temporarily unavailable. Backoff Retry.
503 5031 Wandura could not check the key in time. Backoff Retry.

Playback

POST /api/delivery/v1/playback. In a batch, the request-level rows answer the whole request; the per-ticket rows come back inside items[], each with its own status (and retry_after instead of the header).

Whole request

Status Code When Retry? Your app shows Your backend does
400 none The body is not JSON, or has neither episode_id nor film_ref with a numeric episode_no. No Broken Fix the request.
400 invalid_request Only one of union_info and drm_kek, or a malformed batch. No Broken Fix the request.
400 invalid_device_info A device value is empty-looking, for example "(null)", or under 8 characters. fields names it. No Broken Fix how the app reads the Player SDK values. Alert.
400 unsupported_version Unknown or retired dated version. No Broken See Migrating versions.
401 none Header missing, or key unknown or revoked. No Broken Check the key. Alert.
403 none The key lacks playback. No Broken Use a playback key.
429 rate_limited Playback limit reached for every item. With "reason": "prefetch_shed": prefetch is paused near the limit. After Retry-After Busy (play); nothing (prefetch) Retry plays; drop prefetches. See Rate limits.
503 service_unavailable Wandura could not check the key in time. After Retry-After Busy Retry. Do not rotate the key.
500 none (rare) An unexpected error. The JSON body carries request_id. Backoff Busy Retry once; report it with the request id.

Per ticket (top level for a single episode, or one item of a batch)

Status Code When Retry? Your app shows Your backend does
403 not_entitled Your organisation may not stream this film right now. reason says why (table below). No Unavailable Log reason. Stop selling the film once your next catalog sync confirms it is gone.
404 not_ready The episode or film is unknown, not published or not ready. No Not yet Refresh your catalog.
409 sdk_required Encrypted episode and no device values. No Broken Send union_info and drm_kek. Alert.
429 rate_limited This item could not be admitted (batch only). reason prefetch_shed for a paused prefetch. After retry_after Nothing for a prefetch Retry this item only.
502 none The stream could not be prepared, or the play token could not be signed. Backoff Busy Retry, then report.
503 not_ready No playable version of the episode right now. No Retry-After. Not now Not yet Try again later (next play or sync).
503 service_unavailable The video provider did not answer in time (The video provider did not answer in time — retry). After Retry-After (2 s) Busy Retry. The episode is not missing.
503 service_unavailable The ticket could not be issued right now (Could not issue this grant right now — retry). After Retry-After Busy Retry.

Do not take irreversible steps on one answer. Before you stop selling a film or refund viewers because of not_entitled or not_ready, confirm it with your next catalog sync: a withdrawn film disappears from the catalog.

If Wandura cannot check your licence or the episode in time while issuing a ticket, it answers 503 service_unavailable (Could not check the licence or episode right now — retry) with Retry-After, never 404 or 403. Keep selling, and retry.

not_entitled reasons

Log reason and quote it to support, but show the same screen for all of them: 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 (UTC) is outside your licence window.

Configuration

GET /api/delivery/v1/config

Status Code When Retry? Your backend does
400 unsupported_version Unknown or retired dated version. No Send a supported version.
401 none Header missing, or key unknown or revoked. No Check the key.
403 org_suspended (in error) Your organisation is suspended. No Contact Wandura.
429 rate_limited Configuration limit reached. After Retry-After Read it less often: at start-up or every few hours.
503 service_unavailable Wandura could not check the key in time. After Retry-After Retry; keep the configuration you had.
503 service_unavailable Wandura could not read your configuration in time (Could not read your configuration in time — retry). After Retry-After Retry; keep the configuration you had.

List creatives

GET /api/delivery/v1/creatives

Status Code When Retry? Your backend does
400 unsupported_version (flat) Unknown or retired dated version. No Send a supported version.
401 4010 No Authorization: Bearer header. No Fix the request.
401 4011 Key unknown or revoked. No Check the key.
403 4030 The key lacks creatives:export. No Use a key with that scope.
403 4031 Your organisation is suspended. No Contact Wandura.
422 4220 limit is not 1–100 (an empty limit= counts as 0). No Fix the request.
422 4221 updated_since is not epoch seconds. No Fix the request.
422 4222 cursor is not valid. No Restart from your last checkpoint.
429 rate_limited (flat) Creatives limit reached. After Retry-After Wait; sync less often.
503 5030 The feed is temporarily unavailable. Backoff Retry; keep your checkpoint.
503 5031 Wandura could not check the key in time. Backoff Retry. Do not rotate the key.

Get a creative

GET /api/delivery/v1/creatives/{id}

Status Code When Retry? Your backend does
400 unsupported_version (flat) Unknown or retired dated version. No Send a supported version.
401 4010 No Authorization: Bearer header. No Fix the request.
401 4011 Key unknown or revoked. No Check the key.
403 4030 The key lacks creatives:export. No Use a key with that scope.
403 4031 Your organisation is suspended. No Contact Wandura.
404 4040 No approved creative with this ID for your organisation (also: the ID is not a UUID). No Remove it from your active set.
429 rate_limited (flat) Creatives limit reached (shared with the list). After Retry-After Wait.
503 5030 The feed is temporarily unavailable. Backoff Retry.
503 5031 Wandura could not check the key in time. Backoff Retry.

List open videos

GET /api/delivery/v1/videos

Status Code When Retry? Your backend does
400 none cursor is not a token this endpoint issued, or limit is not 1–200. No Fix the request; restart the sweep.
400 unsupported_version Unknown or retired dated version. No Send a supported version.
401 none Header missing, or key unknown or revoked. No Check the key.
403 none The key lacks videos:read. No Use the app's open video key.
403 app_not_registered (in error) The key is not bound to an app. No Register the app; use that app's key.
403 org_suspended (in error) Your organisation is suspended. No Contact Wandura.
404 collection_not_found (in error) Unknown, unpublished or not granted to you. No Check the collection code.
429 rate_limited List limit reached. After Retry-After Wait; cache the list.
500 none The list could not be read. Backoff Retry; keep serving your previous list.
503 service_unavailable Wandura could not check the key in time. After Retry-After Retry.

Get one open video

GET /api/delivery/v1/videos/{id}

Status Code When Retry? Your backend does
400 none id is not a UUID. No Use the id from the list.
400 unsupported_version Unknown or retired dated version. No Send a supported version.
401 none Header missing, or key unknown or revoked. No Check the key.
403 none The key lacks videos:read. No Use the app's open video key.
403 app_not_registered (in error) The key is not bound to an app. No Register the app.
403 org_suspended (in error) Your organisation is suspended. No Contact Wandura.
404 video_not_found (in error) Unknown, not granted, unpublished, archived or not playable yet. No Drop it from your list.
429 rate_limited Single-video limit reached (its own counter). After Retry-After Wait; prefer the cached list.
500 none The video could not be read. Backoff Retry.
503 service_unavailable Wandura could not check the key in time. After Retry-After Retry.

Updated 5 Oct 2026 · Change history (10)

↑↓ selectEnter openEsc close

Send feedback

Your message goes straight to the Wandura team. It includes the address of this page.

0 / 4000