Error Codes
Errors follow the OpenAI shape:
error
{
"error": {
"message": "Human-readable summary",
"type": "error_category",
"code": "machine_readable_code",
"param": "field_name_if_applicable"
}
}Some errors add fields to error so a client can act without parsing the message: model_not_in_plan adds allowed_models (models this key can use, best first) and upgrade_url; balance errors add top_up_url and the amounts. On /v1/messages the same refusals use the Anthropic shape ({"type":"error","error":{"type":…,"message":…}}) with these fields on error.
Every error response also carries an X-Request-Id header. Include it when reporting issues to ScaleMax support. For symptom-first fixes, start from Troubleshooting.
Codes
| HTTP | Code | Type | Meaning | What to do |
|---|---|---|---|---|
401 | invalid_credentials | authentication_error | The API key is missing, malformed, revoked, or being sent to the wrong credit/token billing surface. | Use the base URL returned by setup: API-credit keys normally use /v1, API-token keys use /token/v1, and unified Auto keys use https://api2.scalemax.pro/v1. Then check the Authorization header; replace the key only if both are correct. |
403 | key_expired | permission_error | The API key was valid but has now expired. | Request a renewed key from ScaleMax support. |
403 | key_disabled | permission_error | The API key is suspended or disabled, or a feature (for example video generation or Voice) is switched off on it. A model outside your plan is model_not_in_plan, not this. | Check the key in dashboard Settings. If it should work, contact ScaleMax support with the request id. |
403 | model_not_in_plan | permission_error | The model you asked for is not included in this key’s plan (its model families, the models selected for the key, or a model launched after the key was bought). The key itself works. The error lists models you can use in allowed_models and links to plans in upgrade_url. | Switch to a model from allowed_models (the full list is on the dashboard Models page), or buy a pack that includes the model. Claude Code refused on claude-haiku-4-5: set ANTHROPIC_DEFAULT_HAIKU_MODEL to one of your models, or run npx scalemax@latest. |
401 | wrong_billing_surface | authentication_error | The key is valid but was sent to the base URL of the other billing type (a token key on /v1, or a credit key on /token/v1). | Use the base URL named in the error message (it is also shown for the key in dashboard Settings). The key does not need replacing. |
429 | rate_limit_exceeded | rate_limit_error | You exceeded the per-key requests-per-minute limit. | Back off and retry with jitter. See Rate Limits for your specific cap. |
429 | concurrency_limit_exceeded | rate_limit_error | Shown in your request log. The key already had its maximum number of requests running at once. The API answers rate_limit_exceeded with a message naming the cap. | Wait for a running request to finish, honor Retry-After, then retry. Nothing is charged for the refused request. |
429 | balance_temporarily_reserved | rate_limit_error | Another in-flight request is temporarily reserving this key’s available balance. | Wait for that request to finish, honor Retry-After, then retry once. |
429 | limit_reached | quota_error | You used your full token budget for this period. | Top up the existing key with a compatible token pack before retrying. |
402 | insufficient_credit | quota_error | The key does not have enough available credit or tokens to start this request. The error says what is left, what the request needed and where to top up (top_up_url). | Top up the existing key. If another request is still running, wait for it to settle before checking the balance. |
402 | balance_too_low_for_output | quota_error | Shown in your request log. The balance left could not cover the longest reply the request allowed (max_tokens). The API answers insufficient_credit, and names a max_tokens that fits when a shorter reply would. | Lower max_tokens (or max_output_tokens) to the figure in the error, or top up the key. |
402 | free_model_requires_paid_account | quota_error | Free models are not available on trial keys. | Buy any pack (or top up once) to use free models on the key, or pick a model your trial includes. |
400 | invalid_request | invalid_request_error | The request body failed schema validation. | Check the parameter list for the endpoint. Common causes: missing model, empty messages, malformed tool_calls. |
404 | model_not_found | invalid_request_error | The model id isn't in the catalog. | Use GET /v1/models for API credit or GET /token/v1/models for API tokens to see the current list. |
400 | context_length_exceeded | invalid_request_error | The combined input exceeds the model context window. | Trim conversation history or switch to a model with a larger window. |
400 | bridge_unsupported_text_format | invalid_request_error | A /v1/responses request asked for a structured output format (text.format, for example json_schema) that this model cannot enforce. | Remove text.format and ask for the shape in the prompt, or switch to a model that supports structured output. |
400 | responses_not_supported | invalid_request_error | This model is not served on /v1/responses. | Call the same model on /v1/chat/completions. |
400 | tool_output_missing_call_id | invalid_request_error | A /v1/responses tool result (function_call_output) did not name the call it answers. | Send each tool result with the call_id of the function_call it answers. |
400 | image_input_unsupported | invalid_request_error | The request carries an image and the chosen model can't read images. | Remove the image or switch to a model with image input; the error message names some you can use. |
502 | provider_unavailable | api_error | The model provider is temporarily unavailable for this request. | Retry with exponential backoff, or switch to another available model. |
502 | upstream_error | api_error | The upstream provider returned an error or timed out. | Retry with exponential backoff. If persistent, try a different model. |
504 | upstream_timeout | api_error | The provider took too long to respond. | Retry. For long generations consider streaming. |
500 | internal_error | api_error | Unexpected error inside the gateway. | Retry. If it persists, contact support with the request id from the response headers. |
Retry behavior
- For a retryable
429, honor theRetry-Afterheader. Do not create parallel retries. The caps and headers behind a 429 are described in Rate limits. 5xxresponses are safe to retry with capped exponential backoff and jitter. Stop retrying after response content has started streaming.- Most
4xxresponses are not retryable. The explicit exception is a temporary429. Authentication, permission, validation, and exhausted-quota errors require corrective action first.