Appearance
Idempotency
Placing an order costs money, and networks fail. So every order request needs an Idempotency-Key header: if you send the same request again with the same key, you get the first answer again - never a second order.
This applies to:
http
POST /v1/teams/01JA…/orders
Idempotency-Key: 7b0c4c2e-5f0e-4a8e-9b0c-0f3e1d2c4b5a
Content-Type: application/json
{"items": [ … ], "tos_accepted": true}Rules
| Required | yes - a missing or malformed key answers 422 with an error on idempotency_key |
| Format | 1–255 visible ASCII characters (a UUID works well, or your own order id) |
| Scope | per team; keys of the Console API and the reseller API are separate |
| Lifetime | 24 hours |
What happens on a retry
| Situation | Answer |
|---|---|
| same key, same body, first request finished | the first response again, with header Idempotent-Replayed: true |
| same key, another body | 422, error: idempotency_key_reused |
| same key while the first request still runs | the second request waits up to 10 seconds for the first one and gets its response; after that 409, error: idempotency_key_in_progress (with Retry-After) |
| the first request was refused before an order was recorded (validation, rate limit, scope) | the key is free again - fix the request and send it with the same key |
| the first request was interrupted after its order was recorded | that order as it stands now, with 202 - never a second order. Poll the order (GET …/orders/{order}) for its state |
If a request fails unexpectedly after its order was recorded, the key answers 500 with error: order_unknown_state and the order_id: read that order instead of ordering again.
When an order fails with 502 checkout_unavailable, try again with a new key.
Choosing keys
- Generate a new key per order you intend to place, and keep it until you know the outcome.
- Using the id of your own order record (e.g.
shop-order-4711) makes a retry after a crash safe automatically. - Replays do not count against the order rate limit.
In the PHP SDK
orders($team)->create() sends a new UUID per call automatically, and reuses it for the retry after a token refresh. Set your own key with withIdempotencyKey() - see SDK orders.