# Caching

> **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 /config` at 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](https://docs.wandura.ai/v1/developers/reference/behaviour#freshness).

## Rules
- **Errors are not data.** A `503`, a timeout or a `429` never 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](https://docs.wandura.ai/v1/developers/reference/behaviour#caching-headers).
- **Use server time.** Compare `expires_at` with your server clock (synchronised), not a device clock.

## Related
- [Catalog sync](https://docs.wandura.ai/v1/developers/guides/catalog-sync), [Open video sync](https://docs.wandura.ai/v1/developers/guides/open-video-sync)
