Errors
Error codes, safe retries, and how to confirm credit refunds.
Errors use one envelope. request_id matches the x-request-id header; validation failures add an issues array.
HTTP/1.1 402 Payment Required
x-request-id: gen_9Lm3…
{
"error": {
"code": "insufficient_credits",
"message": "Insufficient credits",
"request_id": "gen_9Lm3…"
}
}{
"error": {
"code": "invalid_request",
"message": "Invalid request body",
"request_id": "gen_2Zt0…",
"issues": [
{ "path": "resolution", "message": "resolution must be one of 1K, 2K, 4K" }
]
}
}Error codes
| error.code | HTTP | When | Charged? |
|---|---|---|---|
unauthorized | 401 | Missing, malformed, unknown or revoked key. | No |
api_access_disabled | 403 | API access was disabled for the account by support. | No |
invalid_request | 400 | Body is not JSON, a field fails validation, or Idempotency-Key has an invalid format. Validation errors include issues. | No |
model_not_found | 404 | model is missing or not in /v1/models. | No |
insufficient_credits | 402 | Balance is below the price of this request. | No |
rate_limited | 429 | Per-key request rate exceeded. Honour retry-after. | No |
concurrency_limited | 429 | More than 10 generations still queued for the account. | No |
provider_error | 502 | The provider could not accept the request. If submission had already started, read the generation's credits and credits_refunded fields. | Check generation |
idempotency_conflict | 409 | The same Idempotency-Key was used with a different body. Use a new key for a new generation. | No additional charge |
submission_pending | 503 | The submission outcome could not be confirmed. Retry with the SAME Idempotency-Key or query request_id; do not create a new submission. | May be charged; check generation |
not_found | 404 | The generation id does not exist or belongs to another account. | No |
internal_error | 500 | Something on our side. Retry with the same Idempotency-Key and backoff; contact support with request_id if it persists. | Check generation; never assume a refund |
Handling advice
- Fix invalid input, authentication, whitelist access, or balance errors before making a new attempt. A reserved request that was rejected before debit keeps its original response on idempotent replay; use a new key after fixing the cause.
409 idempotency_conflictmeans the key already belongs to a different body. Use the original body to retrieve that generation; use a new key only when you intend to create another generation.- Retry
429afterretry-after. For timeouts and500/502/503, back off and reuse the same Idempotency-Key and body.503 submission_pendingmeans the submission state could not be confirmed; query its request ID or retry with that key. - A
202response is a generation object, which can already befailedafter a completed refund or an idempotent replay. Readstatus,error,credits, andcredits_refunded. A refund awaiting recovery remainsqueued; an HTTP error alone is not proof of a refund. - Keep the generation or
request_idfrom unexpected responses so support can trace the request.