Skip to content
APIs Pricing Docs Guides Changelog Status Log in Start free

Errors and retries

Errors are returned as JSON with a stable code, a human-readable message and the request_id:

{
  "error": {
    "code": "credits_exhausted",
    "message": "The workspace has insufficient credits.",
    "request_id": "req_8f3a1c..."
  }
}

Validation errors also include fields. We never return JSON with an image content type, and never fall back to a different output format.

Codes

HTTP Code Meaning Retry?
400 invalid_json The body is not valid JSON. No, fix the request.
401 unauthorized Missing, unknown, expired or revoked key. No.
402 credits_exhausted No credits left in any balance. After adding credits.
403 forbidden Missing permission, service or referrer restriction, or suspended workspace. No.
404 not_found Resource not found in your workspace. No.
409 conflict The request conflicts with current state. No.
413 payload_too_large Body over the size limit. No.
415 unsupported_format Requested output format is not supported. No.
422 validation_error One or more fields are invalid; see fields. No.
429 rate_limited Too many requests. Yes, after Retry-After seconds.
500 generation_failed / internal_error We could not complete the request. You were not charged. Yes, with backoff.
503 service_unavailable Temporarily unavailable. You were not charged. Yes, with backoff.

Retrying

Retry only 429, 500 and 503. Use exponential backoff with jitter, for example 1s, 2s, 4s and 8s, plus or minus 20%, up to five attempts. Honour Retry-After when present.

Failed requests are never charged, so retrying a failed request cannot double-charge you. A request that succeeded is charged once, even if you did not receive the response; check the request_id in your usage log before retrying non-idempotent work.

Request ids

Every response, successful or not, carries X-Request-Id. Include it when contacting support.