Errors return a consistent envelope: HTTP status, machine code, human message, and (for validation) per-field detail. Handle by code, not by message string — messages improve over time, codes are stable.
The envelope
{ error: { code: 'validation_failed', message: '...', details: [{field, issue}], request_id } }. Always log request_id — support can trace any call from it.
Common 4xx
401 invalid_key (re-auth), 403 insufficient_scope (key lacks the needed scope — the message names it), 404 not_found, 409 conflict (concurrent update — refetch and retry), 422 validation_failed (details array has per-field issues), 429 rate_limited (honor Retry-After).
5xx handling
500/503 are retryable with backoff — the SDKs do this automatically. Sustained 5xx: check status.turgo.ai before debugging your side.
Idempotency keys
POST endpoints accept an Idempotency-Key header: retries with the same key return the original result instead of double-creating. Use it on any create you might retry.