Errors
Every error from the K-Agent API has the same shape, a stable code you can branch on, and a message written for people in Arabic or English.
The error envelope
Section titled “The error envelope”{ "error": { "type": "conflict_error", "code": "session_busy", "message": "This session is answering another message. Retry in a moment.", "request_id": "req_01k6rz9f1j3m5p7r9t1w3y5a7c", "doc_url": "https://kagent.72.62.2.247.sslip.io/docs/en/reference/errors/#session_busy" }}| Field | Description |
|---|---|
type |
The broad category, below. |
code |
Stable, snake_case. Branch on this. New codes may be added; treat unknown ones by their type and HTTP status. |
message |
For people, in the language of Accept-Language (ar or en). It can change at any time — never parse it. |
param |
Present when one parameter is at fault: a field name, or a JSON pointer such as /tools/max_tool_rounds. |
request_id |
The same value as the Request-Id response header. Quote it when you contact support. |
doc_url |
A link to this page, at the code’s row. |
Types and statuses
Section titled “Types and statuses”type |
HTTP status | Meaning |
|---|---|---|
invalid_request_error |
400 (malformed), 422 (understood but invalid), plus 405, 413 and 428 | Fix the request. |
authentication_error |
401 | The credential is missing, invalid, expired or revoked. |
permission_error |
403 | The credential is valid but may not do this. |
not_found_error |
404 | It doesn’t exist — or it belongs to another project or another end user. |
conflict_error |
409, or 412 for a stale If-Match |
The current state doesn’t allow it. |
rate_limit_error |
429 | Too many requests; wait for Retry-After. |
quota_error |
429 | A plan or cost limit was reached. |
provider_error |
502 | The AI provider failed. |
api_error |
500, 503 | Something went wrong on our side. |
Retrying safely
Section titled “Retrying safely”- Retry
429after theRetry-Afterseconds,409 session_busy,session_queue_fullandidempotency_in_progressafter a short pause, and500,502and503with exponential backoff. Codes marked Retryable below are the ones worth retrying. - Don’t retry when the response has
x-should-retry: false(for examplequota_exceeded), or for other4xxerrors — fix the request first. - Always send an
Idempotency-Keyon POST requests you might retry, so a retry can never create a second message, session or ticket. See Idempotency.
Errors in streams
Section titled “Errors in streams”Errors that happen before a stream starts are normal JSON responses. After it starts, a failed run ends with a run.failed event that carries run.error, and the error event is used only for stream faults (token_expired, stream_timeout, internal_error). See Runs and streaming.
Error codes
Section titled “Error codes”Invalid request (400, 405, 413, 422, 428)
Section titled “Invalid request (400, 405, 413, 422, 428)”| Code | Meaning · What to do |
|---|---|
allowed_ | A publishable key needs at least one allowed origin, such as https://www.example.com. What to do: Add at least one origin ( |
credential_ | The AI provider rejected this API key. Check the key and try again. What to do: The provider rejected the key during the live check. Copy the key again from the provider's console and make sure it can call the chosen model. |
draft_ | The draft can only run in playground sessions. What to do: |
external_ | The external_id format is invalid. Use 1 to 128 Latin letters, digits or the characters . _ : -, starting with a letter or digit. Session IDs must not start with sess_ and end-user IDs must not start with eu_. What to do: Use 1–128 characters from |
idempotency_ | This Idempotency-Key was already used with a different request. Use a new key for each new request. What to do: Use a new |
identity_ | Tools that require a verified customer must not ask the model for identity details such as phone numbers or emails. Use end_user placeholders instead. What to do: Remove phone, email or user-ID parameters from tools that need a verified user, and use |
if_ | This change needs an If-Match header with the current etag. What to do: Send |
input_ | The input is too long. What to do: Shorten the input: up to 4,000 characters with browser credentials, 32,000 with a secret key. |
invalid_ | The K-Agent-Version header names an unknown API version. What to do: Send |
invalid_ | The pagination cursor is not valid for this list. What to do: Use |
invalid_ | The Idempotency-Key header must be 1 to 255 characters long. What to do: Keep |
invalid_ | The request body is not valid JSON. What to do: Send a valid JSON body. Check quotes and trailing commas. |
invalid_ | The parameter "{param}" has an invalid value. What to do: Fix the value named in |
method_ | This endpoint doesn't support this HTTP method. What to do: Use the HTTP method the API reference shows for this path. |
model_ | This model isn't available on your current plan. What to do: Pick a model your plan allows ( |
override_ | This agent doesn't allow changing this setting per request. What to do: Add the field to the agent's |
placeholder_ | A placeholder in the tool's URL, headers or body had no value, so the call was not made. What to do: A |
project_ | The X-Project-Id header names a different project from the one this key or token belongs to. What to do: API keys and tokens already belong to a project. Drop the |
project_ | Choose a project by sending its ID in the X-Project-Id header. What to do: Dashboard cookie requests must send |
reference_ | The configuration refers to an item that doesn't exist in this project. What to do: The configuration points at an ID ( |
request_ | The request body is too large. What to do: Keep request bodies under 1 MiB (5 MiB for knowledge sources). |
secret_ | A secret can only be sent to the hosts listed in its allowed_hosts. What to do: Add the tool's host to the secret's |
secret_ | Secret variables can only be sent with a single message or ask request; they are never stored on a session. What to do: Send secret variables with each request ( |
system_ | System and developer messages aren't accepted; the agent's own instructions apply. What to do: Remove |
tool_ | Another tool of this agent already uses this name. What to do: Rename the tool: names must be unique across the agent's built-in, HTTP and client tools. |
tool_ | The request includes a tool that the agent doesn't declare as a client-side tool. What to do: Only send |
tool_ | Send an output for every pending tool call. What to do: Send one output for every |
tools_ | Client-side tools can't be sent when the request is bound to a session. What to do: Drop |
unknown_ | The event list contains a type that is not in the event catalog. Use catalog event types or ["*"]. What to do: Subscribe only to event types from the catalog in the webhooks guide, or to |
unknown_ | The field "{param}" is not recognized. What to do: Remove the field named in |
unknown_ | This model is not known. What to do: Use a model ID from |
unsupported_ | Only text content is supported. What to do: Send text only: |
unsupported_ | The request uses a parameter that isn't supported. What to do: Remove |
url_ | This URL is not allowed. Use a public https:// address. What to do: Use a public |
validation_ | The request contains an invalid value. What to do: Fix the value at the JSON pointer in |
variable_ | A required variable was not provided. What to do: Send every variable the agent marks |
variable_ | The request sets a variable that this agent doesn't declare. What to do: Send only variables the agent declares, and check their spelling. |
webhook_ | This project already has the maximum number of webhook endpoints. What to do: A project can have up to 10 webhook endpoints. Delete one, or subscribe an existing endpoint to more events. |
Authentication (401)
Section titled “Authentication (401)”| Code | Meaning · What to do |
|---|---|
authentication_ | Authentication is required. Send your API key in the Authorization header as "Bearer <key>". What to do: Send |
invalid_ | The API key is invalid, expired or revoked. What to do: The key is mistyped, expired, rolled or revoked. Create or roll a key in the dashboard. |
invalid_ | The client token is invalid. What to do: Mint a new client token on your server with |
invalid_ | The email or password is incorrect. What to do: Check the email and password. Repeated failures are rate limited. |
token_ | The client token has expired. Request a new one. What to do: Get a new client token (widget: |
Permission (403)
Section titled “Permission (403)”| Code | Meaning · What to do |
|---|---|
csrf_ | This request was blocked because it came from another site. What to do: Dashboard cookie requests must be same-origin JSON requests. Server integrations should use an API key, not cookies. |
insufficient_ | This API key doesn't have the scopes this request needs. What to do: Use a key that has the scope this route needs (for example |
origin_ | This website's origin is not allowed for this key. Add it to the key's allowed origins. What to do: Add this exact origin ( |
origin_ | Requests with a publishable key must come from a browser that sends an Origin header. What to do: Publishable keys only work from browsers, which send |
permission_ | You don't have permission to do this. Required permission: {permission}. What to do: Your role lacks the permission named in the message. Ask an admin for a role that includes it. |
principal_ | This kind of credential can't call this endpoint. What to do: This route needs a secret key or a dashboard user. Publishable keys and client tokens can call only the browser routes listed under End users & identity. |
signup_ | Sign-up is closed on this server. Ask an administrator for an invitation. What to do: Ask an administrator for an invitation. |
Not found (404)
Section titled “Not found (404)”| Code | Meaning · What to do |
|---|---|
project_ | Project not found, or you are not a member of it. Check the X-Project-Id header. What to do: Check the |
resource_ | The requested {resource} was not found. What to do: Check the ID or slug. Items in another project, or owned by another end user, also return 404. |
route_ | There is no endpoint at this path. Check the URL against the API reference. What to do: Check the path, including the |
session_ | Session not found. Create sessions with POST /v1/sessions; you can then use either its ID or your external_id. What to do: Create sessions with |
Conflict (409, 412)
Section titled “Conflict (409, 412)”| Code | Meaning · What to do |
|---|---|
agent_ | This agent is archived and no longer answers new messages. What to do: The agent was archived ( |
agent_ | The agent isn't ready to answer yet. Check the blockers listed in its readiness. What to do: Read the agent's |
already_ | This person is already a member of the organization. What to do: The person is already in the organization; change their role instead. |
client_ | This client_message_id was already used for a different message. What to do: You reused a |
email_ | An account with this email already exists. Log in instead. What to do: Log in instead, or sign up with another email. |
etag_ | This item changed since you loaded it. Reload it and apply your changes again. What to do: The draft changed after you read it. Fetch the agent again, re-apply your change and send the new |
handoff_ | Another team member has already claimed this handoff. What to do: Another teammate claimed it first. Refresh the queue; admins can reassign with |
handoff_ | A handoff is already open for this session. What to do: This session already has an open handoff. Work it in the Handoff Desk, or resolve it before requesting another. |
handoff_ | This handoff is no longer open. What to do: The handoff was already resolved or expired. Refresh it before acting. |
idempotency_ | A request with this Idempotency-Key is still being processed. Retry after it finishes. What to do: The first request with this key is still running. Retry with backoff; once it finishes you get its stored result. |
invitation_ | This invitation has expired or was revoked. Ask for a new one. What to do: Ask an admin for a new invitation link. Links work once and expire after 7 days. |
last_ | An organization must keep at least one owner. What to do: Make another member an owner before removing or demoting this one. |
model_ | No API key is configured for this model's provider. Add a provider key in Settings. What to do: Connect a key for the model's provider (Settings → Model providers, or |
name_ | This name is already in use. Choose a different one. What to do: Pick a different name or slug. |
no_ | This session has no open handoff. What to do: There is no open handoff to release or resolve. Fetch the session to check its |
run_ | This run has already finished and can't be cancelled. What to do: The run already finished. Nothing to do. |
run_ | This run isn't waiting for tool outputs. What to do: Submit tool outputs only while the run's status is |
session_ | This external_id already belongs to a session with a different agent. What to do: This |
session_ | This session is answering another message. Retry in a moment. What to do: The session is answering another message and uses |
session_ | This session is closed. What to do: You sent |
session_ | This session belongs to a different end user. What to do: The session belongs to another end user, and a session's end user never changes. Use a different session ID. |
session_ | A session with this external_id already exists. What to do: You sent |
session_ | Too many messages are waiting in this session. Wait for the agent to reply, then try again. What to do: Ten messages are already waiting in this session. Wait for replies before sending more. |
slug_ | Another agent in this project already uses this slug. What to do: Another agent in this project uses this slug. Choose a different |
Rate limits and quota (429)
Section titled “Rate limits and quota (429)”| Code | Meaning · What to do |
|---|---|
anonymous_ | Too many messages right now. Please try again later. What to do: An anonymous widget visitor hit a per-IP, per-session or daily cap. Ask them to try later, or identify signed-in users with client tokens. |
cost_ | The daily usage cap has been reached. Please try again tomorrow. What to do: The organization reached its daily model-cost cap. Sessions hand off and |
playground_ | The daily limit for test conversations has been reached. Connect your own provider key to keep testing. What to do: Test-panel runs on platform models are capped per project per day. Connect your own provider key to keep testing, or try tomorrow. |
quota_ | Your plan's AI conversation quota for this month is used up. What to do: The plan's AI conversations for this month are used up (Free, or a paid plan with a hard cap). Upgrade or wait for next month; the response carries |
rate_ | Too many requests. Wait a moment and try again. What to do: Wait the number of seconds in |
AI provider (502)
Section titled “AI provider (502)”| Code | Meaning · What to do |
|---|---|
provider_ | The AI provider rejected the credentials. What to do: The model provider rejected the credentials. Check or replace the provider key. |
provider_ | The AI provider rejected the request. What to do: The provider rejected the request. Check the model settings; contact support with the |
provider_ | The AI provider returned an error. What to do: Retry later. Configure |
provider_ | The AI provider is overloaded. Try again shortly. What to do: Retry with backoff; |
provider_ | The AI provider is limiting requests. Try again shortly. What to do: The provider is rate limiting the key. Retry with backoff or raise your limits with the provider. |
provider_ | The AI model declined to answer. What to do: The model declined to answer. K-Agent tries |
provider_ | The AI provider took too long to respond. What to do: Retry. If it keeps happening, choose a faster model or a smaller |
provider_ | The AI provider is unavailable right now. What to do: Retry later, and configure |
Server (500, 503)
Section titled “Server (500, 503)”| Code | Meaning · What to do |
|---|---|
internal_ | Something went wrong on our side. Please try again; if it keeps happening, contact support with the request ID. What to do: Retry with backoff. If it keeps happening, contact support with the |
service_ | The service is temporarily unavailable. Try again shortly. What to do: The server is restarting or overloaded. Retry with backoff. |
Codes outside HTTP responses
Section titled “Codes outside HTTP responses”These codes never come back as an HTTP error. They appear in a run’s error (run errors), as a stream error event, or in a tool result that only the model sees — you will find them in run steps and the dashboard’s Debug tab.
| Code | Meaning · What to do |
|---|---|
handed_ | The conversation was handed to a member of staff. What to do: Returned to the model for the remaining tool calls of a round in which a liability handoff ended the turn. Nothing to do. |
no_ | No API key is connected for the agent's AI provider. What to do: The agent's AI provider has no API key, so the run ended with the fallback message. Connect a provider key (Settings → Model providers, or |
run_ | The run was interrupted before it finished. What to do: The run stopped before finishing (for example during a server restart) and ended through the never-silent path. Check the session and send the message again if needed. |
stream_ | The stream was open too long and has been closed. Reconnect with Last-Event-ID to continue. What to do: Reconnect with |
ticket_ | This customer already has an open ticket. What to do: Returned to the model when the customer already has an open ticket; it tells them the existing ticket number. Nothing to do. |
too_ | Too many tool calls in one step. What to do: At most 5 tool calls run per round; the model receives this for the extra calls. Nothing to do. |
tool_ | The run waited too long for tool outputs and was stopped. What to do: Tool outputs must arrive within 10 minutes of |
unreadable | The lookup came back in a form that could not be read. What to do: Your HTTP tool's endpoint returned something that isn't JSON or doesn't match |
upstream_ | The lookup could not be completed right now. What to do: Your HTTP tool's endpoint failed (non-2xx, timeout, over 1 MiB or a blocked address). Inspect the run steps and test the tool. |
Warnings
Section titled “Warnings”Some successful responses carry warnings: non-fatal notes worth logging.
| Warning | Meaning |
|---|---|
external_id_looks_like_phone |
The external_id looks like a phone number. Keep personal data out of IDs; store contact details in end-user traits. |
external_id_looks_like_email |
The external_id looks like an email address. Same advice. |
create_params_ignored |
The session already existed, so creation-only settings in the request were ignored. |
client_history_ignored |
OpenAI-compatible endpoint: the session’s stored history was used and earlier messages in the request were ignored. |
identity_as_parameter |
A tool parameter is named like personal identity data. Turn on requires_verified_user and use end_user placeholders instead. |