Skip to main content

Idempotency

A network error can hide whether a write succeeded. Send an Idempotency-Key header so that a retry returns the first result instead of creating a second record.

When to Send It​

RequestIdempotency-Key
POST /customers, POST /categories, POST /collections, POST /products, POST /inventory/adjustments, POST /orders, POST /returns, POST /refunds, POST /exchangesRequired
Every PUT, PATCH and DELETEOptional
Quotes (POST /returns/quote, POST /exchanges/quote) and POST /approvals/...Not used

The key is 1 to 128 characters. A UUID per operation works well. Sending the header with an empty value answers 400 IDEMPOTENCY_KEY_REQUIRED, also on requests where the key is optional.

How It Works​

  • A key belongs to your application and one operation (method and path) of one merchant.
  • The first request with a key runs normally and its response is stored for 7 days.
  • A retry with the same key and the same request (same path, query, body, X-Outlet-ID and X-User-ID) gets the stored response again, with the same status code and body. Nothing runs twice.
  • The same key with a different request answers 409 IDEMPOTENCY_KEY_REUSED.
  • While the first request is still running, a retry answers 409 IDEMPOTENCY_IN_PROGRESS. Wait a moment and retry with the same key.
  • Error responses 4xx from the operation itself are stored like successes: retrying a request that failed validation returns the same error. Fix the request and send it with a new key.
  • POST /orders has a second guard: an external_order_id your source already sent answers 409 DUPLICATE_EXTERNAL_ORDER_ID with data.order_id, the first order, whatever the key. See Creating Orders.
  • Responses 5xx are not stored: retrying with the same key runs the request again.
  • A rare case for POST /orders: the first request saved the order, but the server stopped before it stored the answer (for example a crash). A retry with the same key then answers 409 DUPLICATE_EXTERNAL_ORDER_ID with data.order_id, instead of the stored answer. That order_id is the order your first request made: read it with GET /orders/{id} and do not send the order again.
tip

Generate the key once per business operation (for example once per stock adjustment in your system), store it with the operation, and reuse it for every retry of that operation.