Private cache
Your workspace's encrypted cache of what it already fetched. Repeats are free, and partly known records only fetch the missing fields.
Every workspace has its own encrypted cache. Nothing is shared between workspaces: keys include the workspace id, and every value is sealed with AES-256-GCM under a key only that workspace can unwrap.
Two kinds of record
| Kind | Used by | Answers |
|---|---|---|
| Entity | /v1/run, /v1/run/auto, single-stage waterfall runs | Any vendor, field by field, for the same person or company |
| Response | /v1/call on GridRouter's managed vendor accounts | The same endpoint with the same normalized input |
Calls on your own vendor keys never use the response cache, so at launch repeats are answered by the
entity cache through /v1/run and waterfalls.
An entity is found by any identity it carries, strongest first: LinkedIn URL, email, name at domain,
domain, company name. An enrichment by email is found again by LinkedIn URL. Inputs are normalized
first: emails are lowercased with +tags removed, domains reduce to the registrable domain, company
legal suffixes are dropped.
When every wanted field is fresh, the answer is a free hit. When some are, it is a partial: the
route runs and the cached fields fill what the vendors leave empty. A single-stage waterfall skips
the vendors whose fields are already fresh.
Freshness
| Field class | Default TTL | Field class | Default TTL |
|---|---|---|---|
work_email | 90 days | technographics | 14 days |
personal_email | 90 days | signals | 1 day |
phone | 180 days | verification | 30 days |
title | 30 days | social | 30 days |
firmographics | 30 days | other | 30 days |
A value is kept for the shortest of: its class TTL (overridable per workspace), the vendor's data
terms (vendors that forbid storage are never cached), your plan's maximum (30 days on Free) and the
request's ttl_s.
Per request
Set data.cache in the execution options, or use
Cache-Control:
mode | Header | Meaning |
|---|---|---|
prefer (default) | Serve fresh fields, fetch the rest | |
refresh | no-cache | Always fetch, then write |
only | only-if-cached | Never call a vendor; a miss is 404 not_found with details.cache: "miss" |
bypass | no-store | No read, no write |
max_age_s (Cache-Control: max-age=N) is the oldest value this request accepts,
stale_while_revalidate_s serves a stale value while refreshing it in the background, and
write: false reads without writing.
Response headers
| Header | Value |
|---|---|
X-Grid-Cache | hit, partial, stale or miss when the cache was consulted; bypass on an explicit bypass |
X-Grid-Cache-Age | Seconds since the value was fetched |
X-Grid-Fetched-At | When it was fetched (ISO, UTC) |
X-Grid-Saved-Micro | Vendor spend the answer avoided, in micro-USD (list price for your own keys) |
The call body carries the same facts in cache, with fields_cached and fields_fetched.
Manage it
/cache shows savings, a 30-day hit chart and an explorer with masked labels (never values).
DELETE /v1/cachepurges by key, tag or capability;all=truedestroys the workspace's cache key, so every value becomes unreadable at once.POST /v1/cache/forgetdeletes every record about a person or company under any identity, for data subject requests.POST /v1/cache/feedbackdrops fields (after a bounce, say) so the next request fetches them again.
Free keeps up to 50,000 records. At the limit, new records are not written and existing ones still update.