Errors & status codes
Error response format, common HTTP status codes and how to handle them.
Error format
When a request fails, RuToken returns a non-2xx HTTP status and a JSON body in the OpenAI error format:
{
"error": {
"message": "No available channel for model gpt-4o-mini under group default (request id: 20261016123456789abcdef)",
"type": "new_api_error",
"param": "",
"code": "model_not_found"
}
}
| Field | Type | Description |
|---|---|---|
message |
string | Human-readable description. Usually ends with (request id: ...). |
type |
string | Error source: new_api_error (raised by the gateway), upstream_error, or a provider type such as invalid_request_error (passed through from the upstream provider). |
param |
string | Related request parameter, if any. |
code |
string | Machine-readable code, e.g. model_not_found, insufficient_user_quota. May be empty. |
The Claude endpoint POST /v1/messages uses the Anthropic error shape instead:
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "max_tokens is required (request id: 20261016123456789abcdef)"
}
}
Always log the request id from the message. Include it when you contact support — it lets the administrator find the exact request in the logs.
HTTP status codes
| Status | Meaning | What to do |
|---|---|---|
400 |
Bad request: invalid JSON, missing or invalid parameters, or the prompt was rejected by content filtering. | Fix the request. Do not retry it unchanged. |
401 |
Missing, invalid, expired or disabled API key. | Check the key and the auth header for the format you use. |
403 |
The key has no access: quota exhausted, user banned, IP not on the key's allow list, model or group not permitted for the key. | Top up the balance or adjust the key settings in the console. |
404 |
Unknown endpoint or resource. | Check the method and path. |
413 |
Request body too large. | Reduce the input size. |
429 |
Rate limit reached (gateway or upstream). | Retry with exponential backoff. |
500 |
Internal gateway error. | Retry with backoff; report the request id if it persists. |
501 |
Endpoint not implemented (e.g. /v1/files, /v1/fine-tunes). |
Use a supported endpoint. |
502 / 503 / 504 |
Upstream unavailable or timed out, or no channel is currently available for the model (503, code model_not_found). |
Retry with backoff, or try another model. |
Before returning an error, the gateway may already have retried your request on other upstream channels. The error you receive is the final result of those attempts.
Retrying
Retry only on 429, 500, 502, 503 and 504. Use exponential backoff with jitter and cap the number of attempts:
import random
import time
import requests
def post_with_retry(url, headers, payload, max_retries=5):
for attempt in range(max_retries + 1):
resp = requests.post(url, headers=headers, json=payload, timeout=600)
if resp.status_code not in (429, 500, 502, 503, 504) or attempt == max_retries:
return resp
# 1s, 2s, 4s, 8s ... plus random jitter
time.sleep(2 ** attempt + random.random())
async function postWithRetry(url, headers, payload, maxRetries = 5) {
for (let attempt = 0; ; attempt++) {
const resp = await fetch(url, { method: "POST", headers, body: JSON.stringify(payload) });
if (![429, 500, 502, 503, 504].includes(resp.status) || attempt === maxRetries) return resp;
// 1s, 2s, 4s, 8s ... plus random jitter
await new Promise((r) => setTimeout(r, 2 ** attempt * 1000 + Math.random() * 1000));
}
}
The official OpenAI and Anthropic SDKs already retry these errors automatically (see their max_retries option).
Errors during streaming
If an error happens before the first chunk, you get a normal HTTP error response. Once a stream has started the status is already 200, so a later failure can only appear as an error event or as a stream that ends early. See Streaming.