Menu

Caching

Store renders on a CDN and serve repeat requests for free, with control over lifetime and cache keys.

Turn it on

With cache=true, the result is stored and identical requests get the stored file instead of a new render:

curl -X POST "https://shotkit.net/api/take" \
  -H "X-Access-Key: YOUR_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com","cache":true,"cache_ttl":86400}' \
  --fail-with-body -o shot.jpg
  • Cache hits are free. They don't count toward your monthly screenshots (they do count toward the per-minute rate limit).
  • GET hits are redirected (302) to the file on the CDN, so <img src> tags load straight from it. POST hits return the file.
  • cache_ttl sets the lifetime, from 4 hours (14400, the default) to 30 days (2592000).
  • Caches are per workspace; other customers never get your renders.
  • Async requests always render and don't use the cache.

This makes signed URLs cheap to embed: the first view renders, and every later view of the same URL is a free redirect.

What counts as identical

The cache key is your workspace plus every option except these, which don't change the render: cache, cache_ttl, response_type, async, webhook_url, webhook_sign, webhook_errors and external_identifier. Option order doesn't matter.

The site's content isn't part of the key: if the page changes, you keep getting the cached version until it expires.

Force a fresh render

Send a Cache-Control: no-cache request header. The page is rendered again and the cache entry is replaced:

curl "https://shotkit.net/api/take?url=https://example.com&cache=true" \
  -H "X-Access-Key: YOUR_ACCESS_KEY" -H "Cache-Control: no-cache" -o shot.jpg

Separate entries with cache_key

cache_key is any string that becomes part of the key. Use it to roll a new version on your schedule, for example one render per day:

curl -X POST "https://shotkit.net/api/take" \
  -H "X-Access-Key: YOUR_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com","cache":true,"cache_key":"2026-10-09"}' \
  --fail-with-body -o shot.jpg

Response headers

Header Value
X-Cache MISS when rendered now, HIT when served from the cache.
X-Cache-Url The file's CDN URL, valid until the entry expires.
Cache-Control private, max-age=<seconds left>, so browsers keep their copy too.

With response_type=json, the body also has cache_url.

Warm the cache

Render ahead of time without downloading the file by combining cache=true with response_type=empty:

curl -X POST "https://shotkit.net/api/take" \
  -H "X-Access-Key: YOUR_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com","cache":true,"response_type":"empty"}' \
  --fail-with-body -o shot.jpg