Skip to main content

Client API Errors

OMNI Client API guarantees machine-readable failures across REST (/v1/*) and hosted MCP (/mcp). This page is the authoritative v1.5 error contract.

Contract guarantees

  1. error.type and error.code are stable for programmatic branching.
  2. error.message is human-readable and can change; never parse it.
  3. error.request_id (REST) and error.data.request_id (MCP JSON-RPC) are required support correlation keys.
  4. New error codes can be added during beta; existing codes are not silently repurposed.

REST error envelope

{
  "error": {
    "type": "invalid_request | auth_error | permission_error | rate_limit_error | api_error",
    "code": "machine_readable_code",
    "message": "Human-readable message",
    "request_id": "req_..."
  }
}

Diagnostic headers to log on every failure

  • X-Request-Id
  • Omni-Required-Scopes (on 403 insufficient_scope)
  • Retry-After (on 429 rate_limit_exceeded)
  • Idempotency-Replayed: true (idempotent replay responses)

HTTP class mapping

error.typeTypical HTTP
invalid_request400, 409
auth_error401, 403
permission_error403
rate_limit_error429
api_error500, 502, 503, 504

Exhaustive v1.5 REST code registry

Derived from live handlers in webapp/client_api.py.
error.typeerror.codeHTTPRetry?Trigger
auth_errormissing_api_key401NoMissing/malformed bearer token
auth_errorinvalid_api_key401NoInvalid format, revoked key, or unauthorized key resolution
auth_errorauth_rejected403NoKey rejected by control plane
permission_errorinsufficient_scope403NoRequired scope missing
rate_limit_errorrate_limit_exceeded429YesBurst or sustained per-key limit exceeded
invalid_requestinvalid_parameter400NoInvalid integer/parameter coercion
invalid_requestmissing_q400Nofred.search missing q
invalid_requestmissing_series_id400Nofred.series missing series_id
invalid_requestunknown_tool400NoUnknown tool ID
invalid_requestmissing_idempotency_key400NoMissing header for mutating invoke/call
invalid_requestinvalid_json400NoBody not valid JSON
invalid_requestinvalid_payload400NoRequest schema invalid
invalid_requestidempotency_conflict409YesSame idempotency key currently in-flight
api_errorservice_disabled503YesKill switch enabled
api_errorauth_backend_unavailable503YesControl plane unavailable
api_errorinvalid_control_plane_response503YesControl plane payload invalid/incomplete
invalid_requestfred_invalid_request4xx passthroughNoUpstream FRED rejected request
api_errorfred_upstream_error5xx passthroughYesUpstream FRED transient/server failure
invalid_request or api_errormcp_invocation_failedpassthrough5xx onlyMCP invoke path failed; type depends on surfaced status

Endpoint-to-code coverage matrix (REST)

EndpointDeclared code set
GET /v1/healthmissing_api_key, invalid_api_key, auth_rejected, rate_limit_exceeded, service_disabled, auth_backend_unavailable, invalid_control_plane_response, insufficient_scope
GET /v1/openapi.jsonmissing_api_key, invalid_api_key, auth_rejected, rate_limit_exceeded, service_disabled, auth_backend_unavailable, invalid_control_plane_response, insufficient_scope
GET /v1/fred/searchmissing_q, invalid_parameter, fred_invalid_request, fred_upstream_error, plus auth/scope/rate/system codes
GET /v1/fred/series/{series_id}missing_series_id, invalid_parameter, fred_invalid_request, fred_upstream_error, plus auth/scope/rate/system codes
GET /v1/mcp/toolsauth/scope/rate/system codes
POST /v1/mcp/invokemissing_idempotency_key, invalid_json, invalid_payload, unknown_tool, idempotency_conflict, mcp_invocation_failed, plus auth/scope/rate/system codes
GET /mcpauth/scope/rate/system codes
DELETE /mcpauth/scope/rate/system codes
GET /sseauth/scope/rate/system codes

Hosted MCP JSON-RPC error envelope

{
  "jsonrpc": "2.0",
  "id": 3,
  "error": {
    "code": -32001,
    "message": "Unauthorized",
    "data": {
      "omni_code": "invalid_api_key",
      "request_id": "req_..."
    }
  }
}

JSON-RPC code mapping

JSON-RPC codeCategoryTypical source
-32700Parse errorInvalid JSON body before routing
-32600Invalid requestMissing/invalid JSON-RPC envelope or method
-32601Method not foundUnsupported MCP method
-32602Invalid paramsMissing tool name, missing idempotency key, invalid params
-32001Auth/permissionMapped auth_error and permission_error
-32002Rate limitingMapped rate_limit_error
-32603Internal errorMapped api_error and unhandled internal failures

omni_code to JSON-RPC mapping

omni_codeJSON-RPC codeRetry?
missing_api_key, invalid_api_key, auth_rejected, insufficient_scope-32001No
rate_limit_exceeded-32002Yes
missing_idempotency_key, invalid_payload, unknown_tool, idempotency_conflict, fred_invalid_request-32602idempotency_conflict only
auth_backend_unavailable, invalid_control_plane_response, service_disabled, fred_upstream_error, mcp_internal_error-32603Yes
Notes:
  • Transport-level parse/request failures (-32700, -32600, -32601) can omit omni_code.
  • request_id is always present in hosted MCP error payloads.

Retry policy (authoritative)

ConditionRetry?Rule
429 rate_limit_exceeded / -32002YesHonor Retry-After; otherwise bounded exponential backoff + jitter
503 auth_backend_unavailable / 503 invalid_control_plane_responseYesBounded backoff + jitter
409 idempotency_conflictYesRetry with same idempotency key
fred_upstream_error (5xx)YesRetry idempotently with bounded backoff
400 invalid_request* / -32602NoFix request first
401/403 auth/scopeNoFix key/scopes first

Deterministic handling algorithm

  1. Parse only machine fields (error.type, error.code, JSON-RPC error.code, omni_code).
  2. Retry only transient classes (429, 5xx, retryable JSON-RPC classes).
  3. Reuse idempotency key on all retried write-like operations.
  4. Emit structured logs with endpoint/method, idempotency key, and request id.
  5. Escalate persistent failures with request IDs and retry history.
  • /sources/client-api-reference
  • /sources/client-api-endpoints
  • /sources/client-api-retries
  • /sources/client-api-mcp-hosted