Skip to content

Idempotency and retries

A request can time out after the order is placed but before the response arrives. The Idempotency-Key header makes a retry safe.

Every POST needs an Idempotency-Key header, max 255 characters. Use a new value, such as a UUID, for each new action. Reuse it for every retry of that action.

POST /api/public/v1/orders
Authorization: Bearer lxr_live_…
Idempotency-Key: 5b0e2c1a-6f7d-4e3b-9a8c-1d2e3f4a5b6c
Content-Type: application/json
Request Response
New key The request runs and its response is stored.
Same key, same request The stored response is replayed with Idempotent-Replayed: true. Nothing runs twice.
Same key, different request 422 idempotency_key_reused. Nothing runs.
Same key, same request, first still running 409 idempotency_request_in_progress. Retry shortly.
No key 400 idempotency_key_required. Nothing runs.
Key longer than 255 characters 400 idempotency_key_invalid. Nothing runs.
  • Same request means the same method, path, query and body, byte for byte. Retry with the original bytes; do not rebuild the JSON.
  • Scope. Idempotency keys are per API key. Two API keys can use the same value.
  • Retention. Keys are kept 7 days.
  • Stored responses: 2xx and 4xx only. A 5xx, or a request that never arrived, is not stored; a retry with the same key runs it again.
  1. POST /orders for ORD-1001 with Idempotency-Key: 5b0e… times out.
  2. Retry with the same key and the same body.
  3. If the first request placed the order, the retry returns the same 201 and order, with Idempotent-Replayed: true. No second order or stock reservation is made.
  4. If it did not, the retry places the order.

A retry with a new key answers 409 external_order_id_conflict with the existing order ID. Only the original idempotency key returns the original response.

Response Retry?
Timeout, connection error Yes, same key and body.
429 rate_limited Yes, after Retry-After seconds.
409 idempotency_request_in_progress Yes, same key and body, after a few seconds.
5xx Yes, same key and body, with backoff: 1 s, 2 s, 4 s, up to a minute.
409 version_conflict Read the record again, then send a new request with a new key.
Other 4xx No. Fix the request; send it under a new key.

GET requests need no idempotency key and are always safe to retry.