Caching
Accept a recent cached result with max_age and pay half the credits on a hit. How freshness, cache keys, X-Cache and meta.cached work.
By default every request fetches Google live. If a slightly older result is fine for your use case, set max_age to the oldest result you accept, in seconds. When SerpKite has a matching result that fresh, it returns it immediately for half the credits. Otherwise it fetches live at the normal price and stores the result for the next caller.
curl https://api.serpkite.com/v1/search \
-H "Authorization: Bearer $SERPKITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"q":"best espresso machine 2026","country":"us","max_age":3600}'How it works
- You send a request with
max_age: 3600(one hour). - SerpKite looks up a result for the same normalised request: same endpoint, query,
country,language, location, device, page, filters and so on. - If one exists and is younger than
max_age, it is returned withX-Cache: HITand costs 0.5× the usual credits. - If not, or if it is older, the search runs live at full price with
X-Cache: MISS, and the fresh result replaces the cached one.
Without max_age (or with max_age: 0) you always get a live result and it is never served from cache. The maximum is 2,592,000 seconds (30 days).
Pricing
A cache hit costs half of what the same live request would, rounded up to the next 0.001 credit so it is never free:
| Request | Live | Cache hit |
|---|---|---|
/v1/search (1 page) |
1 | 0.5 |
/v1/search with num: 100 |
7 | 3.5 |
/v1/autocomplete |
0.5 | 0.25 |
/v1/lens |
2 | 1 |
The X-Credits-Used header and meta.credits_used show the actual charge.
Telling a hit from a miss
- The
X-Cacheresponse header isHITorMISS. - In JSON,
meta.cachedistrueon a hit andmeta.cached_atholds the time the result was fetched (ISO 8601).
"meta": {
"request_id": "req_01J8ZK4M6Q2V7",
"credits_used": 0.5,
"cached": true,
"cached_at": "2026-09-29T07:12:44Z",
"engine": "google",
"parse_quality": "ok"
}
How long results stay cached
max_age is the freshness you accept, but results also expire on their own. Current defaults:
| Endpoint | Kept for up to |
|---|---|
| Most endpoints | 6 hours |
/v1/news |
30 minutes |
/v1/webpage |
1 hour |
/v1/autocomplete |
24 hours |
So max_age: 86400 on /v1/search behaves like “anything from the last 6 hours”. These retention times may change; max_age is the contract.
Privacy
Every successful live result is written to the cache, whether or not the request sent max_age: max_age only decides whether you are served a cached copy. Entries are stored in memory under a SHA-256 hash of the normalised request, so the query text is never used as a key, and they expire automatically after the times above. Your identity and API key are not part of the entry. Raw HTML (include_html) is never cached. See Privacy and data retention.
When to use it
- Agents and chatbots: popular questions repeat.
max_age: 3600cuts cost on repeated queries without users noticing. - Dashboards that refresh often: use a
max_agea little shorter than your refresh interval. - Rank tracking: usually leave it off, or set it to your tracking window, so each run reflects a fresh SERP. The batch lane is the cheaper lever there.
- News monitoring: keep
max_ageshort; news caching is capped at 30 minutes anyway.
max_age is also honoured inside batch requests (POST /v1/batches).
Related: Credits and billing, Response headers.
Last updated: 2026-09-29