Freshness
Every field knows how stale it is allowed to be.
Each field has a time-to-live (TTL) based on how fast it changes. When you call a primitive, any field older than its TTL is refreshed before the answer is returned; fresh fields are served from cache. You do not get silently stale data, and you do not pay to re-fetch something that is still current.
#How it works
Every fact is stored with an expires_at set from its namespace and key TTL. A fact past
that time is marked is_stale. On the next call, the engine triages the requested fields
into missing, stale, and fresh, then refreshes only the missing and stale ones. A refresh
writes a new fact row and supersedes the old one, keeping the confidence and the source.
#TTLs
| Field group | Fields | TTL |
|---|---|---|
| Fast-moving | recent_news | 1 hour |
| Daily | pricing, free_tier, self_serve, mcp_available, claude_compatible, codex_compatible, cursor_compatible | 1 day |
| Weekly | products, funding, technology, executives, api, openapi, cli, sdks, llms_txt, and the readability signals | 7 days |
| Slow-moving | description, categories | 30 days |
See Schemas for the per-field TTL table.
#In the response
Every research response carries a freshness block, one entry per returned field:
"freshness": {
"description": { "observedAt": "2026-08-20T08:02:33.979Z", "stale": false },
"recent_news": { "observedAt": "2026-08-20T08:02:34.548Z", "stale": false }
}A profile reports the same per-fact, with observedAt and stale on each
fact, plus a top-level lastChecked.
#cached vs stale
The cached flag on a research response tells you whether the whole answer came from stored
facts (true) or at least one field was refreshed on this call (false). The per-field
stale flag tells you the freshness state of that field. See Caching
for how repeat calls stay fast and cheap.