Concepts
Errors
The error format, every error type with its status code, and what to do about it.
Format#
Every error has the same shape:
JSON
{
"error": {
"type": "validation_failed",
"message": "Some fields are not valid.",
"errors": [
{ "field": "email", "message": "must be a valid email address." },
{ "field": "brand_id", "message": "is required." }
],
"request_id": "req_3f9a1c0b7d2e4a65"
}
}typeis stable: write your code against it.messageis for people and may be improved over time.errorslists each field that is wrong (validation and query errors only).request_ididentifies the request in Quilo's logs.
Types#
| Status | type | What it means | What to do |
|---|---|---|---|
| 400 | invalid_request | The request itself is wrong: not JSON, wrong Content-Type, body over 64 KB, unknown query parameter, bad cursor, wrong method. | Fix the request; see message and errors. |
| 401 | authentication_failed | No key, not a Quilo key, unknown, revoked or expired key. | Check the header; create a new key if needed. |
| 403 | insufficient_scope | A read-only key tried to change something. | Use a key with Read and write access. |
| 403 | permission_denied | The person's role or brand access does not allow it, the workspace is read-only, API access is off, the company is suspended, or the person left the company. | Read message; ask an owner or admin. |
| 404 | not_found | No such record in your company (or you cannot see it), or no such endpoint. | Check the ID and the path. |
| 405 | invalid_request | Method not allowed on this endpoint (see the Allow header). | Use the listed method. |
| 409 | conflict | A unique value already exists (a sale's receipt number in that brand), or an Idempotency-Key was reused with a different body. | Look up the existing record, or use a new Idempotency-Key. |
| 422 | validation_failed | A field is missing, unknown, read-only, too long or has the wrong format, or brand_id/client_id is not in your company. | Fix each field in errors. |
| 429 | rate_limited | Too many requests for this key this minute. | Wait Retry-After seconds, then retry. |
| 500 | server_error | Something failed on Quilo's side. | Retry with backoff; contact support with the request ID if it persists. |
Which errors to retry#
| Retry? | Errors |
|---|---|
| Yes, with backoff | 429, 500, 502, 503, 504, network timeouts |
| No — fix first | 400, 401, 403, 404, 409, 422 |
Retrying a POST after a timeout can create the record twice. Send an Idempotency-Key so retries are safe.