HTTP Status Codes
Error Response Format
All error responses follow a consistent structure:API Error Codes
General Errors
Example
Authentication Errors
Example
Device Authorization Errors
Returned byPOST /device/token while an agent polls for approval. These follow RFC 8628, so three of the four are not failures — they report where the flow is, and only access_denied means stop.
authorization_pending and slow_down both carry details.interval, the number of seconds to wait (default 5).
Example
Wallet & Payment Errors
Example
required is max_price + the API fee, because an order with no
retailer_credentials_id is placed on a Zinc account and the item comes out of your
wallet. details.fund_with lists every way forward; when you already have your own
retailer account saved for that store it is listed first, as the
your_retailer_account rail, and naming it drops the balance required to the API fee
alone. See Retailer Accounts and
the rails.
Order Request Errors
unsupported_retailer, unsupported_country, and guest_checkout_not_supported are all predictable before you submit an order — ask GET /retailers/check with the product URL and destination country first.non_us_retailer is a legacy value that the API no longer returns. Zinc is not US-only; if you branch on it, that branch is dead.Example
External Service Errors
Example
Order Processing Errors
When an order fails during processing, theerror_type field in the order response or webhook payload contains one of these codes:
On a best-effort order,
some of these codes stop being failures. A code covered by a concern you relaxed
is recorded as an entry in
fulfillment.concessions and the order goes ahead —
the same code, reported as something that was worked around rather than something
that stopped the order.Structured error details
Alongside the flaterror and error_type keys (kept for backward compatibility), a failed job result may include an error_details object. This is the structured home for enrichment beyond the category and message — for example, the specific reasons a shipping address was rejected, or which fields failed validation.
Each entry in
field_errors is a FieldError:
Each entry in
line_rejections is a LineRejection: one order line the retailer rejected, as the retailer reported it. It’s currently reported for Amazon orders and is empty on order-level failures. Lines the retailer cancelled only because another line was rejected aren’t listed.
Example
Product Errors
An order sent with
fulfillment: { "items": "best_effort" } skips the offending
item and ships the rest instead of failing on these codes. The item’s status
becomes skipped, and the code lands in fulfillment.concessions. An order
whose every item was skipped still fails, as cart_empty.
Example
Price Errors
Example
Cart & Checkout Errors
Example
Gift Errors
An order submitted with
is_gift: true fails with this error type rather than
being placed as a normal order — a gift arriving with prices visible to the
recipient is treated as worse than no order. If gifting is an optional add-on in
your flow, catch this error type and retry without is_gift to place the order
as a standard purchase. See Gift orders.
Alternatively, opt out of the failure up front with
fulfillment: { "gift": "best_effort" } — a retailer with no gift option then
gets a normal order rather than none, and the order reports the substitution in
fulfillment.concessions.
gift_message does not fail this way. Where a retailer’s checkout has no
gift-message field, the order is still placed without the message.Example
Shipping Errors
Example
Payment Errors
Example
Account Errors
Example
Retailer Errors
Refusals you can predict
Three of these refusals are decided from the store and destination alone, so you do not have to submit an order to discover them.GET /retailers/check returns the
same code up front in unsupported_reason:
The codes are reused verbatim from the order path, so a refusal from
/retailers/check
and one from POST /orders for the same URL cannot disagree.
Example
Quantity Limit Errors
An order sent with
fulfillment: { "quantity": "best_effort" } buys the
retailer’s cap instead of failing with quantity_limit_exceeded, and reports the
requested and fulfilled counts in fulfillment.concessions. order_limit_exceeded
is your own account limit and is not relaxable.

