

## The contract [#the-contract]

Every response carries `meta.cache`. Three values:

| Value   | Meaning                                                                                                                                                         |
| ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `HIT`   | Served from a warm cached copy that is still inside its TTL. Upstream wasn't touched.                                                                           |
| `MISS`  | Fetched fresh for this request.                                                                                                                                 |
| `STALE` | Served a cached copy that is past its TTL while a refresh runs in the background (stale-while-revalidate). The next request typically gets the refreshed value. |

Values are uppercase strings — match on `"HIT"`, not `"hit"`.

The cache is **per-resource**, not per-request. Identical requests collapse onto the same
cached entry. Different query strings (different `?date=`, different filters) live in
different cache lines.

## TTLs [#ttls]

| Resource                   | TTL        |
| -------------------------- | ---------- |
| Live box scores            | 30 seconds |
| Standings (active edition) | 5 minutes  |
| Schedules                  | 6 hours    |
| Final box scores           | 7 days     |
| Teams, players             | 24 hours   |
| Everything else            | 1 hour     |

A cached entry can be served `STALE` for up to one extra TTL past expiry while the refresh
runs; beyond that it is evicted and the next request is a `MISS`.

## Opting out [#opting-out]

There is **no client-side opt-out**. Cache freshness is enforced server-side, and the live
box-score TTL (30 seconds) is tighter than anything you'd negotiate per request.

If you need a guaranteed-fresh read during a live window, poll on the cadence in the
[Data freshness](/docs/getting-started/freshness) table. If you observe staleness beyond
the TTLs on this page, contact support with the `meta.request_id` value.

## Cache and quotas [#cache-and-quotas]

`HIT`, `MISS`, and `STALE` all meter identically against your monthly unit allowance.
We don't refund cache hits — the weight is for the response shape, not the upstream cost.
Plan capacity against the [weights table](/docs/getting-started/quotas).
