Errors
problem+json and every status code.
Problem responses
Every JSON failure is an RFC 9457 application/problem+json document. The type URI points at the matching section of this page, so an agent can link a human straight to the fix. Log the request_id; never log credentials or delivery tokens.
{
"type": "https://car-imgs.vercel.app/docs/errors#402",
"title": "Payment Required",
"status": 402,
"detail": "This account has 0 credits. Buy a pack or enable auto-reload to continue.",
"request_id": "req_01j9x…",
"credits_remaining": 0,
"links": {
"billing": "https://car-imgs.vercel.app/dashboard#billing"
}
}At a glance
| Status | Meaning | Retry? |
|---|---|---|
| 400 | Invalid parameters or JSON. | Fix, then retry |
| 401 | Bearer key missing, invalid or revoked. | Fix, then retry |
| 402 | The account has fewer than 1 credit. | Do not retry |
| 403 | Missing scope, or an invalid/expired delivery token. | Fix, then retry |
| 404 | The make/model/year is not in the catalog. | Fix, then retry |
| 410 | A capped delivery URL was fully redeemed. | Mint a new URL |
| 413 | JSON body larger than 64 KiB. | Fix, then retry |
| 429 | Rate limit exceeded. | Retry with backoff |
| 500 | Unexpected failure. | Retry later |
| 502 | The render failed. | Mint a new URL |
| 503 | A dependency is down or the service is overloaded. | Retry later |
400Bad Request
A parameter is missing, out of range or not one of the allowed values, or the JSON body does not parse. The detail field names the offending parameter. Correct the request; do not retry it unchanged.
401Unauthorized
Send the key as Authorization: Bearer cimg_…. Keys in the query string are never accepted. If the key was revoked, create a new one in the dashboard or run car-image login.
402Payment Required
Cached and freshly generated images cost the same 1 credit, so a 402 means the balance is exhausted. Buy a pack in the dashboard or turn on auto-reload.
Agents: never retry a 402 automatically and never open or complete a purchase on your own. Surface the problem to the human, optionally with a hosted Checkout link created through POST /api/v1/billing/checkout.
403Forbidden
Either the key lacks the required scope (the body says which), or a signed URL's token is malformed, expired, or was minted by a key that has since been revoked. Create a key with the right scope, or mint a fresh URL.
404Not Found
The API only renders vehicles that exist in the open-source vehicle-db catalog for the requested year. Discover valid values with GET /api/v1/vehicles, resolve free text with POST /api/v1/images/resolve, or add the vehicle upstream.
410Gone
The signed URL reached its max_uses. Mint a new one; creating URLs with max_uses: 0 (unlimited within the TTL) avoids this for public pages.
413Payload Too Large
Split the batch. POST /api/v1/image-urls accepts up to 50 images per call, which fits comfortably under the limit.
429Too Many Requests
Wait the integer number of seconds in Retry-After, then retry with exponential backoff and jitter. The default limit is 120 requests per minute per key; RateLimit-Remaining tells you how close you are before it happens. See Rate limits & caching.
500Internal Server Error
Something failed on our side. Nothing was charged for a failed image. Retry once after a short pause and report the request_id if it persists.
502Bad Gateway
Image generation did not produce a usable render. The credit is refunded automatically. For a keyed request, retry after a pause. For a signed URL, the failed delivery still consumed the URL — mint a new one before retrying.
503Service Unavailable
The response includes Retry-After when a short retry is appropriate. Nothing was charged.
304 is free. A 402 is never retried by well-behaved agents. Every other status leaves the balance untouched.