Errors
All errors return a consistent envelope:
json{ "error": { "code": "invalid_request", "message": "`status` must be one of active, draft, archived", "details": { ... } // optional } }
Error codes
| Code | HTTP | When |
|---|---|---|
unauthorized | 401 | Missing or invalid API key |
forbidden | 403 | Key lacks required scope, or feature not on plan |
not_found | 404 | Resource does not exist for this store |
invalid_request | 400 | Body validation failed; check `details` |
method_not_allowed | 405 | HTTP method not supported on this path |
rate_limited | 429 | Hit per-minute or per-day limit |
conflict | 409 | State conflict (e.g. duplicate slug) |
plan_limit_exceeded | 403 | Subscription tier limit hit (e.g. max products) |
internal_error | 500 | Server-side failure; safe to retry with backoff |
Retrying
Safe to retry: 500, 502, 503, 504, and 429 (with Retry-After). Use exponential backoff with jitter.
Not safe to retry blindly: 4xx responses other than 429 โ fix the request first.