Failures carry the HTTP status that matters and an error object. Log error.message, and branch on error.code when it says more than HTTP_ERROR:{
"success": false,
"error": { "code": "HTTP_ERROR", "message": "Access token lacks the 'orders:write' scope" }
}
Validation failures from the request body list the offending fields in error.details:{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{ "field": "body.price", "message": "Input should be greater than 0", "type": "greater_than" }
]
}
}
Status codes#
| Status | Means | What to do |
|---|
400 | The request is malformed or the state is wrong for it | Fix the call; retrying changes nothing |
401 | No token, an expired one, or a revoked one | Mint a new token |
403 | The token is valid but lacks the scope, or the path is outside the public API | Check x-numu-scope on the endpoint |
404 | No such resource, or it belongs to another store | Check the id and the store_id in the path |
409 | Conflicts with current state (duplicate SKU, an order already paid) | Read error.message; often you already have what you wanted |
422 | The body failed validation | Fix the fields listed in error.details |
429 | Rate limited | Wait Retry-After seconds — see Rate limits |
5xx | Our fault | Retry with backoff; if it persists, tell us |
Retrying safely#
GET and DELETE are safe to retry as they are. For POST, a retry can create a second record — check for the resource before retrying, or use the natural key the endpoint offers (products upsert by SKU, for example).Retry 429 and 5xx with exponential backoff, starting around a second and giving up after a handful of attempts. Do not retry 4xx other than 429: the request will fail identically every time.Scope failures read clearly#
A 403 from a scope check names the scope it wanted:{ "success": false, "error": { "code": "HTTP_ERROR", "message": "Access token lacks the 'catalog:write' scope" } }
A 403 that says the operation is not permitted at all means the path is outside what any token can reach — admin, staff, billing, or token management. Those are not part of the public API. Modified at 2026-09-24 13:03:12