# Caching & freshness

Onekey remembers recent answers. That makes repeat calls fast and free, and it protects the source platforms from being hammered. Three fields in `metadata` tell you what you got.

| Field | Meaning |
| --- | --- |
| `cached` | `false`: fetched fresh for you. `true`: served from Onekey's memory. |
| `stale` | `true`: the copy is older than its fresh window. You still get it instantly; Onekey refreshes it in the background so the next call is fresh. |
| `age_s` | How old the data is, in seconds. |

## The life of a cached answer

Each endpoint has its own windows, shown on its page (profiles live longer than searches, live feeds shortest).

1. **Fresh.** Younger than the fresh window. Served from cache, free, `stale: false`.
2. **Stale.** Older than the fresh window, but not expired. Served instantly and free with `stale: true`, and refreshed in the background.
3. **Expired.** Too old. Your call fetches fresh and pays the full price.
4. **Source down.** If a refresh fails and a recent-enough copy exists, you get that copy (`stale: true`) instead of an error. If not, you get a `502` and are not charged.

## Not found is remembered too

A record that does not exist is cached as "not found" for 1 minute on most endpoints and 5 minutes on some; each endpoint page states its own window. Repeating the lookup returns `404` immediately and free.

## Sharing

Most endpoints share one cache across customers, which is why repeat lookups are cheap for everyone. Simultaneous identical requests are merged into a single fetch.

## Tips

- Need to know how fresh something is? Read `age_s` or `fetched_at`.
- If `stale: true` matters to you (for example live prices), treat it as a signal to retry in a few seconds.

## Coming soon

- A way to force a fresh fetch on a single call.
- Per-request cache control.
