Skip to main content
The API uses conventional HTTP status codes and returns exactly one JSON error envelope on every failure. Inspect error.code for programmatic handling; error.message is human-readable and may change.

Error envelope

string
Coarse class tied to the HTTP status (see below). SDKs subclass their exception types on type.
string
Stable, machine-branchable string. Switch on this — it is the one taxonomy that never changes meaning.
string
Human-readable explanation. Do not parse.
string
The id of the failing request (matches the x-request-id response header). Quote it in support requests.
string | null
The request field that caused the error, when the failure is attributable to one.
request_id is returned on every response — success and error — via the x-request-id header. On errors it is also mirrored inside the envelope. See the overview.

Types

type is the coarse class and maps onto the HTTP status. SDKs subclass their exception hierarchy on it.

Codes

code is the stable, machine-branchable string. Branch on it; it never changes meaning across versions.
version_conflict is a returned error: agent updates use optimistic concurrency, so a stale expected_version fails with 409. Refetch current_version and re-apply your change.

The four 409s are four different remedies

A 409 is not one thing, and the code is what tells you which. version_conflict means one versioned object is stale — re-read it and re-apply. revision_conflict means a whole shared declaration moved — merge, using the paths the message names. name_conflict means somebody else owns the name — pick another or adopt. job_not_ready and compliance_pending mean nothing is wrong at all — retry, and a client that treats them as terminal gives up on work that was going to succeed.

Handling errors

Retry 429 and transient 5xx responses with exponential backoff, honoring Retry-After on 429. Treat 400, 401, 402, 403, and 404 as terminal — fix the request or credentials rather than retrying. Branch a 409 on its code, never on the status — two of them are retryable and the rest are not.
Every mutation accepts an Idempotency-Key, so retrying a request that failed with a network error or 429 will not double-apply. See the overview.