Skip to main content
Every error from the Driftless API (whether you reach it through the CLI, the MCP server, or directly) comes back as the same JSON envelope. An agent should branch on the machine-readable code, not parse the human message.

The envelope

retryable is honest: the CLI auto-retries a GET once on a transient failure but never re-sends a write, and never retries a 4xx. If you build your own client, do the same.

Why a code at all

Input that’s wrong shouldn’t reach the agent as an opaque 500. Two layers guarantee that:
  1. Validation rejects a bad enum (status, visibility) with a field-level 400 before it touches the database.
  2. A Postgres-error translator catches any constraint violation that slips through and turns it into a coded 4xx, never a generic 500.
After those two, a 500 means what it should: a real bug or an outage. That’s also the only time retryable is true.

Code catalog

Validation & input

Access & identity

Governance & conflicts

Commercial allowance

These errors include the current usage snapshot and an actionable next_action for contacting sales. They are definitive (retryable: false).

Server

Observability

Every captured error is also emitted to PostHog (request_failed server-side, command_failed from the CLI) with code, status_code, and endpoint as properties, so the error surface is one queryable map, sliceable by type and endpoint rather than free-text. The exception text itself never leaves the log — join on request_id.