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; errors that originate upstream are forwarded verbatim with the upstream body and content-type.

{
"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_not_invocable, agent_inputs_unmappableAgent invocations (model: "agent/<agent-id>"): version pinning (agent/<id>@<version>) is not available yet; the agent is trigger-driven and cannot be invoked directly; or the agent declares two or more named inputs (use POST /v1/agents/runs instead). model_not_found also covers unknown and inaccessible agent IDs — indistinguishable from an unknown model. See the agent invocation guide.
401Missing, malformed, or revoked API key. The body is a plain string envelope: {"error": "Unauthorized"}.
403permission_errormodel_access_deniedThe key authenticated, but the user group does not grant access to the model.
404not_foundE.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.
429rate_limit_errorOrg 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.

If stream: true is set and an error occurs after the SSE has started, Kindo emits an error event followed by response.failed:

event: error
data: {"error":{"message":"upstream stream interrupted","type":"server_error","code":"stream_error"}}
event: response.failed
data: {"id":"resp_abc123","status":"failed","object":"response"}

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.

When an upstream provider (Anthropic, OpenAI, etc.) returns a 4xx or 5xx with its own body, Kindo forwards that body verbatim, preserving the upstream Content-Type. Your client sees whatever shape the upstream produced — Kindo does not rewrap. The exception is upstream_empty_body, which Kindo emits when the upstream returned an HTTP error with no body so consumers always have a parseable JSON envelope to log.

If you want a single consistent error shape across providers, parse on the outer HTTP status first; only fall back to body inspection when you need provider-specific detail.