Skip to content

Errors

Every refusal says what happened and, for a person, what to do. A refused or failed call is not charged. Branch on the status and the machine-readable code; show the message to a person if you like, but don’t parse it.

The shape follows the format of the endpoint you called, so each SDK raises its usual exceptions.

Chat Completions, Responses and Speech: the OpenAI shape. The reason is in error.code.

{
"error": {
"type": "billing_error",
"code": "api_wallet_empty",
"message": "Your API wallet does not have enough credits for this request. ..."
}
}

Messages: the Anthropic shape, with Anthropic’s types. The specific reason is in error.message.

{
"type": "error",
"error": {
"type": "rate_limit_error",
"message": "This API key is limited to 60 requests a minute. ..."
}
}

A few refusals send error as a plain string: images and video, an unknown key on Chat Completions and Models, and an unknown model on Chat Completions. Some add a message.

{ "error": "unauthorized" }
{ "error": "unknown_model", "model": "gpt-4o",
"known": ["glm-5.3-flash", "..."] }

So read the code like this:

const body = await response.json();
const code = typeof body.error === 'string' ? body.error : body.error?.code ?? body.error?.type;

These come from the key, the wallet and the limits, and can happen on any endpoint.

Status Code (OpenAI shape) Messages type Meaning What to do
401 unauthorized (string on Chat Completions, Models, images, video) authentication_error Missing, unknown or revoked key Check the key and the header; it may have been revoked
402 api_wallet_empty billing_error The API wallet cannot pay for this request Add funds, or lower max_tokens
402 key_spend_cap_reached billing_error The key reached its monthly cap Raise or remove the cap, or use another key
403 account_suspended permission_error The account is suspended Contact us
413 request_too_large request_too_large The body is too big Send less at once: fewer or smaller images, a shorter history
429 rate_limited rate_limit_error The key passed its requests per minute Wait Retry-After seconds, or raise the key’s limit
429 too_many_concurrent_requests rate_limit_error 8 requests already in progress on the account Wait for one to finish
429 (no JSON body) More than 10 requests a second from one IP address Slow down
503 overloaded (type overloaded_error) overloaded_error Aderra is busy receiving other large requests Retry after Retry-After (5) seconds
Status Code Endpoint Meaning What to do
400 invalid_json / invalid json all The body is not JSON Fix the body
400 unknown_model / unknown model <id> all Not an Aderra chat model Use an id from GET /v1/models
400 unsupported_n Completions, Responses n is not 1 Send n: 1, or leave it out
400 max_tokens must be a positive integer Messages max_tokens is 0, negative or not a number Send a positive integer, or leave it out
400 max_output_tokens must be a positive integer Responses Same, for max_output_tokens Same
429 or 400 / 5xx upstream_error (with the upstream status as a number in code) / api_error all The model is busy or failed Try again in a few seconds. Not charged
502 upstream_unreachable / api_error all The model could not be reached Try again. Not charged
Status error Meaning What to do
400 invalid_json, missing_prompt No JSON object, or an empty prompt Fix the body
400 invalid_size size is not a string Send a string
400 unsupported_size The model is not sold at that size; allowed lists the sizes Use one of allowed
400 invalid_price_limit maxPriceMicro is not a string of digits Fix it
400 unknown_model Unknown model while maxPriceMicro is set Check the name in /v1/usage/prices
400 no_reference_image Edits: no recent image on the account Generate or send an image first
400 invalid_duration Video: duration is not a whole number above 0 Fix it
400 image_required Video, image mode: there is no recent image Generate or send an image first
400 invalid_mode, invalid_image_count, invalid_reference_video_count, invalid_source_video, invalid_end_frame, invalid_video_origin, invalid_explicit Video: a field has a value Aderra does not take Fix it; see Video
400 end_frame_requires_two_images, reference_required, source_video_required Video: the mode found nothing to use at that position Make or send the image or clip first
400 reference_images_unavailable, video_mode_unavailable Video: the model cannot take images as references, or does not make that mode Follow the message
402 price_limit_exceeded The image costs more than maxPriceMicro Raise the ceiling or pick another model
422 refused_blank, image_content_refused The image model refused the prompt Reword it. Not charged
422 video_content_refused The video model refused the prompt Reword it. Not charged
502 image_failed, video_failed The model failed Try again. Not charged
Status code Meaning
400 invalid_json, model_not_found, invalid_input, input_too_long, input_too_long_for_format, invalid_voice, unsupported_format, invalid_speed, unsupported_language A field is wrong; param names it
401 unauthorized No valid key (also on GET /v1/audio/voices and GET /v1/audio/models, which take any Aderra key)
402 insufficient_credits (type insufficient_quota) The wallet cannot pay for this input
403 api_key_required A terminal key was used
429 provider_busy The voice service is busy. Not charged
502 provider_failed The voice could not be made. Not charged

See Text to speech errors for what to do about each.

A terminal key follows your plan, so it can get the plan’s refusals as well: insufficient_credits when the plan’s credits run out, context_length_exceeded when a conversation is longer than the plan’s context window, burst_window_exhausted when the plan’s message window is used up, and plan_required on the Free plan. See Error messages. API keys never get these.