Skip to main content
Kyma answers a failed request with a JSON error body and an HTTP status that describes your request, not the model behind it. Read error.code to decide what to do: it is stable, while error.message is written for people and can change. error.retryable (also sent as the x-should-retry header) says whether sending the same request again can succeed. error.request_id identifies the call; include it when you contact us.

The error object

On OpenAI-compatible endpoints (/v1/chat/completions, /v1/completions, /v1/embeddings and the rest):
Some errors add fields next to error: need_usd, have_usd, topup_url and topup on a 402, did_you_mean and suggested_models on an unknown model. On route_refused, suggested_models is inside error.

On /v1/messages

/v1/messages answers in Anthropic’s error envelope, so Anthropic SDKs and Claude Code handle Kyma errors unchanged. error.type is an Anthropic error type, the Kyma code sits next to it, and request_id is also at the top level:
The upstream_error type becomes overloaded_error on a 503 and api_error on a 502.

Media jobs and kyma-gen

A failed image or audio job still answers GET /v1/jobs/{id} with HTTP 200; the job carries status: "failed" and error: { code, message }. Job codes describe what happened to the job: content_policy, content_policy_likeness, content_policy_nsfw, content_policy_unsafe, moderation_blocked, input_too_large, input_invalid, invalid_input, prompt_too_long, provider_timeout, timeout, provider_rate_limited, provider_unavailable, insufficient_credits. A failed job is refunded. /v1/genmedia/* (used by the kyma-gen CLI) keeps its own shape: { "error": "<message>", "details": { "error_type": "...", ... } }.

Request IDs

Every response carries an x-request-id header, errors and successes alike, and every error body repeats it as error.request_id. Include it when you email hello@kymaapi.com; it lets us find the exact call.

Should I retry?

  1. Read x-should-retry or error.retryable first. The official OpenAI and Anthropic SDKs already honor x-should-retry and retry twice by default.
  2. If it is retryable, wait Retry-After seconds when the header is present, then retry with exponential backoff and jitter.
  3. Statuses that can be retried: 408, 429, 502, 503, 504, and a stream that ended with stream_interrupted.
  4. Do not retry 400, 401, 402, 403, 404 or 413 unchanged: they fail the same way until you change the request, the key or the balance.

Error types

Error codes

Codes are stable: new ones are added, existing ones are never renamed or given a new meaning. Codes marked Not returned yet are reserved; endpoints send the older value listed under Older values until then. Some image, audio, embedding and rerank errors still use older values too.

Authentication and access

The request

Models

Billing

Rate limits

Model availability

Kyma

Media jobs

Account and sign-in

Older values

Billing errors (402)

A 402 is always about money or free-tier access, never about your payload. Every 402 has error.type: "billing_error" and names the rule in error.code:
  • model_requires_paid: the account has never added credits and this model is outside the free tier (free_tier on GET /v1/models says which models a new key can call). required is 0, because no top-up amount turns a paid model into a free one: add credits once, then the model is available.
  • insufficient_credits: the balance does not cover this request. need_usd is the most the request can cost as sent (prompt plus max_tokens) and have_usd is your balance. Add at least the difference, or lower max_tokens.
Two pointers come with every 402: topup_url is the billing page for a person, and topup is the endpoint an agent with a wallet can pay without a person. Only POST /v1/topup itself answers with a payment challenge.

Rate limit errors (429)

rate_limit_exceeded means too many requests, or tokens, in the current minute for your tier. On /v1/chat/completions and /v1/messages the response carries Retry-After and the x-ratelimit-limit-requests, x-ratelimit-remaining-requests and x-ratelimit-reset-requests headers. Limits per tier are on Limits and tiers.

Errors while streaming

Once a stream has started, the HTTP status is already 200. If the model fails mid-answer:
  • On /v1/chat/completions the last chunk has finish_reason: "error" and an error object with code: "stream_interrupted", followed by data: [DONE].
  • On /v1/messages the stream ends with event: error and {"type":"error","error":{"type":"overloaded_error","code":"stream_interrupted",...}}, which Anthropic SDKs raise as an error.
Retry the whole request. The text streamed before the failure is billed like any other output; the charge shows on the Logs page.

Responses that succeeded but need attention

  • x-kyma-max-tokens-clamped: your balance covered fewer output tokens than max_tokens asked for, so the request ran with this lower limit.
  • x-kyma-served-model differs from the model you asked for: another model answered.
  • finish_reason: "length" with empty content on a reasoning model: reasoning used the whole max_tokens. Raise it.

Troubleshooting