Car Image API
Documentation

Rate limits & caching

120 req/min per key, RateLimit-* headers, ETags and cache policy.

Rate limits

Each API key may make 120 requests per minute by default, counted in a fixed 60-second window. Every response announces the budget so clients can pace themselves without guessing; higher per-key limits are available on request. Unauthenticated endpoints (device codes, the playground) are limited per IP.

HeaderExampleMeaning
RateLimit-Limit120Requests allowed per window for this key.
RateLimit-Remaining117Requests left in the current window.
RateLimit-Reset42Seconds until the window resets.
Retry-After42Only on 429: integer seconds to wait before retrying.
429 Too Many Requests
HTTP/2 429
content-type: application/problem+json
ratelimit-limit: 120
ratelimit-remaining: 0
ratelimit-reset: 42
retry-after: 42

{"type":"https://carimage.dev/docs/errors#429","title":"Too Many Requests","status":429,"detail":"Rate limit exceeded for this key. Retry after 42 seconds.","request_id":"req_01j9x…"}

ETags: free repeats

Every image response carries a stable ETag per variant. Send it back as If-None-Match and an unchanged image returns 304 Not Modified with no body and no credit charged. Weak comparison is used, so a W/ prefix on either side still matches.

bash
curl -sI -H "Authorization: Bearer $CAR_IMAGE_API_KEY" \
  -H 'If-None-Match: "9f2a…c41d"' \
  "https://carimage.dev/api/v1/images/car?make=porsche&model=911&year=2024&view=side"
# HTTP/2 304
# etag: "9f2a…c41d"

Cache policy by response type

ResponseCache-ControlWhy
Keyed image bytes (GET /api/v1/images/car)private, max-age=86400Your server or browser may keep the bytes for a day; shared caches must not, because the response was authorized by your key and metered.
Signed URL, unlimited usespublic, max-age=<remaining TTL>, s-maxage=<remaining TTL>, stale-while-revalidate=60Billed once at creation, so CDNs and browsers may serve repeats for free until the URL expires (capped at one day per cache entry).
Signed URL with max_usesprivate, no-storeEvery redemption must reach the origin so the use counter can be enforced.
Free example imagespublic, s-maxage=31536000, stale-while-revalidate=86400The allowlisted landing-page images are public and immutable.

The rule of thumb: a response that cost a credit is private to the caller; a response that was prepaid (a signed URL) or free (an example) may be shared. If you want a CDN in front of your images, mint signed URLs with a long TTL and unlimited uses.

Generation and concurrency

First renders are the slow path (about ten seconds). Concurrent requests for the same new variant are coalesced onto one render — the second caller waits for the first instead of paying for a duplicate. Very large batches of never-seen vehicles should be spread out; the rate limit, not the renderer, is the ceiling you will hit first.