Errors
The v2 response envelope, error shape, pagination wrapper, and retry guidance.
Response envelope (API v2)
Every v2 endpoint responds with one of these shapes
(backend/backend/app/api/v2/base.py:1-7):
// Success
{ "data": <payload>, "meta": { "request_id": "…", "timestamp": "…" }, "error": null }
// Paginated list
{ "data": { "items": […], "total": N, "page": N, "per_page": N, "pages": N },
"meta": { … }, "error": null }
// Error
{ "data": null,
"error": { "code": "…", "message": "…", "details": { … } },
"meta": { … } }
meta.request_idis generated server-side for every response — include it in bug reports to make logs greppable (ResponseMeta,app/api/v2/base.py:20-24).- Paginated lists default to
per_page: 20(PaginatedData,app/api/v2/base.py:43-50). Some v2 list endpoints use cursor pagination instead — follow themetacursor fields they return (app/api/v2/cursor_pagination.py). error.codeis a stable machine string;messageis human-readable;detailscarries structured context when available (ErrorDetail,app/api/v2/base.py:27-32).
:::note[Scope] This envelope is the v2 contract. Some legacy v1 routes predate it and return bare payloads — check the generated reference tables and prefer v2 routes for new integrations. :::
Retry guidance
- 429 / rate limited — back off and retry after the interval indicated by the response; the per-user windows are short (60 s, see Limits).
- 5xx — retry with exponential backoff and jitter; keep the same idempotency expectations as your original request.
- 4xx — do not blind-retry: fix the request.
error.detailsusually names the offending field.
Last updated 2026-08-25 (git-derived)