Errors
One error envelope, predictable codes.
Every 4xx and 5xx response from /v1 has the same shape. SDKs branch on type and code; humans read message and request_id.
The error envelope
404 Not Found · application/json
{
"error": {
"type": "not_found_error",
"code": "resource_missing",
"message": "No such order: ord_invalid",
"doc_url": "https://docs.tablezio.com/errors/resource_missing",
"request_id": "req_8b2c3d4e5f6a7b8c9d0e1f2"
}
}Always include the request_id when contacting support — it pinpoints the exact request in our logs.
Error types
| Status | Type | When |
|---|---|---|
| 400 | invalid_request_error | Malformed JSON, missing required fields, validation failure. |
| 401 | authentication_error | Missing, invalid, expired or revoked API key. |
| 403 | permission_error | The key authenticated but lacks the required scope. |
| 404 | not_found_error | The resource doesn't exist (or doesn't belong to this restaurant). |
| 409 | idempotency_error | An Idempotency-Key was reused with a different request body. |
| 422 | invalid_request_error | Body validated structurally but failed semantic checks. |
| 429 | rate_limit_error | Per-key rate limit exceeded. Retry after the X-RateLimit-Reset epoch. |
| 5xx | api_error | Something broke on our side. Safe to retry with the same Idempotency-Key. |
Common codes
| Code | Meaning |
|---|---|
unauthenticated | No key or invalid key. |
forbidden | Missing scope. |
resource_missing | 404 — bad ID or scope mismatch. |
invalid_request | Validation failure. Check the param hint if present. |
idempotency_key_in_use | Same key + different body. Use a new key. |
rate_limited | Too many requests this minute. |
api_error | Internal error. Retry safely. |
Retrying safely
Retries are safe for any idempotent request — GET, HEAD, DELETE — and for any mutation that carries an Idempotency-Key. Use exponential backoff with jitter, and give up after 5xx persists for more than ~60 seconds.