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; upstream HTTP errors are converted to the Anthropic envelope while preserving their status and message.

{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "max_tokens is required"
}
}
StatusTypeCommon codesCause
400invalid_request_error—Body fails schema validation (missing max_tokens, malformed messages, etc.), references a missing model, or is blocked by org DLP policy (e.g. binary document attachments that cannot be redacted).
401authentication_error—Missing, malformed, or revoked API key.
403permission_error—Model access is denied, or a credit or budget check refuses the request.
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. Honors Retry-After when present.
500api_error—Unexpected Kindo-side failure.
502api_error—A successful upstream response has no stream body. Example: {"type":"error","error":{"type":"api_error","message":"Upstream returned empty stream body"}}

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.)

A credit or budget check can return HTTP 403 before streaming starts, including when stream: true. The Anthropic envelope uses error.type: "permission_error"; inspect error.message for CHAT_DEPARTMENT_BUDGET_REACHED followed by an explanation. This identifier is in the message; this envelope does not add an error.code field. CHAT_INSUFFICIENT_CREDITS identifies a credit refusal instead.

A department budget can block a request even when the organization has credits. Do not retry a budget refusal while the budget still blocks the request. Ask your organization administrator to review it; see When a budget blocks a request.

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.

An upstream 4xx or 5xx keeps its HTTP status and is converted to the Anthropic envelope. error.type follows the HTTP status (for example, permission_error for 403); error.message carries the extracted upstream message, or the upstream body as text when no message can be extracted. Parse the HTTP status first and inspect the message for the refusal reason.