Skip to content

Messages API errors

POST /v1/messages returns errors using Anthropic’s standard 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

{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "max_tokens is required"
}
}

Status / type / code reference

StatusTypeCommon codesCause
400invalid_request_errorBody fails schema validation (missing max_tokens, malformed messages, etc.) or references a missing model.
401authentication_errorMissing, malformed, or revoked API key.
403permission_errorThe key authenticated, but the user group does not grant access.
429rate_limit_errorOrg or user rate limit. Honors Retry-After when present.
500api_errorUnexpected Kindo-side failure.
502upstream_empty_bodyUpstream returned an empty body. Example: {"type":"error","error":{"type":"upstream_empty_body","message":"..."}}

401 note

On /v1/messages, 401 returns Anthropic’s typed authentication_error envelope rather than the plain-string {"error":"Unauthorized"} shape used on /v1/chat/completions and /v1/responses.

{
"type": "error",
"error": {
"type": "authentication_error",
"message": "Unauthorized"
}
}

The Messages API uses Anthropic’s typed envelope, which includes type but not a separate code field. (This differs from the Chat Completions and Responses APIs, where errors include both type and code.)

Mid-stream errors

If stream: true has flipped the response into SSE, errors arrive as an event: error frame before the stream terminates:

event: error
data: {"type":"error","error":{"type":"overloaded_error","message":"upstream overloaded"}}

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.

Provider passthrough

When an upstream provider (Anthropic, 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. The exception is upstream_empty_body, which Kindo emits (as the value of error.type) 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