Error format
The shared error body, every error code and retry advice
When anything under /api/v1/** fails, the HTTP status is not 2xx and the body always has the same shape:
{
"error": {
"code": "insufficient_scope",
"message": "This API key does not have the generate:write permission.",
"request_id": "req_xxxxxxxxxxxxxxxxxxxx"
}
}| Field | Description |
|---|---|
code | Machine-readable error code. Branch on it. Stable, never changes |
message | Human-readable explanation. It follows the language: the website uses the interface language, the API uses Accept-Language, and the default is Chinese. May change; don't match on it |
request_id | Unique id of this request, identical to the X-Request-Id response header and the Developer Center logs. Include it when reporting a problem |
Successful responses carry the X-Request-Id header too.
GET /api/file/<filename> is not under /api/v1 and returns plain-text errors, see image download.
Status codes
| Status | code | Meaning | What to do |
|---|---|---|---|
400 | invalid_request and sub-codes | Invalid parameters | Fix the parameters; don't retry |
401 | unauthorized | No Authorization header | Add it |
401 | invalid_api_key | Key invalid, revoked or expired; message says which | Create a new key |
402 | insufficient_credits | Not enough credits; message states how much is needed and how to top up | Top up |
403 | insufficient_scope | Key lacks the required scope | Create a key with that scope |
403 | banned | Account banned | Contact support |
404 | session_not_found | session_id doesn't exist or isn't yours | Omit it, or pass one of your own |
404 | not_found | Image pack publication doesn't exist or isn't yours | — |
429 | rate_limited | Key over its 24-hour limit | Wait for the window to pass, see rate limits |
429 | new_user_daily_limit | New account over its 24-hour spend cap | Come back tomorrow |
500 | internal_error | Generation failed or server error. Reserved credits have been refunded | Retry once; if it keeps failing, report with request_id |
503 | auth_unavailable | Authentication service temporarily unavailable | Retry in a few seconds |
400 sub-codes
Parameter errors on POST /api/v1/generate come with a specific sub-code:
code | Meaning |
|---|---|
invalid_request | Body is not JSON, or both prompt and ref_image_ids are missing |
prompt_too_long | prompt exceeds 4000 characters |
invalid_model | model is not in the model table |
invalid_ratio | ratio is invalid, or unsupported by this model; message lists the allowed values |
invalid_resolution | resolution is not 1K / 2K / 4K |
invalid_quality | quality is not low / medium / high |
invalid_image_count | n is not 1 / 2 / 4 |
invalid_reference_images | ref_image_ids is not an array of strings |
too_many_reference_images | More reference images than the model allows |
reference_image_missing | A reference image is no longer in the Library (deleted or cleaned up) |
prompt_or_reference_required | Prompt and reference images can't both be empty |
Retry advice
400/401/402/403/404: retrying gives the same answer. Fix the request first429 rate_limited: 24-hour rolling window. Back off exponentially; never retry immediately500: credits are refunded, so retry once as-is. If it keeps failing, stop and report withrequest_id503: retry after a few seconds- Network timeout: generation can take up to 5 minutes. After a timeout, don't blindly resend. Check "Recent conversations" on the website first to see whether that run produced images, so you don't pay twice
Photopurr Docs