Skip to main content
Errors are JSON with a stable machine-readable code. Trigger one against staging right now:

The error envelope

Every error response has the same shape: There is no hint or retryable field — retryability is conveyed by HTTP status alone. Error envelopes never include the access block; the X-RateLimit-* headers are set on every response that reaches the rate limiter, including 400/404/429/5xx errors — but 401/403 authentication errors are rejected before the rate limiter runs and carry no X-RateLimit-* headers.

Error codes

These are the codes the API emits today, exhaustively:
The two 404 codes are ownership-scoped: on /v1/feedback they mean the target does not belong to your account, not necessarily that it never existed.

Warnings

Warnings are the API degrading gracefully instead of failing. They share the error shape — code, message, optional details — and arrive in a warnings array on search and document responses (/v1/feedback has no warnings field):
Warnings never invalidate the response. A 200 with warnings is a complete answer: the status stays 200, the payload is valid and usable, and warnings survives every verbosity preset and budget shed. Missing passage IDs and over-restrictive source policies are deliberately warnings, not errors — your agent gets whatever is available plus a signal about what it did not get.

Retrying

Retry 429 and 5xx with backoff; treat 4xx (other than 429) as bugs in the request, not transient failures.
  • There is no Retry-After header. On 429, read X-RateLimit-Reset (RFC3339) — limits use fixed one-second windows, so the reset is at most about a second away. Exponential backoff also works fine.
  • Rate-limit tokens are spent before validation, so retry loops sending invalid bodies still burn budget.
  • The SDKs and CLI retry automatically: the CLI retries 429 and 500+ up to 3 times with exponential backoff capped at 8 seconds (--no-retry disables).

CLI exit codes

caesar-search maps outcomes to exit codes so scripts branch on status, not output parsing. See CLI automation. With --json, CLI errors go to stderr as {"error":{"code","message","hint"}} — the code is taken from the API envelope’s error.code when one exists. Exit code 1 is not part of the contract.