Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.auriko.ai/llms.txt

Use this file to discover all available pages before exploring further.

Auriko returns errors in the format matching the endpoint’s API family. OpenAI-compatible endpoints (/v1/chat/completions, /v1/models, etc.) use the OpenAI error envelope. Anthropic-compatible endpoints (/v1/messages, /v1/messages/count_tokens) use the Anthropic error envelope.

Error envelope

OpenAI error envelope

Every non-2xx response on OpenAI-compatible endpoints uses this shape:
{
  "error": {
    "message": "Model 'gpt-5-turbo' is not in the catalog. See the models endpoint for the current list.",
    "type": "not_found_error",
    "code": "model_not_found",
    "param": "model",
    "doc_url": "https://docs.auriko.ai/errors/model_not_found"
  }
}
FieldTypeRequiredPurpose
messagestringyesHuman-readable, actionable. Don’t branch on text.
typestringyesOne of six categories (see below). Drives SDK class.
codestring | nullyesStable machine identifier. Branch on this.
paramstring | nullyesOffending field name. null when not attributable.
doc_urlstringrecommendedLink to the error’s docs page.
providerstring | nullnoUpstream provider that generated the error. Null for non-provider errors.
suggestionstringnoActionable fix hint for routing/capability errors. Absent for other error types.
Notes:
  • The envelope is flat under error. There is no details[] array and no nested error objects.
  • Content-Type is application/json; charset=utf-8 on every error response.
  • The response body is never empty; even 401 and 404 carry the envelope.

Anthropic error envelope

Anthropic-compatible endpoints (/v1/messages and /v1/messages/count_tokens) return errors in the Anthropic Messages API format:
{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "message": "Request body must be a JSON object."
  }
}
FieldTypeRequiredPurpose
type (top-level)stringyesAlways "error".
error.typestringyesOne of nine categories (see table below).
error.messagestringyesHuman-readable description. Don’t branch on text.
error.suggestionstringnoActionable fix hint for routing/capability errors. Absent for other error types.
The Anthropic envelope doesn’t carry code, param, or doc_url. Routing failures include an optional suggestion with an actionable fix hint. Branch on error.type and HTTP status instead.
error.typeWhen
invalid_request_error400 — malformed or invalid request
authentication_error401 — missing or invalid API key
permission_error403 — authenticated but not allowed
not_found_error404 — resource doesn’t exist
request_too_large413 — payload exceeds size limit
rate_limit_error429 — rate or quota limit hit
billing_error402 — billing issue
api_error500 / 502 / 503 / 504 — server-side fault
overloaded_error529 — temporarily overloaded

Required headers

Every response — success and error — carries:
  • x-request-id — unique per request. Copy this when opening a support ticket. SDKs expose it as request_id (Python) / requestId (TypeScript) on every raised exception.
Error responses also carry, when applicable:
  • Retry-After — integer seconds. Present on 429 and 503. SDKs read this for automatic backoff.

Error types (OpenAI envelope)

The OpenAI envelope’s type field uses a closed set of six values:
typeWhenSDK class
invalid_request_error400 / 405 / 409 / 413 / 422 — malformed or semantically invalid requestBadRequestError (or ConflictError on 409)
authentication_error401 — missing, malformed, or invalid API keyAuthenticationError
permission_error403 — authenticated but not allowedPermissionDeniedError
not_found_error404 — resource doesn’t exist or isn’t visibleNotFoundError
rate_limit_error429 — rate or quota limit hitRateLimitError
api_error5xx — server-side fault or upstream failureInternalServerError (500) / APIStatusError (502 / 503 / 504)

Error codes

These 52 codes are the canonical set. Codes are stable — once published, meaning never changes.

Authentication and authorization

CodeHTTPtype
invalid_api_key401authentication_error
expired_api_key401authentication_error
insufficient_permissions403permission_error
feature_disabled403permission_error
mfa_required403permission_error
invalid_recovery_code401authentication_error
mfa_verification_failed401authentication_error

Request validation

CodeHTTPtype
invalid_request400invalid_request_error
missing_required_parameter400invalid_request_error
invalid_parameter_value400invalid_request_error
payload_too_large413invalid_request_error
context_length_exceeded400invalid_request_error
content_filtered400invalid_request_error
idempotency_conflict409invalid_request_error
field_immutable400invalid_request_error
operation_not_allowed400invalid_request_error
unknown_field400invalid_request_error
method_not_allowed405invalid_request_error
duplicate_resource409invalid_request_error
state_precondition_failed409invalid_request_error

Routing — capability

CodeHTTPtype
tools_not_supported400invalid_request_error
json_mode_not_supported400invalid_request_error
structured_output_not_supported400invalid_request_error
tools_with_structured_output_not_supported400invalid_request_error
vision_not_supported400invalid_request_error
reasoning_not_supported400invalid_request_error
thinking_disable_not_supported400invalid_request_error
streaming_not_supported400invalid_request_error
non_streaming_not_supported400invalid_request_error
batch_only400invalid_request_error
tier_opt_in_required400invalid_request_error
tool_choice_required_not_supported400invalid_request_error

Routing — constraint

