Chat Completions API errors
POST /v1/chat/completions returns errors in OpenAI’s Chat
Completions 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.
Envelope
{ "error": { "message": "Model 'unknown-model' not found.", "type": "invalid_request_error", "code": "model_not_found" }}Status / type / code reference
| Status | Type | Common codes | Cause |
|---|---|---|---|
400 | invalid_request_error | invalid_body, model_not_found | Body fails schema validation or references a missing model. |
401 | — | — | Missing/malformed/revoked key. Plain envelope: {"error": "Unauthorized"}. |
403 | permission_error | model_access_denied | The key authenticated, but the user group does not grant access. |
429 | rate_limit_error | — | Org or user rate limit. Honors Retry-After when present. |
500 | server_error | internal_error | Unexpected Kindo-side failure. |
502 | server_error | upstream_empty_body | Upstream returned an empty body. |
Chat Completions does not emit 404 from Kindo’s edge — any 404 the client sees is upstream provider passthrough.
401 exception
401 uses the plain-string envelope {"error": "Unauthorized"}
rather than the typed {"error": {"message": "...", ...}} shape.
This matches Kindo’s API-key middleware on /v1/chat/completions
and /v1/responses.
Mid-stream errors
Once stream: true has flipped the response into SSE, errors arrive
as an inline event: error SSE frame followed by data: [DONE]:
event: errordata: {"error":{"message":"upstream stream interrupted","type":"server_error","code":"stream_error"}}
data: [DONE]Treat any event: error payload with code: "stream_error" as
terminal. The outer HTTP status stays 200.
Provider passthrough
When LiteLLM or the upstream provider returns a 4xx or 5xx with its
own body, Kindo forwards that body verbatim (preserving the upstream
Content-Type) so 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.
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.
See also
- Authentication —
401causes. - Model catalog —
403causes. - Streaming — mid-stream error events.