Errors
Every error response has the same shape:
{ "success": false, "error": "This order can no longer be changed or cancelled here. Refresh the page to see its latest status.", "code": "order_not_editable" }
codeis stable and machine-readable. Your program should branch on it.erroris an English message for people. It may change.details(onvalidation_failedonly) lists each problem with the fieldpathand amessage.- The
X-Request-Idheader identifies the request. Quote it when you contact support.
How requests are checked
A path that doesn't exist (404 not_found) or a wrong method (405 method_not_allowed) is answered first. Then the checks run in this order, and the first that fails decides the error:
- The API key:
401 invalid_api_key,403 api_not_enabled,403 account_action_required. Too many failed attempts from one network are answered429 rate_limitedat this step. - The rate limit:
429 rate_limited. This comes before the permission check, so refused calls still count. - The key's permission:
403 insufficient_scope. - For writes, whether your account is on hold:
403 account_on_hold. - The id in the path, if it isn't a valid id:
404 not_found. - The query string and the body:
400 invalid_json,413 payload_too_large,415 unsupported_media_type,422 validation_failed. - The
Idempotency-Key:400,409 request_in_progress,422 idempotency_key_reused. Errors in the steps above never use up a key. - The business rules: a specific code with
404,409or422. An id in the path that is valid but doesn't exist or isn't yours returns404 not_foundon reads, and the endpoint's own code (such as404 order_not_found) on writes; each endpoint lists its codes.
General error codes
| Code | HTTP status | Meaning |
|---|---|---|
invalid_json |
400 | The request body is not valid JSON. |
idempotency_key_required |
400 | This request needs an Idempotency-Key header. |
invalid_idempotency_key |
400 | Idempotency-Key must be 1 to 255 visible ASCII characters. |
invalid_api_key |
401 | The API key is missing, malformed, revoked or no longer valid. |
api_not_enabled |
403 | API access is not enabled for this account. |
account_action_required |
403 | Sign in to the portal and finish the required account steps first. |
insufficient_scope |
403 | The API key does not have the permission this call needs. |
account_on_hold |
403 | The account is on hold. Writes are refused; reads still work. |
not_found |
404 | The resource does not exist or does not belong to this account. |
method_not_allowed |
405 | The path exists but does not support this method. The Allow header lists the supported methods. |
request_in_progress |
409 | A request with this Idempotency-Key is still running or its result is unknown. |
payload_too_large |
413 | The request body is larger than 1 MB. |
unsupported_media_type |
415 | The request body must be sent as application/json. |
validation_failed |
422 | The input is not valid. details lists each field and the reason. |
idempotency_key_reused |
422 | This Idempotency-Key was already used with a different request. |
request_rejected |
422 | The request was rejected by a business rule. |
rate_limited |
429 | Too many requests. Wait for the number of seconds in Retry-After. |
internal_error |
500 | Unexpected error. Quote X-Request-Id when you contact support. |
Business rule codes
Business rules return their own codes. Their status follows fixed rules:
- codes ending in
_not_foundare404: something in the path doesn't exist or isn't yours; - codes ending in
_changedare409: the data changed since you read it; read it again and decide again; - other state conflicts, such as
order_not_editableorshipment_not_cancellable, and uniqueness conflicts, such asstore_order_no_takenandlibrary_sku_taken, are409; - quota and usage limits are
409as well, because waiting doesn't reliably clear them; don't retry them automatically; - everything else is
422. An id inside the request body (a product, a shipping option) that doesn't exist or isn't yours is a422rule failure, not a404; - a rule failure we can't describe more precisely is
422 request_rejected.
The codes each endpoint can return are listed in its reference section. All business codes the API returns today:
| Code | HTTP status | Example message | Returned by |
|---|---|---|---|
library_not_in_library |
422 | This product is not in My products. Please refresh the page. | POST /v1/sku-mappings |
library_sku_taken |
409 | This SKU is already used for another product. | POST /v1/sku-mappings |
order_not_editable |
409 | This order can no longer be changed or cancelled here. Refresh the page to see its latest status. | PATCH /v1/orders/{id}, POST /v1/orders/{id}/cancel |
order_not_found |
404 | This order could not be found. | PATCH /v1/orders/{id}, POST /v1/orders/{id}/cancel |
order_product_not_allowed |
422 | Choose products from My products. Other products can't be added to your orders here. | POST /v1/orders/preview, POST /v1/orders, PATCH /v1/orders/{id} |
orders_unavailable |
422 | We can't take orders right now. Please contact your account manager. | POST /v1/orders/preview, POST /v1/orders, PATCH /v1/orders/{id} |
preference_channel_unavailable |
422 | This shipping option is no longer available. Please choose another one. | POST /v1/orders/preview, POST /v1/orders, PATCH /v1/orders/{id}, POST /v1/shipments |
product_not_reorderable |
422 | One of the products is no longer available to reorder. Please refresh the page and try again. | POST /v1/requests/reorder |
shipment_changed |
409 | This shipment was updated. Please review it again. | POST /v1/shipments/{id}/confirm |
shipment_not_cancellable |
409 | This shipment can no longer be cancelled here because we've already sent you the freight quote. Please contact your account manager. | POST /v1/shipments/{id}/cancel |
shipment_not_decidable |
409 | This shipment can no longer be confirmed or commented on. It may have been updated or already confirmed. Please refresh the page. | POST /v1/shipments/{id}/confirm |
shipment_not_found |
404 | This shipment could not be found. | POST /v1/shipments/{id}/cancel, POST /v1/shipments/{id}/confirm |
shipments_unavailable |
422 | We can't take shipments right now. Please contact your account manager. | POST /v1/shipments |
stock_short |
422 | Some products don't have enough available stock. Refresh the page to see the latest quantities and try again. | POST /v1/shipments |
store_order_no_locked |
409 | Orders from your store keep the store's order number, so it can't be changed here. | PATCH /v1/orders/{id} |
store_order_no_taken |
409 | You already have an order with this store order number. | POST /v1/orders, PATCH /v1/orders/{id} |
unknown_country |
422 | Choose your country from the list. | POST /v1/requests/sourcing |
The message column shows the current English text; it may change.
Handling errors
| Status | What to do |
|---|---|
| 400, 413, 415, 422 | Fix the request. Sending the same request again gives the same error. |
| 401, 403 | Check the key, its permissions and your account in the portal. Don't retry automatically. |
| 404 | Check the id; it may belong to another account. |
| 405 | Use a method from the Allow header. |
| 409 | Read the resource again with GET, then decide. For request_in_progress see Idempotency. |
| 429 | Wait the number of seconds in Retry-After, then retry. See Rate limits. |
| Network error or timeout on a write | Retry with the same Idempotency-Key. The first request may still be running, and a new key could create a duplicate. See Idempotency. |
500, or request_in_progress that doesn't go away |
Reads: retry with backoff. Writes: check the current state with GET, and use a new Idempotency-Key only if the write didn't happen. See Idempotency. |