Skip to content

Responses API errors

POST /v1/responses returns errors in OpenAI’s Responses error envelope. Errors that originate at Kindo’s edge use the table below. For stateless model requests, upstream HTTP errors are converted to the OpenAI-compatible envelope, preserving their status and message.

{
"error": {
"message": "Model 'unknown-model' not found.",
"type": "invalid_request_error",
"code": "model_not_found"
}
}
StatusTypeCommon codesCause
400invalid_request_errorinvalid_body, model_not_found, unsupported_parameter, unsupported_tool_type, mutually_exclusive_parametersBody fails schema validation, references a missing model, asks for a feature not yet implemented (e.g. background: true on a Kindo-managed conversation), includes an mcp tool on a stateless request (set store: true or pass conversation), or sets both previous_response_id and conversation.
400invalid_request_erroragent_version_pinning_unsupported, agent_inputs_unmappableAgent invocations (model: "agent/<agent-id>"): version pinning (agent/<id>@<version>) is not available yet; or the agent’s declared inputs cannot be bound to a freeform input — it declares two or more named inputs, or a single non-text input (use POST /v1/agents/runs with named inputs instead). model_not_found also covers unknown and inaccessible agent IDs — indistinguishable from an unknown model. See the agent invocation guide.
401——Missing, malformed, or revoked API key. The body is a plain string envelope: {"error": "Unauthorized"}.
403permission_errormodel_access_denied, upstream_errorModel access is denied, or a stateless model request fails an upstream credit or department budget check.
404not_found—E.g. GET /v1/responses/{id} for a response that does not exist or has been pruned.
404invalid_request_errorprevious_response_not_foundprevious_response_id references a response that is unknown, inaccessible, or was not stored (stateless responses cannot be chained). Matches OpenAI’s wire shape for this error.
413——JSON request body exceeds the 50 MB (52,428,800-byte) limit. Returned before route handling as {"message":"Request body too large. Maximum size is 50 MB."}.
429rate_limit_error—Org or user rate limit exceeded. Honors the Retry-After header when present.
500server_errorinternal_errorUnexpected Kindo-side failure.
502server_errorupstream_empty_bodyUpstream LiteLLM / provider returned an empty response.

The 401 envelope is the plain-string form {"error": "Unauthorized"} rather than the typed {"error": {"message": "...", "type": "...", "code": "..."}} shape. This matches how Kindo’s API-key middleware reports auth failures across the Chat Completions and Responses APIs.

For stateless model requests (without store: true, conversation, or previous_response_id), a credit or department budget check can return HTTP 403 before streaming starts, including when stream: true. The response has error.type: "permission_error" and error.code: "upstream_error". Inspect error.message for CHAT_DEPARTMENT_BUDGET_REACHED and its explanation. CHAT_INSUFFICIENT_CREDITS identifies a credit refusal instead.

For model requests in a Kindo-managed conversation (store: true, conversation, or previous_response_id), a credit or department budget refusal during execution is recorded on the response. With stream: false, the request returns HTTP 200 with status: "failed" and the recorded CHAT_DEPARTMENT_BUDGET_REACHED or CHAT_INSUFFICIENT_CREDITS in error.code. With streaming, a live error emits an error event with code: "server_error" and the error message, then ends the stream. Do not wait for a response.failed event on this path.

For model: "agent/<agent-id>", acceptance of the request starts an asynchronous run. A refusal during execution can leave the response with status: "failed". Poll GET /v1/responses/{id} and inspect the response object’s error: error.code carries the recorded CHAT_AGENT_BUDGET_REACHED, CHAT_DEPARTMENT_BUDGET_REACHED, or CHAT_INSUFFICIENT_CREDITS when available, or server_error when no specific error was recorded. With streaming, a live step can emit an error event with code: "server_error" and the step’s error message, followed by response.failed containing the final response object. The HTTP status remains 200 once the stream has started.

Budgets and credits are separate checks: an agent or department budget can block a request while the organization still has credits. Do not retry a budget refusal while that budget still blocks the request. Ask your organization administrator to review it; see When a budget blocks a request.

For stateless model requests, Kindo forwards upstream SSE events. If Kindo cannot read the upstream stream after SSE has started, it emits an error event followed by data: [DONE]:

event: error
data: {"error":{"message":"Stream processing error.","type":"server_error","code":"stream_error"}}
data: [DONE]

The outer HTTP status stays 200 because headers were already flushed when streaming began. SDK consumers should treat any mid-stream error event as terminal.

See Streaming for the full SSE protocol.

For stateless model requests, an upstream 4xx or 5xx keeps its HTTP status and is converted to the OpenAI-compatible envelope. error.code is upstream_error; error.message carries the extracted upstream message (or the upstream body as text when no message can be extracted). For example, upstream 403 uses error.type: "permission_error". Parse the HTTP status first and inspect the message for the refusal reason.