Guides
TL;DR — Cache the catalog and open video lists on your server; reuse tickets only per viewer, device, episode and intent until 5 minutes before they expire; cache subtitle files per episode; read
GET /configat start-up. Never put any Delivery API response in a shared cache (CDN, proxy), and never cache an error as if it were data.
What to cache, and for how long
| What | Where | How long | Key | Never |
|---|---|---|---|---|
| Catalog | Your database | Until the next complete sync (15–60 min) | Film id; episode film_id + episode_no |
Replace it with a failed or partial sync |
| Ticket | Memory on your backend, or none (Wandura reuses for you) | Until 5 minutes before expires_at |
viewer + device + episode + intent | Share it across devices, store it on disk, extend it |
| Prefetched ticket on the device | App memory | Until 1 minute before expires_at |
episode | Persist it |
| Open video list | Your server | Until the earliest refresh_before (45 min) |
Video id |
Store links in the app |
| Subtitle files | Your app or backend | Per episode, until a ticket lists another URL | URL | Publish the URLs |
| Configuration | Your backend | Hours; reload at start-up | Key | Hard-code its values instead |
| Creatives | Your database | Forever, overwritten by creative_id |
creative_id |
Use past rights.ends_at |
How fresh Wandura's answers are
Wandura caches too: a change on its side reaches you after a bounded delay (catalog ≤ 30 s, licence checks ≤ 30 s, episodes ≤ 60 s, subtitles ≤ 5 min). All bounds, and what happens during an incident: Canonical API behaviour · Freshness.
Rules
- Errors are not data. A
503, a timeout or a429never replaces something you had. - No shared caches. Tickets, signed links and your catalog belong to your organisation. Every Delivery API response says
Cache-Control: no-store. See Canonical API behaviour · Caching headers. - Use server time. Compare
expires_atwith your server clock (synchronised), not a device clock.
Related
Updated 2 Oct 2026 · Change history (2)