CodeHTTPtype
cost_constraint_exceeded400invalid_request_error
latency_constraint_exceeded400invalid_request_error
throughput_constraint_not_met400invalid_request_error
provider_not_in_allowlist400invalid_request_error
provider_blocked400invalid_request_error
required_params_not_supported400invalid_request_error

Routing — policy

CodeHTTPtype
byok_keys_required400invalid_request_error
platform_keys_unavailable400invalid_request_error

Routing — modality

CodeHTTPtype
unsupported_modalities400invalid_request_error

Resources

CodeHTTPtype
model_not_found404not_found_error
resource_not_found404not_found_error

Rate limits and quotas

CodeHTTPtype
rate_limit_exceeded429rate_limit_error
budget_exhausted429rate_limit_error
insufficient_quota429rate_limit_error

Routing and providers

CodeHTTPtype
no_provider_available503api_error
upstream_error502api_error
upstream_timeout504api_error
model_unavailable503api_error

Server

CodeHTTPtype
internal_error500api_error
service_unavailable503api_error
Auriko abstracts over multiple upstream LLM providers. Error messages name the model and the upstream provider that produced the error. The provider name appears in error.provider and may appear in error.message. Failover across providers happens automatically before a 429 or 5xx surfaces to the client.

Retry policy

Branch on type and code, not on HTTP status alone. The SDK retry loop uses the same rules.
ConditionRetryableNotes
type: rate_limit_error + code: rate_limit_exceededyesHonor Retry-After header.
type: rate_limit_error + code: budget_exhaustednoTop up credits or raise the budget.
type: rate_limit_error + code: insufficient_quotanoAccount has no quota on the current plan.
type: api_error + status 500 / 502 / 503 / 504 (except code: internal_error)yesExponential backoff. Honor Retry-After on 503.
type: api_error + code: internal_errornoUnclassified fault; retrying won’t help. Contact support with x-request-id.
type: authentication_error / permission_error / not_found_error / invalid_request_errornoClient-side fix required.
Network failure before any response (DNS, TCP, TLS)yesSDK raises APIConnectionError.
Anthropic-compatible endpoints don’t carry code. The Anthropic SDK retries based on HTTP status.

Mid-stream errors (SSE)

Streaming endpoints return Content-Type: text/event-stream. When the HTTP status is already committed as 200 OK and an error occurs mid-stream, the envelope surfaces as a final data: event and the stream closes:
HTTP/1.1 200 OK
Content-Type: text/event-stream
x-request-id: req_01HXABCDEFGHJKMNPQRSTVWXYZ

data: {"id":"chatcmpl_01HX...","choices":[{"delta":{"content":"Hello"},"index":0}]}

data: {"error":{"message":"Upstream timed out after 30 seconds.","type":"api_error","code":"upstream_timeout","param":null,"provider":"openai","doc_url":"https://docs.auriko.ai/errors/upstream_timeout"}}
Rules:
  • Errors never emit as partial JSON or a different SSE event name.
  • data: [DONE] signals successful completion only. After an error event, no [DONE] follows.
  • The connection closes immediately after the error event.

SDK exception dispatch

The Python and TypeScript SDKs dispatch incoming envelopes to typed exceptions. Every instance exposes message, type, code, param, request_id, doc_url, status_code, retry_after_seconds, and provider.
import os
from auriko import Client
from auriko.errors import (
    AurikoAPIError,
    APIConnectionError,
    AuthenticationError,
    PermissionDeniedError,
    BadRequestError,
    ConflictError,
    NotFoundError,
    RateLimitError,
    InternalServerError,
    APIStatusError,
)

client = Client(api_key=os.environ["AURIKO_API_KEY"])

try:
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": "Hello!"}],
    )
except AuthenticationError as e:
    print(f"Check your API key. request_id={e.request_id}")
except PermissionDeniedError as e:
    print(f"Not allowed: {e.message} (code={e.code})")
except RateLimitError as e:
    print(f"Rate limited, retry after {e.retry_after_seconds}s")
except NotFoundError as e:
    print(f"Not found: {e.message} (param={e.param})")
except BadRequestError as e:
    print(f"Bad request: {e.message} (param={e.param})")
except ConflictError as e:
    print(f"Conflict: {e.message} (code={e.code})")
except InternalServerError as e:
    print(f"Server error. request_id={e.request_id}")
except APIStatusError as e:
    print(f"Upstream error ({e.status_code}): {e.message}")
except APIConnectionError as e:
    print(f"Network error: {e.message}")
except AurikoAPIError as e:
    print(f"API error ({e.status_code}): {e.message}")

Built-in retry

The SDK retries on APIConnectionError, rate_limit_error (except budget_exhausted and insufficient_quota), and api_error (except code: internal_error). Retries use exponential backoff and honor Retry-After when present.
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["AURIKO_API_KEY"],
    base_url="https://api.auriko.ai/v1",
    max_retries=2,
)

# Disable retries
client = OpenAI(
    api_key=os.environ["AURIKO_API_KEY"],
    base_url="https://api.auriko.ai/v1",
    max_retries=0,
)

Support

When reporting a failure to support, include the x-request-id from the response header (or request_id / requestId on the SDK exception). That single identifier pairs the client view with the server log.