Reference
Errors
The two error formats and the body for each status. Which errors to retry, and how to report an error so that we can find it.
An error has the format of its endpoint, so that the error classes of each SDK work.
/v1/chat/completions, /v1/responses and /v1/models use the OpenAI format:
{
"error": {
"message": "Insufficient balance: $0.001230 required, $0.000400 available",
"type": "insufficient_quota",
"param": null,
"code": "INSUFFICIENT_BALANCE",
"details": {
"required_micros": 1230,
"required_usd": 0.00123,
"available_micros": 400,
"available_usd": 0.0004
}
}
}
/v1/messages and /v1/messages/count_tokens use the Anthropic format:
{
"type": "error",
"error": {
"type": "billing_error",
"message": "Insufficient balance: $0.001230 required, $0.000400 available"
},
"request_id": "req_8f2a1c"
}
| Field | What it is |
|---|---|
message | A sentence for a person to read |
type | The error type that the SDKs use |
code | Our code. It does not change, so your code can use it. OpenAI format only |
param | The field that caused the error, if there is one. OpenAI format only |
details | More data, where it helps. OpenAI format only |
The Anthropic format uses the same types, with one change: insufficient_quota becomes
billing_error.
Each status
| Status | type | Meaning | Retry |
|---|---|---|---|
400 | invalid_request_error | The request has a problem, and the message names it. Examples are a parameter that we do not use and a model on the wrong endpoint. Idempotency-Key with stream: true and a request that the model refused also get this error | No |
401 | authentication_error | The request has no key, a key in the wrong format or a revoked key. The response has a WWW-Authenticate header | No |
402 | insufficient_quota | Your balance is too low. details shows the amount that the request needed and the amount that you had | After you add balance |
403 | permission_error | Code STARTER_BALANCE_ONLY. The account has only the starter balance, and this model is not a starter model. The message names the models that you can use | After you add balance |
404 | not_found_error | We do not have this model. GET /v1/models has the list | No |
409 | invalid_request_error | A request with the same Idempotency-Key did not complete yet | Yes, after a short time |
422 | invalid_request_error | The body is not correct on /v1/chat/completions, or an Idempotency-Key came again with a different body, or a starter prompt is too long. details has the fields | No |
429 | rate_limit_error | Too many requests. See Rate limits | Yes, after Retry-After |
500 | api_error | Our error. The body has request_id. Send it to us | Yes, with backoff |
502 | api_error | No route could serve the model. We did not charge you. See Reliability | Yes, with backoff |
503 | api_error | Code SUPPLY_NOT_CONFIGURED. The model has no route at this time. We did not charge you | Yes, later, or use a different model |
On /v1/messages, a body that is not correct gets a 400 error, not a 422 error, because the
Anthropic API does the same.
Read an error
import openai
try:
reply = client.chat.completions.create(model="claude-haiku-4-5-20251001", messages=messages)
except openai.APIStatusError as e:
print(e.status_code) # 402
print(e.message) # "Insufficient balance: $0.001230 required, …"
print(e.body["error"]["type"]) # "insufficient_quota"
print(e.response.headers["x-request-id"])import OpenAI from "openai";
try {
await client.chat.completions.create({ model: "claude-haiku-4-5-20251001", messages });
} catch (err) {
if (err instanceof OpenAI.APIError) {
console.log(err.status, err.message, err.type, err.headers["x-request-id"]);
}
}Report an error
Each response has an x-request-id header. A response without a stream also has the same value in
kontinent.request_id. Send the id, your request and the result that you expected to
team@kontinentai.com. See Request ids. The status page shows if the
API answers and which models answered in our last test.
The dashboard routes
/api/v1/* uses a different format, {"ok": false, "error": {...}}. The dashboard uses these routes.
They are not part of the public API. Do not use them in your code.