Error envelope
Every non-2xx error response uses the same envelope, mirroring the Anthropic/OpenAI error shape. Parseerror.code for machine-readable error
classification; error.message is for logging and humans — do not parse it
programmatically.
request_id is a UUID minted per request — include it when contacting
support, and use it to correlate a request across your own logs. Successful
responses carry the same id in the X-Request-Id response header and the
body’s request_id field.
Error codes
Theerror.code enum is locked; adding new codes is a minor version bump
per the versioning policy.
The enum also reserves
grounding_deferral and crisis_resources; deferral
and crisis outcomes are returned as 200 responses with deferral/crisis
payloads rather than as errors — see the Quickstart.
The 502 special case (sync generation failures)
On/v1/query, and on /v1/chat in sync mode (stream: false), a
generation-pipeline failure that produces nothing usable (empty answer, no
deferral, no crisis) returns 502 — and the body is still the
SyncResponse envelope, not the error envelope:
request_id for support correlation and error.message for display
(it’s always a generic sanitized string — internal error details are never
exposed). Retry with backoff.
When a PARTIAL answer (or a deferral/crisis short-circuit) exists alongside a
pipeline error, the endpoint returns 200 with the optional error field
populated instead.
Rate limits
Default limits for thestandard tier: 60 requests per minute, 5000
requests per day — shared across every /v1/* endpoint that requires a
key (/v1/query, /v1/chat, POST /v1/jobs, /v1/jobs/{id}, and
POST /v1/session-tokens) per API key. Submitting an async job is one
metered request and each poll is one more; the job’s background execution is
never metered. Minting a session token is itself one metered request, and a
session key does not get its own budget — it draws from its parent
long-lived key’s pool, so the limit is effectively per partner.
Every successful response carries rate-limit headers:
Read
X-RateLimit-Remaining on every successful response to self-throttle
before reaching 429. When you receive a 429, wait the number of seconds in
the Retry-After response header before retrying.