Troubleshooting

View as Markdown
On this page

Start with the HTTP status and the error.code field of the response body: one status can have several causes. The full table of codes is in Errors and limits.

401: the key is rejected#

The answer is 401 invalid_api_key.

Cause. One of three:

  • the key was copied in part, or with a space or quotes;
  • the key is revoked;
  • in Claude Code, the ANTHROPIC_API_KEY variable is still set in the environment. Its value goes in the x-api-key header, which we read before Authorization: an old Anthropic key arrives instead of ours.

Fix. Check the key on the Keys page: it starts with sk-aic- and is in the active list. For Claude Code drop the stray variable and make sure it is gone:

bash
unset ANTHROPIC_API_KEY
env | grep ANTHROPIC

The variable may also be set in the ~/.claude/settings.json file; check its env block. Then type /status in Claude Code: the Auth token line should name ANTHROPIC_AUTH_TOKEN.

402: the balance falls short#

The answer is 402 insufficient_balance.

Cause. The balance cannot hold the reserve for the request. The reserve is larger than the request’s price: it is computed from the body size and from max_tokens, or from the model’s maximum output without it. So a 402 can come with money still on the balance.

Fix. Top up or set a smaller max_tokens in the request. Retrying without that won’t help. How the reserve is computed is in Billing and usage.

403: the model is not allowed for the key#

The answer is 403 model_not_allowed.

Cause. The key has a list of allowed models, and this model is not on it.

Fix. Add the model to the key’s list on the Keys page, or use an allowed one: GET /v1/models with this key shows them. In Claude Code check the background model from ANTHROPIC_DEFAULT_HAIKU_MODEL too: it has to be on the list as well.

If a 403 arrives with an HTML page instead of JSON, it is not our API’s answer: our 403 is always JSON with an error.code. Tell support the time of the request and the address it went to.

400: the model is not found#

The answer is 400 model_not_available.

Cause. The id is not on our list, or the model is there but not on this protocol. Common cases:

  • Claude Code sent a model name of its own because the models are not pinned with the ANTHROPIC_DEFAULT_*_MODEL variables;
  • the id is spelled differently from the list, with a dot instead of a hyphen for example;
  • the model was picked in a tool that speaks another protocol: Codex works only with models on the Responses protocol.

Fix. Take the id from Models and prices and check the model has your tool’s protocol. For Claude Code pin the models as in its setup.

429: a limit hit#

A 429 has five different causes. The response body tells which one:

What the answer hasCauseFix
rate_limit_exceededThe key’s per-minute limit on requests or tokens ran out.Wait as many seconds as retry-after says. If you hit it all the time, raise the key’s limit in the dashboard.
concurrent_requestsThe key already runs as many requests as it may at once: 4.Retry in a second; Claude Code with subagents does so by itself. If you need more in parallel, spread the requests across keys.
monthly_limit_exceededThe key’s monthly spend cap ran out.Waiting is no use before the next month. Increase the key’s monthly cap in the dashboard or use another key.
Plain text, no JSONThe per-IP limit: 60 requests per minute and 1,200 per hour from one address, however many keys are in use.Wait as retry-after says. A second key won’t help: the address is what counts.
An error in the Anthropic or OpenAI format, without a code of oursA limit on the model provider’s side; the answer is passed through as is.Retry following retry-after and x-should-retry; Claude Code does this by itself.

All the limits and their values are in Keys and limits.

413 and 400: the request is too large#

The code request_too_large comes with two statuses, 413 and 400, and their causes differ.

  • 413. The request body is over 32 MB. The answer may also come as plain text, without JSON. Trim the conversation history or the attachments: base64 images take the most.
  • 400. The request alone exceeds the key’s whole per-minute token limit. Tokens here are an estimate: the body size in bytes divided by 4. Waiting won’t help: raise the key’s token limit in the dashboard or shorten the request.

524 and cut-offs: the answer never came#

Cause. A request without streaming waits for the whole answer in silence. If the model takes more than about two minutes, Cloudflare in front of our API closes the connection with code 524. That answer is Cloudflare’s, not ours: it has no JSON with an error.code.

Fix. Turn on streaming, "stream": true. In a stream, when the model is silent for more than 15 seconds, we send a keepalive and the connection holds. For Codex keep stream_idle_timeout_ms from our setup.

Another case is 504 upstream_timeout: the request ran longer than 30 minutes, the limit for one request. Split the task into parts.

404 and “cannot connect”: a wrong base URL#

Cause. The address is not written the way the tool expects it. Anthropic clients add /v1 to the address themselves; OpenAI clients don’t. An extra or a missing /v1 makes a path we don’t have, and the answer is 404.

Fix. Check the address against the table:

ToolSettingValue
Claude CodeANTHROPIC_BASE_URLhttps://api.aicreator.app
Codex CLIbase_urlhttps://api.aicreator.app/v1
ClineBase URLhttps://api.aicreator.app/v1
OpenCodesettings.baseURLhttps://api.aicreator.app/v1
AiderOPENAI_API_BASEhttps://api.aicreator.app/v1

The site’s address, llm.aicreator.app, does not take requests: the API lives at api.aicreator.app.

Unreachable or cut off from Russia#

Cause. The main address goes through Cloudflare, which is not reachable everywhere in Russia.

Fix. Use the second address of the same API, https://api-ru.aicreator.app. The key, the paths and the balance are the same. The /v1 rule is the same too: for Claude Code it is https://api-ru.aicreator.app, for the others https://api-ru.aicreator.app/v1. Ask for long answers as a stream here as well.

502 and 503: the service is temporarily unavailable#

Cause. The model’s provider did not answer (502 upstream_unavailable) or the service is overloaded (503 at_capacity). Such a request is not charged.

Fix. Retry the request unless the x-should-retry header says false; when there is a retry-after, wait that many seconds. If the error persists, tell support the time of the request and the model. Add the X-Billing-Id header if the answer has one: a 503 has none.

A request is missing from the dashboard’s log#

Cause. The log holds only requests that reached the model’s provider. A request we refused earlier (401, 402, 403, our 400 and 429) does not show in the log and costs nothing.

Fix. Look at the answer your tool got: the cause is in its status and error.code.