犀速AI
Contents
Updated 2026-10-04

API & Error Codes

Error codes and rate limits

Xisu AI error codes and rate limits: the next step for each code, why low balance shows as rate_limit_error on the Anthropic protocol, backing off by Retry-After on 429, insufficient versus negative balance, and why reports need a request_id.

Almost every failure you hit while integrating is in the table below. None of them means "the service is broken" — each has a definite next step.

Code Meaning What to do
invalid_api_key Invalid key Check it wasn't revoked and was copied in full. If this key has an IP allowlist, calling from elsewhere shows this exact same error — check your source IP first
insufficient_balance Insufficient balance Top up
account_overdrawn Balance is negative, usually after a refund clawback Contact support to reconcile the account
budget_exceeded This key hit its budget cap Raise the budget or use another key
model_not_allowed This key cannot call this model Read the message: “…by your plan” means upgrade the plan; “…for this API key” means the plan is fine — ask support to widen this key
rate_limit_exceeded Too many requests Back off per Retry-After
no_available_channel That model is temporarily unavailable Try again shortly
upstream_error The upstream returned an error, and the cause does not trace back to your payload Try a different model first; this one is usually on us to fix upstream. A genuinely invalid payload comes back as upstream_rejected_request (400) — but this 502 is still no proof your payload is fine, so if it keeps failing, check it against the message. If it keeps happening, open a ticket with the request_id
upstream_rejected_request The upstream judged the request itself invalid — this one really is the payload Fix the payload and send it again; retrying it unchanged will fail exactly the same way. The message usually quotes the upstream verbatim — go by that. The most common cause is a tool/function JSON Schema the upstream refuses
system_not_supported_upstream Every upstream currently serving this model drops the system prompt Retry without the system prompt — that will go through; or pick a model without the “no system prompt” tag on the Models page
context_length_exceeded Input exceeds the context limit declared for this model on our platform Shorten the input or split it up; a model with a larger context also works. Retrying will not help — the error message carries the actual length and the limit.
content_policy_violation The content was blocked by the platform's content policy Retrying as-is will always give the same result — change the content and send again; if you believe it is a false positive, open a ticket with the request_id
content_policy_needs_text The request contains content the platform cannot read as text (pre-tokenized token arrays, images, PDFs, etc.) Send it as text and try again; if you really need to send this kind of content, open a ticket to have this key allowed
tenant_closing Account is being closed Contact support — topping up will not restore access

/v1/messages uses a different set of error types

The Anthropic-native protocol has its own error types (error.type in the response body). They do not overlap with the table above — and error.type is what the SDK reads.

error.type HTTP Meaning What to do
invalid_request_error 400 The request was judged invalid (your payload, an over-long input, an upstream refusal, or content the platform cannot read as text — they all land on this one type) Fix the payload and send it again rather than retrying it unchanged — every one of those causes has the same next step. Read the message: it says which one, and carries our request_id
authentication_error 401 Invalid key Check whether it was revoked and that you copied it in full; if the key has an IP allowlist, calling from anywhere else returns this same message
permission_error 403 Your plan or this key does not allow the model, the content was blocked by the content policy, or the account is being closed Read the message: if it is about the model, adjust the key's model scope or upgrade the plan; if it is about the content policy, change the content (if you believe it is a false positive, open a ticket with the request_id); if it is about the account, contact support
not_found_error 404 This model is not on /v1/messages (it has no Anthropic upstream configured) Pick a different model, or switch to /v1/chat/completions — the message points the way. Retrying will not help
request_too_large 413 Request body too large Compress or split the request (multimodal content is usually the bulk of it)
rate_limit_error 429 Rate limited / quota exhausted / balance too low / key budget reached (all four share this one type) Check the balance first, then read the message: if it says this is an account limit, retrying will not help; back off and retry only when it really is rate limiting
api_error 502 / 504 Every upstream failed, or the request was hard-stopped at the timeout Retry later; if it keeps happening, open a ticket with the request_id
overloaded_error 503 The model has no usable upstream right now (cooling down or held back) — this is not "no such model" Back off by the Retry-After in the response and retry — this one is temporary

⚠️ The one that gets misread is rate_limit_error: an empty balance is reported as that too (the Anthropic protocol has no "insufficient balance" type). On a 429, check the balance first; the message says whether it is an account limit — and if it is, retrying will not help however many times you try.

How to back off when rate limited

A rate_limit_exceeded response carries Retry-After (in seconds). Back off by that value; don't retry on a fixed interval — at peak times a fixed interval just makes you compete with yourself for quota.

Exponential backoff with jitter is the sane default; cap it at whichever is larger, Retry-After or your own timeout.

Include the request_id when you report a problem

Every response carries a request_id. Without it we cannot find that call — the gateway handles a large volume every day, and "the one around ten-ish" doesn't locate anything.

When you open a ticket, include: the request_id, when it happened, which model, and the complete error body.

One case that is very easy to misread

insufficient_balance (not enough balance) and account_overdrawn (negative balance) are not the same thing:

  • Not enough balance: the balance is still positive, just short for this call. Topping up genuinely fixes it.
  • Negative balance: usually a refund claw-back pushed the balance below zero. Topping up does not address the cause — open a ticket and have support reconcile the account.

These two used to be reported as one code. The result was that customers whose balance had been pushed negative kept topping up, while the actual accounting problem went unlooked-at.