Errors and limits
MarkdownResponse codes, what they mean, and what to do. All errors are JSON and include a Request ID.
Full guide
Error format
The error uses the format of the API you called: an object named error for OpenAI, {"type": "error", "error": {...}} for Anthropic, and an error object with status and details fields for Gemini. SDKs therefore recognize them as standard API errors.
error.codeanderror.reason— the error class from the table below; the values match.error.type— the format’s standard value (for example,invalid_request_errororserver_error).error.request_id(at the top level in Anthropic asrequest_id), theX-Request-IDheader, and the end of the message contain the request ID.- In Gemini, the class is in
error.details:ErrorInfo.reason— the same code in uppercase (for example,MODEL_OVERLOADED),domain—ailoot.ai; the request ID is inRequestInfo.requestId. - In Gemini format, a 5xx error that must not be retried automatically and
result_pending_checkare returned with status 409 andstatusABORTED: this prevents the Gemini SDK and CLI from retrying them automatically. The error class is inErrorInfo.reason(for example,MODEL_TIMEOUTorRESULT_PENDING_CHECK). - OpenAI-format responses also have the top-level fields
codeandmessagefor older clients.
{
"code": "API_KEY_REQUIRED",
"error": {
"code": "invalid_api_key",
"message": "No API key was sent with the request. Nothing was charged. Please check that the full key is sent in the Authorization header as \"Bearer <key>\". Request ID: 3b28d3de-5b02-4d07-9f3c-4b9a7d0e68d6.",
"param": null,
"reason": "invalid_api_key",
"request_id": "3b28d3de-5b02-4d07-9f3c-4b9a7d0e68d6",
"type": "invalid_request_error"
},
"message": "No API key was sent with the request. Nothing was charged. …"
}{
"type": "error",
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"reason": "invalid_api_key",
"message": "… Nothing was charged. … Request ID: 94ed3e31-4373-41ce-bf8a-0d1ed3f7235e."
},
"request_id": "94ed3e31-4373-41ce-bf8a-0d1ed3f7235e"
}{
"error": {
"code": 401,
"status": "UNAUTHENTICATED",
"message": "The API key is not valid. Nothing was charged. … Request ID: e7aa743b-9d0d-4064-b206-2562609f545b.",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "INVALID_API_KEY",
"domain": "ailoot.ai",
"metadata": {
"code": "invalid_api_key",
"reason": "invalid_api_key",
"request_id": "e7aa743b-9d0d-4064-b206-2562609f545b"
}
},
{
"@type": "type.googleapis.com/google.rpc.RequestInfo",
"requestId": "e7aa743b-9d0d-4064-b206-2562609f545b"
}
]
}
}Error codes
| HTTP | Class (reason) | What happened | What to do |
|---|---|---|---|
| 400 | invalid_request | The request is invalid: an incorrect body or parameter; the model does not support a requested field, attachment, or tool; or the key was sent in the URL | Correct the request as described in the error: remove the unsupported field, attachment, or tool, and send the key in a header. Unsupported fields, attachments, or tools are rejected before a reserve is placed, so nothing is charged. |
| 400 | context_length_exceeded | The request exceeds the model’s context window | Shorten the history or choose a model with a larger context window |
| 400 | content_policy_violation | The request was rejected by the model’s rules | Rephrase the request |
| 401 | invalid_api_key | The key is missing or invalid | Check that the full key was sent |
| 401 | api_key_disabled | The key is disabled | Enable it or create a new key |
| 402 | insufficient_balance, insufficient_quota | There is not enough available balance even for the minimum reserve (insufficient_quota is the same case in a format familiar to the OpenAI SDK) | Add funds or reduce max_tokens |
| 402 | api_key_quota_exhausted | The key’s total spending limit is exhausted | Increase the key limit in the Dashboard |
| 402 | payment_disputed | The account has outstanding debt from a disputed payment | New requests are paused until the debt is repaid; contact support |
| 403 | api_key_expired | The key has expired | Create a new key |
| 403 | account_inactive | Your account is disabled | Contact support |
| 403 | permission_denied | The key is not permitted to make this request, for example because of an IP restriction | Check the key restrictions |
| 404 | model_not_found | The model does not exist | Check the ID against /v1/models |
| 404 | unsupported_endpoint | The model does not support this format | Choose another format or model |
| 404 | not_found | The path or object, such as a task, does not exist | Check the URL and identifier |
| 409 | duplicate_request | An operation with the same idempotency key has already been accepted and may have completed | Check the result of the first operation; do not send a new one |
| 409 | not_ready, video_not_ready | The video or other task is not ready yet | Check its status later |
| 409, 503 | result_pending_check | The request outcome is being determined. For a video task, this is the result_pending_check: true flag in the status response; the task itself remains in_progress | Do not resend the request. Its status will appear in your history (GET https://ailoot.ai/api/v1/usage). Do not create a new video task: check it later through GET /v1/videos/{id}. |
| 410 | model_retired | The model has been retired | Choose a new version from GET /v1/models |
| 413 | request_too_large | The request body is too large | Reduce the files or history |
| 429 | rate_limit_exceeded, gateway_concurrency_limit, gateway_queue_full | Too many requests or concurrent requests from your account | Wait for the interval in the Retry-After header, usually 10 seconds, then retry |
| 429 | usage_limit_reached | The key’s spending window is exhausted (5 hours, 1 day, or 7 days) | Wait for the window to reset or increase the key limit |
| 500 | internal_error | An Ailoot error | Contact support with the Request ID |
| 502 | invalid_model_response, empty_response, incomplete_response | The model returned an invalid, empty, or incomplete response | Look up the Request ID in your dashboard history. If it shows a result or a charge, resending will create a second paid request. A missing entry does not establish that the request was not sent or did not run: do not resend a request whose outcome is unknown; contact support with the Request ID. |
| 502 | result_not_delivered | The result was not delivered because of an Ailoot failure, and the reserve or charge was returned | You can send the request again |
| 503 | model_overloaded | The model is temporarily overloaded | If X-Should-Retry: true, retry after the number of seconds in Retry-After; if false, check the Request ID in your history first |
| 503 | model_unavailable | The model is temporarily unavailable | Choose another model. If X-Should-Retry: true, retry after the number of seconds in Retry-After; if false, check the Request ID in your history first. |
| 503 | service_unavailable | A temporary Ailoot failure | If X-Should-Retry: true, retry after the number of seconds in Retry-After; if false, check the Request ID in your history first |
| 503 | charge_not_confirmed | No response was delivered because the charge could not be confirmed. The reserve was released, and no money was charged. | If X-Should-Retry: true, retry after the number of seconds in Retry-After; if false, check the Request ID in your history first |
| 504 | model_timeout | The model did not respond in time; a result may still appear | Do not send the request again until you have checked its Request ID in your history |
Codes for model responses and result verification (502, 503, and 504) now refer to the model or request: model_unavailable, model_timeout, invalid_model_response, incomplete_response, charge_not_confirmed and result_pending_check. If your code compares error.code against the previous values, replace them with the codes in the table. For help mapping old codes to new ones, contact support.
When to retry a request
- Check X-Should-Retry first: if you see
false,result_pending_checkormodel_timeout— do not retry automatically. The first item is a header value; the others are error codes. Find the Request ID in your Dashboard history to see the result and charge. - Retrying is safe when X-Should-Retry: true is returned: wait
Retry-Afterseconds. For 5xx errors, the code alone is not enough: a result may already exist. Check your Dashboard history first or contact support with the Request ID. This is especially important for images, video, music, and long agent steps. - Retries will not help: for 400, 401, 402, 403, or 404, correct the request, key, or balance first.
Limits
Rate and concurrency limits apply to your account as a whole, not to individual keys. Exceeding them returns 429 rate_limit_exceeded with the header Retry-After: 10. If the model itself is overloaded, you receive 503 model_overloaded with Retry-After: 30. If you need a higher load, contact support.
Spending limits are set per key: the total limit returns 402 api_key_quota_exhausted; the 5-hour, 1-day, and 7-day windows return 429 usage_limit_reached. Learn more: API keys and base URL.
NVIDIA models: queueing
You can request the model list with a zero balance, but generation requires enough balance for the reserve. NVIDIA models, including Nemotron, use a shared queue. Under high load, responses may arrive later, or you may receive a “model temporarily overloaded” error with Retry-After; retry after the specified interval. Prices are in the catalog, and charges work the same way as for other models.
Size limits are set by the model: its context window (the number of tokens you can send) and maximum response length. They are listed in the catalog.
History and spending
History and spending · GET https://ailoot.ai/api/v1/usage · JWT · Authorization: Bearer $TOKEN
JWT ≠ sk-… · Sign-in and sessions