Skip to main content
Every error, on every endpoint, uses the same envelope:
  • error: a stable, machine-readable code. Branch on this.
  • message: human-readable; wording may change, so never parse it.
  • details: present on invalid_request, with one entry per failing field and an index when the payload is an array (census rows, enrollment member checks).

Error codes

Handling patterns that hold up

  • Branch on error, log message. Codes are contractual; messages aren’t.
  • 409 is usually success. Both conflict cases mean “the thing you wanted already exists”; fetch it and continue rather than surfacing an error.
  • Retry 500/503 with the same Idempotency-Key on POST/PUT. Replays within 24 hours are safe by construction; see Rate limits & idempotency.
  • Don’t blanket-retry 4xx. Other than 429 and the 410 re-quote flow, 4xx errors need a changed request, not a repeated one.