Skip to main content
Every write requires the Idempotency-Key header with a unique identifier that your system generates:

Why it is mandatory

Because the bad case is silent. You send a batch of 300 tickets, the request times out and you do not know whether it arrived. If you retry without an idempotency key and it had in fact arrived, you end up with 600 tickets and nobody finds out until the headcount does not add up on the day of the event. With the header, the retry returns the original response and executes nothing.

Behaviour

Same key, same body

Returns the stored response without executing again. The response carries the Idempotent-Replayed: true header.

Same key, different body

422 idempotency_key_reused. It is a safety net: it means you reused a key by mistake.

Key in flight

409 idempotency_in_flight if the operation is being processed at that very moment. Wait a second and retry.

Different keys

Two independent operations. Sending the same batch with two different keys does create everything twice.

How to generate the key

A UUID v4 will do. What matters is that it is stable across retries of the same logical operation and different between different operations.
If your operations already have an identifier of their own — an order number, say — use it. It is more robust than an in-memory UUID, because it survives your own process crashing:

Scope

The key is yours: two different integrators can use the same value without colliding, and the same key on two different endpoints are two different operations. Completed operations are remembered for 7 days. After that, the same key is treated as a new operation.

The accreditation case

POST /tickets/{code}/check-in uses the Idempotency-Key as the scan identifier. That makes it especially safe to retry: if the network dropped right after the ticket was redeemed, the retry returns the same wristband instead of issuing a second one. Generate one key per physical scan and keep it for the duration of the retries: