Cross-cutting
Errors
Every non-2xx response is a JSON envelope: { error: { code, message, request_id, …extras } }. Pin to the code, not the message.
Envelope
json{
"error": {
"code": "forbidden_entitlement_missing",
"message": "Your organization is not entitled to DAVA Connect. …",
"request_id": "req_a1b2c3d4",
"product": "connect"
}
}The code is stable — never localized, never reworded. The message may change between releases. Always branch on code in your client.
Common codes
| HTTP | Code | Meaning |
|---|---|---|
| 401 | auth_required | No session and no API key on a route that requires one. |
| 401 | invalid_api_key | Bearer token didn't verify, or the key was revoked. |
| 403 | csrf_mismatch | Cookie-auth mutation without a matching X-CSRF-Token header. |
| 403 | forbidden_entitlement_missing | Org isn't entitled to the product. Check /admin/orgs/<id>. |
| 403 | forbidden_entitlement_disabled | Entitlement exists but is paused. AVA staff toggles it back. |
| 403 | license_missing_<product> | Self-host license doesn't cover this product. |
| 403 | forbidden_staff_only | Customer account hit a staff-only route. |
| 404 | org_not_found / job_not_found / file_not_found | The named resource doesn't exist or isn't visible to this org. |
| 409 | bootstrap_already_done | First-run wizard hit on a system that already has users. |
| 410 | file_data_missing | File row exists but its bytes have been retention-swept. |
| 413 | file_too_large | Uploaded file exceeds the per-product cap. |
| 415 | unsupported_format | Connect/Norm/Dedup currently accept CSV/TSV; other formats land later. |
| 422 | validation_error | Pydantic body shape mismatch. Check the `fields` array on the response for specifics. |
| 429 | sandbox_budget_exhausted | Per-day sandbox-second cap hit. Comes back with a Retry-After header. |
| 502 | agent_llm_error | Upstream LLM call failed. The user message stays persisted; agent retry creates a new turn. |
| 503 | storage_unconfigured / agent_llm_unconfigured | Operator misconfiguration — should never happen on managed cloud; check env on self-host. |
Retry policy
4xx codes are caller errors — fix and retry, never blind-loop. 429 carries a Retry-After header with the wait-seconds. 5xx is server-side; SDKs back off exponentially with jitter (5 attempts max, ~30s total). 502 specifically on Agent is the LLM provider hiccupping — the user's message is already persisted, so retrying just creates a new turn.