Errors
What each error means, when to retry, and what to tell your vendor.
No error costs credits, and a failed generation is refunded automatically.
Error format
{
"error": {
"code": "invalid_request",
"message": "The Idempotency-Key header is required. Send one unique value per photo, such as a UUID, and reuse it when you retry.",
"param": "Idempotency-Key",
"request_id": "req_9Tz3Kw7Qp2Lx5Nv8Bd4Hs6Jy"
}
}Build your logic on code. message is for developers: don't show it to vendors. param names the field at fault, and request_id helps us when you contact us.
Request errors
These come back as the answer to your request, and no job is created.
| HTTP | Code | What it means | Retry? |
|---|---|---|---|
| 400 | invalid_request | A field, parameter or header is missing or wrong; see param | No, fix the request |
| 400 | style_not_available | The style doesn't exist or was retired | No, pick another style |
| 400 | image_unreadable | The photo file is damaged | No |
| 400 | image_too_small | The photo is under 512 px on its short side | No |
| 400 | image_fetch_failed | We couldn't download your image_url | Yes, once the URL works |
| 401 | invalid_api_key | The key is missing, wrong or revoked | No |
| 402 | insufficient_credits | Your live credits have run out | After credits are added |
| 403 | permission_denied | Not allowed, for example a live key used from a browser | No |
| 403 | account_suspended | Your account is suspended | No, contact us |
| 404 | not_found | No such generation, file or path | No |
| 409 | idempotency_conflict | This Idempotency-Key was used with a different body | No |
| 413 | image_too_large | The photo is over 20 MB or 100 megapixels | No |
| 413 | payload_too_large | The request body is over 10 MB | No, send image_url |
| 415 | unsupported_media_type | The photo isn't JPEG, PNG, WebP or HEIC, or the body isn't JSON | No |
| 429 | rate_limited | Too many requests for this key | Yes, after Retry-After |
| 429 | queue_full | 500 jobs are already waiting | Yes, after Retry-After |
| 429 | daily_limit_reached | You reached today's job cap | Yes, after 00:00 UTC |
| 429 | busy | We are briefly busy | Yes, after Retry-After |
| 500 | internal_error | Something went wrong on our side | Yes |
| 503 | service_unavailable | We can't take the request right now, or your access isn't open yet | Yes, after Retry-After |
Failed generations
A job that was accepted can still fail. You get status: "failed" and a generation.failed webhook, with one of these codes in error.code. The credit is refunded.
| Code | What it means | Retry? |
|---|---|---|
content_refused | The photo or the instruction was refused | Not with the same photo |
image_unprocessable | No result could be made from this photo | Not with the same photo |
generation_timeout | It took too long | Yes, with a new Idempotency-Key |
generation_failed | It failed for another reason | Yes, with a new Idempotency-Key |
queue_timeout | It wasn't finished within 24 hours | Yes, with a new Idempotency-Key |
Retrying
- Timeouts, network errors,
429and5xx: retry with the sameIdempotency-Keyand the same body. Wait forRetry-Afterwhen it is there; otherwise wait 1, 2, 4, 8 seconds and so on. - A failed generation: create it again with a new
Idempotency-Key. - Other
4xxerrors: don't retry. Fix the request, or ask the vendor for another photo. - An error code you don't know: we may add codes. Act on the HTTP status: retry
429and5xx, and don't retry other4xx.
Some 429 and 5xx answers come from our hosting platform without our JSON body. Retry them the same way.
What to tell your vendor
| Code | Message for the vendor |
|---|---|
image_too_small | "This photo is too small. Please upload the original photo, not a screenshot." |
image_too_large | "This photo is too large. Please upload a smaller one." |
image_unreadable | "We couldn't open this photo. Please upload it again from your camera." |
unsupported_media_type | "Please upload a JPEG, PNG, WebP or HEIC photo." |
content_refused | "We couldn't use this photo. Please upload a photo that shows only the dish." |
image_unprocessable | "We couldn't create a picture from this photo. Please try a sharper, brighter photo of the whole dish." |
style_not_available | "This style is no longer available. Please choose another one." |
Other codes need nothing from the vendor.