TL;DR — Branch on
error.code, not the message. Retry only the codes marked Yes, and network errors, with the sameIdempotency-Key.
Errors are JSON: {"error": {"code": "...", "message": "..."}}. Branch on code; the message is for people and may change. Every response has an X-Request-Id header: quote it to support.
Retry only the codes marked Yes below and network errors, with the same Idempotency-Key. Wait for Retry-After when the response has it, otherwise back off with jitter. Never retry the others: the same request will fail the same way.
| HTTP | code |
Retry? | What to do |
|---|---|---|---|
| 400 | invalid_request |
No | The body or a parameter is wrong; the message says which. |
| 400 | idempotency_key_required |
No | Send an Idempotency-Key header (max 255 chars) on every submit. |
| 400 | end_user_id_required |
No | end_user_id is required: the id of the person in your app this run is for. |
| 401 | invalid_api_key |
No | Missing, unknown or revoked API key. |
| 401 | api_key_expired |
No | This API key has expired. Create or rotate a key. |
| 402 | wallet_empty |
No | The product wallet and the org pool cannot cover this run. Add money, then retry. |
| 404 | style_not_found |
No | No style with that id for your org (or not public). |
| 404 | run_not_found |
No | No run with that id for this product. |
| 404 | not_found |
No | No such endpoint. |
| 409 | idempotency_key_reused |
No | This Idempotency-Key was already used with a different body. Use a new key for a new run. |
| 409 | run_not_cancelable |
No | Only queued runs can be canceled. |
| 413 | file_too_large |
No | The file is over the size limit for its type. |
| 415 | unsupported_content_type |
No | Uploads accept JPEG, PNG, WEBP, MP4, MOV and WEBM. |
| 429 | end_user_cap_reached |
Yes | This end user reached the daily run cap. Retry after the Retry-After header (resets 00:00 UTC). |
| 429 | gateway_rate_limited |
Yes | A gateway key's product reached its runs-per-minute limit. Retry after the Retry-After header. |
| 500 | internal_error |
Yes | Something went wrong on our side. Retry with the same Idempotency-Key; quote X-Request-Id to support. |
| 503 | style_unavailable |
Yes | This style cannot run on a live key right now (no model behind it). Test keys still return a sample. |
| 503 | uploads_unavailable |
Yes | Uploads are not available on this deployment right now. |
A run that fails after it was accepted is not an HTTP error: the run ends failed or nsfw with a free-run reason, and you are not charged.
The Jobs API uses its own error codes.
Updated 14 Oct 2026 · Change history (1)