The five most common error envelopes — worked end-to-end
The Error Code Reference lists every code the platform can return — 732 at last count. This guide picks the five you will actually hit during integration and shows you the full response body, not just the code. Each section is a complete request-response pair: a cURL call, the exact error envelope you get back, and how to handle it in Node.js and Python. For the code registry and how to classify errors as retriable or terminal, see Error Codes and the Error-handling runbook.1. 422 — validation failure (VALIDATION_ERROR)
A 422 means the request body failed schema validation before any business logic ran. The envelope carries details.issues, an array of per-field objects naming the field, the error code, and a human-readable message.
Request
Response — 422
422 Error
422 Error
issues array is the actionable part. Each entry names the failing field, a machine-readable code you can branch on, and a message you can show to an operator. Walk the array and map each entry back to your form rather than showing the raw JSON:
issues, then retry with the same Idempotency-Key — the replay cache stores the corrected payload and returns the successful result. A 422 never dispatched anything, so reusing the key is safe.
2. 409 — idempotency conflict (CONFLICT)
When you send a second request with the same Idempotency-Key while the first is still running, the platform returns 409 CONFLICT. The first request owns the lock; the second must wait for it to finish and then replay the cached result.
Request
Response — 409 (in-flight lock)
409 Error
409 Error
Retry-After: 2 header. Wait that interval, then retry with the same key and body. When the first request completes, the retry receives the cached result — the response body you would have gotten from the original — and the header Idempotency-Replay: true confirms it was a replay, not a fresh execution.
IDEMPOTENCY_KEY_REUSED (also 409) and the fix is to correct the body or use a new key.
3. 429 — rate limited (RATE_LIMITED)
The global request limiter returns 429 with a body that tells you exactly how long to wait. The Retry-After header mirrors error.retry_after in the body — read whichever your HTTP client surfaces.
Request
Response — 429
429 Error
429 Error
retry_after value (seconds) reflects the actual bucket refill time. Honor it before any exponential fallback — a blind doubling may retry too soon and hit 429 again.
Idempotency-Key on the retry — a 429 is always a pre-dispatch rejection, so reusing the key cannot double-send.
The response also carries draft-ietf-httpapi-ratelimit-headers (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-RateLimit-Bucket and their no-prefix mirrors). Read them to track how close you are to the limit before you get a 429.
4. 401 — wrong API key class (UNAUTHORIZED)
Orbit API keys come in two classes: secret keys (dv_live_sk_…) for server-side calls and publishable keys (dv_live_pk_…) for client-side operations that do not move money. Using a publishable key where a secret key is required returns 401.
Request — publishable key on a send endpoint
Response — 401
401 Error
401 Error
X-API-Key (or Authorization: Bearer) but the key prefix does not match the endpoint’s required class. The fix is to use the right key:
5. 403 — missing scope (INSUFFICIENT_PERMISSIONS)
When the API key authenticates but lacks the scope required for the endpoint, the platform returns 403 INSUFFICIENT_PERMISSIONS.
Request
Response — 403
403 Error
403 Error
Distinguishing 401 from 403
Check
GET /me with the same key to confirm which case you are in: a 200 with the key’s scopes means 403; a 401 on /me means the key itself is the problem.
Where to go next
- Error Codes — the common codes with the envelope shape
- Error Code Reference — every registered code (732 total)
- Error-handling runbook — classify any code as retriable or terminal
- API error handling by example — retry wrappers in six languages
- Idempotent requests — the full idempotency contract