Errors
Error format, status codes, and how to handle them.
Errors are JSON with the relevant HTTP status code. There are two response shapes depending on where the error originates.
1. Auth, store & rate-limit errors
Problems detected before validation (missing/invalid key, store not
authorized, store paused, rate limit) return a single error string:
{ "error": "API key does not authorize this store" }These are not retryable (except 429) — fix the credentials, store_id
or request, then resend.
2. Validation errors (422)
Invalid payloads return Laravel's validation shape: a summary message
plus a per-field errors map (dot notation for nested fields):
{
"message": "The customer.phone field is required.",
"errors": {
"customer.phone": ["The customer.phone field is required."]
}
}Not retryable — fix the payload before sending again.
3. Rate limit (429)
{ "message": "Too Many Attempts." }Returned with a Retry-After header (seconds) and X-RateLimit-* headers.
Retryable — wait for Retry-After, then resend. See
Rate limits.
Status code reference
| Status | Meaning | Shape | Retry? |
|---|---|---|---|
200 | Updated an existing record | resource | — |
201 | Created a new record | resource | — |
204 | Deleted (no body) | — | — |
400 | Missing store_id route parameter | { error } | No |
401 | Missing or invalid API key | { error } | No |
403 | Key not authorized for this store | { error } | No |
404 | Store unknown/paused, or record not found | { error } | No |
422 | Validation failed | { message, errors } | No |
429 | Rate limit exceeded | { message } | Yes — honor Retry-After |
5xx | Transient server error | — | Yes — exponential backoff |
Recommended handling
2xx → success, done
422 → fix payload, do NOT retry (read `errors` for the failing fields)
401 / 403 → fix credentials / store_id, do NOT retry
404 → check store_id (or that the record exists for PATCH/DELETE)
429 → wait Retry-After, then retry
5xx / net → exponential backoff + jitter, retry safelyRetries are always safe because writes are idempotent on
(store_id, external_id) — see Idempotency.