Bản lưu ngày / Snapshot of 2026-10-11 · 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.
Change history

History: Rate limits

Every change to this page, newest first. Expand an entry to see what changed.

← Rate limits

  1. 2 Oct 2026 · +1 −1 lines
    Show changes
    ⋯
      3. If your **normal** traffic reaches a ceiling, ask in your team's Wandura Discord channel to raise it for your organisation. A raised limit takes effect within about a minute.
      
    - > **Rolling out.** Wandura receives an alert, in a private channel, when your organisation reaches its playback ceiling.
    + Wandura monitors organisations that reach their playback ceiling. Still tell Wandura in your channel when your normal traffic does: that is how a limit gets raised.
      
      Retry rules for every answer: [the retry policy](../reference/behaviour.md#retries).
    ⋯
  2. 2 Oct 2026 · +36 −44 lines
    Show changes
      # Rate limits
      
    - The Delivery API applies an abuse ceiling per organisation. The ceiling is set far above the traffic of a normal integration, so reaching it usually means a runaway loop or a retry storm. This page explains how the ceiling is counted, what the API returns when you reach it and how to recover.
    - 
    - ## How requests are counted
    - 
    - - **Per organisation.** Requests are counted for your organisation as a whole, not per key. Creating more keys does not raise your ceiling.
    - - **Per endpoint group.** Playback, the catalog and the creatives endpoints each have their own counter, so a runaway creatives sync cannot block your catalog.
    - - **Refilled every second.** Playback and the catalog refill your allowance continuously, by one sixtieth of the limit each second. The creatives endpoints use fixed windows that reset at the start of each window.
    - - **Authenticated requests only.** A request with a missing or invalid key is rejected before it is counted, so nobody else can use up your ceiling.
    + > **TL;DR** — Each organisation has an abuse ceiling per endpoint counter, far above normal traffic. Playback counts **tickets**, not requests, and refills every second. Near the ceiling Wandura slows down instead of failing: prefetches are refused first, a `play` request may wait half a second, and repeat requests get the ticket already issued. On a `429`, wait `Retry-After`. The numbers: [Canonical API behaviour · Rate limits](../reference/behaviour.md#rate-limits).
      
    - Every ticket request counts toward the playback ceiling, including requests with `"intent": "prefetch"`. A request that is answered with a ticket Wandura already issued (see [Graceful overload](#graceful-overload)) is not counted, and a refused request does not use up your allowance.
    + ## How it is counted {#how-requests-are-counted}
      
    - ## Current limits {#limits}
    + - **Per organisation**, not per key: more keys do not raise the ceiling.
    + - **Per counter**: playback, catalog, creatives, open video list, single open video and configuration each have their own, so a runaway job on one cannot block another.
    + - **In the counter's unit**: playback counts tickets (a batch of 3 counts 3; a reused ticket counts 0; a refused ticket counts 0); the others count requests.
    + - **Only valid keys** are counted: nobody without your key can use up your ceiling. Anyone who can drive **your** ticket endpoint can, though: limit tickets per viewer on your side ([Security](security.md#trust-boundary)).
      
    - | Endpoint group | Limit per organisation | Window |
    - |---|---|---|
    - | Playback: `POST /api/delivery/v1/playback` | 10,800 requests (about 180 tickets per second) | 60 seconds |
    - | Catalog: `GET /api/delivery/v1/catalog` | 3,000 requests | 60 seconds |
    - | Creatives: `GET /api/delivery/v1/creatives`, `GET /api/delivery/v1/creatives/{id}` (one counter for both) | 3,000 requests | 60 seconds |
    + The limit values per counter, units included, are in one table: [Canonical API behaviour · Rate limits](../reference/behaviour.md#rate-limits). `GET /config` returns the limits that apply to your organisation.
      
    - Playback and the catalog have no minute boundary: the allowance refills every second (see [Graceful overload](#graceful-overload)). The creatives counter uses clock-minute windows (UTC), so its count starts again at every whole minute. One viewer starting an episode usually costs about three playback tickets (the episode itself plus prefetches), so the playback limit is roughly 60 viewers starting an episode every second.
    + ## Refill {#refill}
      
    - The count is approximate on the high side: Wandura's servers count in small batches, so a burst can get a few requests past a limit (at most about 2.5 % with normal traffic) before the `429` starts.
    + | Counters | How the allowance comes back |
    + |---|---|
    + | `playback`, `catalog` | **Continuously**: one sixtieth of the limit every second. From idle you can spend a full minute's worth at once; after that, room comes back second by second, so `Retry-After` is usually **1–2 seconds**. |
    + | `creatives`, `videos`, `video`, `config` | **Per clock minute (UTC)**: the count starts again at every whole minute; `Retry-After` is the rest of the minute. |
      
    - Wandura can raise any of these limits for your organisation alone: ask in your team's Wandura Discord channel. A raised limit takes effect within about a minute, with no change on your side. Wandura is also alerted when an organisation reaches its playback limit. On a `429`, the `X-RateLimit-Limit` header shows the limit that applies to you.
    + Counting is approximate on the high side: a burst can get up to about 2.5 % past a limit before the `429` starts.
      
      ## Graceful overload {#graceful-overload}
      
    - Close to and above the ceiling, Wandura slows down instead of failing, and it protects the episode a viewer has just tapped:
    + Close to the playback ceiling, Wandura protects the episode a viewer has just tapped:
      
      | Situation | What happens |
      |---|---|
    - | You use up your playback allowance | The allowance **refills every second** (the limit divided by 60), instead of once a minute. `Retry-After` says how long until there is room again, usually **1–2 seconds**. From idle you can still send a full minute's limit at once. |
    - | Your playback traffic is close to the limit | **Prefetch is paused first.** When less than about 20 % of your allowance is left, requests with `"intent": "prefetch"` get `429` `rate_limited` with `"reason": "prefetch_shed"`, while requests for episodes a viewer has just tapped (`"intent": "play"`, or no `intent`) are still issued. |
    - | A batch has more items than there is room for | Prefetch items are refused first. Each item that cannot be issued gets its own `"status": 429` and `retry_after` (with `"reason": "prefetch_shed"` for a paused prefetch), and the other items get their tickets. The request itself is `429` only when nothing in it can be issued. |
    - | A `play` request arrives a few hundred milliseconds before there is room | Wandura **holds it for up to about 0.5 seconds** and then issues the ticket, instead of answering `429`. Allow at least 5 seconds of client timeout. Prefetch requests are never held. |
    - | The same viewer asks again for the same episode | If you send `viewer_ref`, a repeat request with the same `viewer_ref`, episode, intent and device values, while the earlier ticket still has at least 5 minutes left, gets **that same ticket** (same `expires_at`, not extended). It is not counted toward your limit. See [Playback](playback.md#viewer-ref). |
    + | Less than about 20 % of your playback allowance left | Requests with `"intent": "prefetch"` get `429` `rate_limited` with `"reason": "prefetch_shed"`. `play` requests are still issued. |
    + | A batch with more items than there is room for | Prefetch items are refused first, each with its own `429` and `retry_after`; the others get tickets. The request is `429` as a whole only when no item can be issued. |
    + | A `play` request arrives a few hundred milliseconds before there is room | Wandura holds it up to about **0.5 seconds**, then issues it. Allow at least 5 seconds of client timeout. Prefetches are never held. |
    + | The same viewer asks again for the same episode on the same device | The ticket already issued comes back, not counted (needs `viewer_ref`; see [Playback](playback.md#viewer-ref)). |
      
      A paused prefetch answers:
    ⋯
      ```
      
    - Treat it like any `429`: it is not an error for the viewer. Request the episode again with `"intent": "play"` when the viewer taps it. The catalog limit refills every second in the same way; catalog requests are never held.
    + It is not an error for the viewer: request the episode with `"intent": "play"` when the viewer taps it.
      
    - ## When you reach the ceiling
    + ## When you reach the ceiling {#when-you-reach-the-ceiling}
      
    - Every endpoint answers `429 Too Many Requests` with a flat error body, including the creatives endpoints:
    + Every endpoint answers `429` with a flat body, the creatives endpoints included:
      
      ```json
      {
    -   "error": "Too many playback requests for this account. This is an abuse ceiling, not a quota — if a normal integration reaches it, contact us and it will be raised.",
    +   "error": "Too many catalog requests for this account. This is an abuse ceiling, not a quota — if a normal integration reaches it, contact us and it will be raised.",
        "error_code": "rate_limited"
      }
      ```
      
    - The response carries these headers:
    - 
    - | Header | Description |
    + | Header (on `429` only) | Meaning |
      |---|---|
    - | `Retry-After` | Seconds until enough allowance has refilled, usually 1–2. On the creatives endpoints, seconds until the current window resets. |
    - | `X-RateLimit-Limit` | Requests allowed per window for this endpoint group. |
    - | `X-RateLimit-Window` | Window length in seconds. |
    + | `Retry-After` | Seconds until there is room again. |
    + | `X-RateLimit-Limit` | The limit of this counter for your organisation, per window (playback: tickets). |
    + | `X-RateLimit-Window` | The window, in seconds (60). |
      
    - The limit headers appear only on `429` responses.
    + ## How to recover {#how-to-recover}
      
    - ## How to recover
    + 1. Stop sending to that counter until `Retry-After` has passed, plus a random 0–1 s. Earlier retries only earn more `429`s.
    + 2. Find the cause: a retry loop without backoff, a job that requests tickets for a whole catalog, catalog calls on every app launch.
    + 3. If your **normal** traffic reaches a ceiling, ask in your team's Wandura Discord channel to raise it for your organisation. A raised limit takes effect within about a minute.
      
    - 1. Stop sending requests to that endpoint group until `Retry-After` has passed. Retrying earlier only returns more `429`s.
    - 2. Look for the cause: a retry loop without backoff, a job that requests tickets for a whole catalog, or catalog calls made on every app launch instead of from a server-side cache.
    - 3. If your normal traffic reaches the ceiling, ask in your team's Wandura Discord channel to have it raised.
    + > **Rolling out.** Wandura receives an alert, in a private channel, when your organisation reaches its playback ceiling.
      
    - ## Good habits
    + Retry rules for every answer: [the retry policy](../reference/behaviour.md#retries).
      
    - - Cache the catalog on your server and refresh it on a schedule.
    - - Request playback tickets only when a viewer starts, or is about to start, an episode.
    - - Sync the creatives feed incrementally with `updated_since`.
    - - Use exponential backoff with jitter for `5xx` responses. See [Smooth playback under load](../guides/smooth-playback.md).
    + ## Related {#related}
    + 
    + - [Smooth playback under load](../guides/smooth-playback.md)
    + - [Go-live checklist](../production/go-live.md): the limit review before launch.
  3. 2 Oct 2026 · +4 −6 lines
    Show changes
    ⋯
      - **Per organisation.** Requests are counted for your organisation as a whole, not per key. Creating more keys does not raise your ceiling.
      - **Per endpoint group.** Playback, the catalog and the creatives endpoints each have their own counter, so a runaway creatives sync cannot block your catalog.
    - - **Fixed windows.** Counts reset at the start of each window.
    + - **Refilled every second.** Playback and the catalog refill your allowance continuously, by one sixtieth of the limit each second. The creatives endpoints use fixed windows that reset at the start of each window.
      - **Authenticated requests only.** A request with a missing or invalid key is rejected before it is counted, so nobody else can use up your ceiling.
      
    - Every ticket request counts toward the playback ceiling, including requests with `"intent": "prefetch"`. **Rolling out:** a request that is answered with a ticket Wandura already issued (see [Graceful overload](#graceful-overload)) is not counted, and a refused request does not use up your allowance.
    + Every ticket request counts toward the playback ceiling, including requests with `"intent": "prefetch"`. A request that is answered with a ticket Wandura already issued (see [Graceful overload](#graceful-overload)) is not counted, and a refused request does not use up your allowance.
      
      ## Current limits {#limits}
    ⋯
      | Creatives: `GET /api/delivery/v1/creatives`, `GET /api/delivery/v1/creatives/{id}` (one counter for both) | 3,000 requests | 60 seconds |
      
    - Each window is one clock minute (UTC), so a count starts again at every whole minute. One viewer starting an episode usually costs about three playback tickets (the episode itself plus prefetches), so the playback limit is roughly 60 viewers starting an episode every second.
    + Playback and the catalog have no minute boundary: the allowance refills every second (see [Graceful overload](#graceful-overload)). The creatives counter uses clock-minute windows (UTC), so its count starts again at every whole minute. One viewer starting an episode usually costs about three playback tickets (the episode itself plus prefetches), so the playback limit is roughly 60 viewers starting an episode every second.
      
      The count is approximate on the high side: Wandura's servers count in small batches, so a burst can get a few requests past a limit (at most about 2.5 % with normal traffic) before the `429` starts.
    ⋯
      ## Graceful overload {#graceful-overload}
      
    - > **Rolling out — not live yet.** The behaviour in this section is being deployed. This page will drop the label when it is live. Until then the [current limits](#limits) work as described above. Code written for the [Smooth playback under load](../guides/smooth-playback.md) guide works both before and after.
    - 
      Close to and above the ceiling, Wandura slows down instead of failing, and it protects the episode a viewer has just tapped:
      
    ⋯
      | Header | Description |
      |---|---|
    - | `Retry-After` | Seconds until the current window resets. **Rolling out:** seconds until enough allowance has refilled, usually 1–2. |
    + | `Retry-After` | Seconds until enough allowance has refilled, usually 1–2. On the creatives endpoints, seconds until the current window resets. |
      | `X-RateLimit-Limit` | Requests allowed per window for this endpoint group. |
      | `X-RateLimit-Window` | Window length in seconds. |
    ⋯
  4. 2 Oct 2026 · +28 −2 lines
    Show changes
    ⋯
      - **Authenticated requests only.** A request with a missing or invalid key is rejected before it is counted, so nobody else can use up your ceiling.
      
    - Every ticket request counts toward the playback ceiling, including requests with `"intent": "prefetch"`.
    + Every ticket request counts toward the playback ceiling, including requests with `"intent": "prefetch"`. **Rolling out:** a request that is answered with a ticket Wandura already issued (see [Graceful overload](#graceful-overload)) is not counted, and a refused request does not use up your allowance.
      
      ## Current limits {#limits}
    ⋯
      Wandura can raise any of these limits for your organisation alone: ask in your team's Wandura Discord channel. A raised limit takes effect within about a minute, with no change on your side. Wandura is also alerted when an organisation reaches its playback limit. On a `429`, the `X-RateLimit-Limit` header shows the limit that applies to you.
      
    + ## Graceful overload {#graceful-overload}
    + 
    + > **Rolling out — not live yet.** The behaviour in this section is being deployed. This page will drop the label when it is live. Until then the [current limits](#limits) work as described above. Code written for the [Smooth playback under load](../guides/smooth-playback.md) guide works both before and after.
    + 
    + Close to and above the ceiling, Wandura slows down instead of failing, and it protects the episode a viewer has just tapped:
    + 
    + | Situation | What happens |
    + |---|---|
    + | You use up your playback allowance | The allowance **refills every second** (the limit divided by 60), instead of once a minute. `Retry-After` says how long until there is room again, usually **1–2 seconds**. From idle you can still send a full minute's limit at once. |
    + | Your playback traffic is close to the limit | **Prefetch is paused first.** When less than about 20 % of your allowance is left, requests with `"intent": "prefetch"` get `429` `rate_limited` with `"reason": "prefetch_shed"`, while requests for episodes a viewer has just tapped (`"intent": "play"`, or no `intent`) are still issued. |
    + | A batch has more items than there is room for | Prefetch items are refused first. Each item that cannot be issued gets its own `"status": 429` and `retry_after` (with `"reason": "prefetch_shed"` for a paused prefetch), and the other items get their tickets. The request itself is `429` only when nothing in it can be issued. |
    + | A `play` request arrives a few hundred milliseconds before there is room | Wandura **holds it for up to about 0.5 seconds** and then issues the ticket, instead of answering `429`. Allow at least 5 seconds of client timeout. Prefetch requests are never held. |
    + | The same viewer asks again for the same episode | If you send `viewer_ref`, a repeat request with the same `viewer_ref`, episode, intent and device values, while the earlier ticket still has at least 5 minutes left, gets **that same ticket** (same `expires_at`, not extended). It is not counted toward your limit. See [Playback](playback.md#viewer-ref). |
    + 
    + A paused prefetch answers:
    + 
    + ```json
    + {
    +   "error": "Prefetch requests are paused while your playback traffic is close to its ceiling — tickets for viewers who pressed play are still issued. Retry the prefetch after Retry-After, or request it when the viewer plays.",
    +   "error_code": "rate_limited",
    +   "reason": "prefetch_shed"
    + }
    + ```
    + 
    + Treat it like any `429`: it is not an error for the viewer. Request the episode again with `"intent": "play"` when the viewer taps it. The catalog limit refills every second in the same way; catalog requests are never held.
    + 
      ## When you reach the ceiling
      
    ⋯
      | Header | Description |
      |---|---|
    - | `Retry-After` | Seconds until the current window resets. |
    + | `Retry-After` | Seconds until the current window resets. **Rolling out:** seconds until enough allowance has refilled, usually 1–2. |
      | `X-RateLimit-Limit` | Requests allowed per window for this endpoint group. |
      | `X-RateLimit-Window` | Window length in seconds. |
    ⋯
  5. 2 Oct 2026 · +1 −1 lines
    Show changes
    ⋯
      - Request playback tickets only when a viewer starts, or is about to start, an episode.
      - Sync the creatives feed incrementally with `updated_since`.
    - - Use exponential backoff for `5xx` responses.
    + - Use exponential backoff with jitter for `5xx` responses. See [Smooth playback under load](../guides/smooth-playback.md).
  6. 2 Oct 2026 · +2 −0 lines
    Show changes
    ⋯
      Each window is one clock minute (UTC), so a count starts again at every whole minute. One viewer starting an episode usually costs about three playback tickets (the episode itself plus prefetches), so the playback limit is roughly 60 viewers starting an episode every second.
      
    + The count is approximate on the high side: Wandura's servers count in small batches, so a burst can get a few requests past a limit (at most about 2.5 % with normal traffic) before the `429` starts.
    + 
      Wandura can raise any of these limits for your organisation alone: ask in your team's Wandura Discord channel. A raised limit takes effect within about a minute, with no change on your side. Wandura is also alerted when an organisation reaches its playback limit. On a `429`, the `X-RateLimit-Limit` header shows the limit that applies to you.
      
    ⋯
  7. 1 Oct 2026 · +7 −4 lines
    Show changes
    ⋯
      
      - **Per organisation.** Requests are counted for your organisation as a whole, not per key. Creating more keys does not raise your ceiling.
    - - **Per endpoint group.** Playback has its own counter. The catalog and creatives endpoints share a second counter.
    + - **Per endpoint group.** Playback, the catalog and the creatives endpoints each have their own counter, so a runaway creatives sync cannot block your catalog.
      - **Fixed windows.** Counts reset at the start of each window.
      - **Authenticated requests only.** A request with a missing or invalid key is rejected before it is counted, so nobody else can use up your ceiling.
    ⋯
      | Endpoint group | Limit per organisation | Window |
      |---|---|---|
    - | Playback: `POST /api/delivery/v1/playback` | 30,000 requests | 60 seconds |
    - | Catalog and creatives, one shared counter: `GET /api/delivery/v1/catalog`, `GET /api/delivery/v1/creatives`, `GET /api/delivery/v1/creatives/{id}` | 3,000 requests | 60 seconds |
    + | Playback: `POST /api/delivery/v1/playback` | 10,800 requests (about 180 tickets per second) | 60 seconds |
    + | Catalog: `GET /api/delivery/v1/catalog` | 3,000 requests | 60 seconds |
    + | Creatives: `GET /api/delivery/v1/creatives`, `GET /api/delivery/v1/creatives/{id}` (one counter for both) | 3,000 requests | 60 seconds |
      
    - Each window is one clock minute (UTC), so a count starts again at every whole minute. Wandura can raise a limit for your organisation on request: ask in your team's Wandura Discord channel. On a `429`, the `X-RateLimit-Limit` header shows the limit that applies to you.
    + Each window is one clock minute (UTC), so a count starts again at every whole minute. One viewer starting an episode usually costs about three playback tickets (the episode itself plus prefetches), so the playback limit is roughly 60 viewers starting an episode every second.
      
    + Wandura can raise any of these limits for your organisation alone: ask in your team's Wandura Discord channel. A raised limit takes effect within about a minute, with no change on your side. Wandura is also alerted when an organisation reaches its playback limit. On a `429`, the `X-RateLimit-Limit` header shows the limit that applies to you.
    + 
      ## When you reach the ceiling
      
    ⋯
  8. 1 Oct 2026 · +10 −1 lines
    Show changes
    ⋯
      Every ticket request counts toward the playback ceiling, including requests with `"intent": "prefetch"`.
      
    + ## Current limits {#limits}
    + 
    + | Endpoint group | Limit per organisation | Window |
    + |---|---|---|
    + | Playback: `POST /api/delivery/v1/playback` | 30,000 requests | 60 seconds |
    + | Catalog and creatives, one shared counter: `GET /api/delivery/v1/catalog`, `GET /api/delivery/v1/creatives`, `GET /api/delivery/v1/creatives/{id}` | 3,000 requests | 60 seconds |
    + 
    + Each window is one clock minute (UTC), so a count starts again at every whole minute. Wandura can raise a limit for your organisation on request: ask in your team's Wandura Discord channel. On a `429`, the `X-RateLimit-Limit` header shows the limit that applies to you.
    + 
      ## When you reach the ceiling
      
    ⋯
      1. Stop sending requests to that endpoint group until `Retry-After` has passed. Retrying earlier only returns more `429`s.
      2. Look for the cause: a retry loop without backoff, a job that requests tickets for a whole catalog, or catalog calls made on every app launch instead of from a server-side cache.
    - 3. If your normal traffic reaches the ceiling, contact Wandura to have it raised.
    + 3. If your normal traffic reaches the ceiling, ask in your team's Wandura Discord channel to have it raised.
      
      ## Good habits
    ⋯
  9. 1 Oct 2026 · +1 −1 lines
    Show changes
    ⋯
      1. Stop sending requests to that endpoint group until `Retry-After` has passed. Retrying earlier only returns more `429`s.
      2. Look for the cause: a retry loop without backoff, a job that requests tickets for a whole catalog, or catalog calls made on every app launch instead of from a server-side cache.
    - 3. If your normal traffic reaches the ceiling, contact your Wandura partner contact to have it raised.
    + 3. If your normal traffic reaches the ceiling, contact Wandura to have it raised.
      
      ## Good habits
    ⋯
  10. 29 Sept 2026 · Page created
↑↓ selectEnter openEsc close

Send feedback

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

0 / 4000