Docs sections
Idempotency
How to retry a request after a timeout or a dropped connection without selling one ticket twice.
Connections drop. A request may arrive and run while its response gets lost. To keep a retry from creating a second order, send the Idempotency-Key header:
http
Idempotency-Key: order-1042Rules
- The key counts in
POSTandDELETErequests.GET,PATCHandPUTdon't need it. - The key is any string up to 255 characters. Your own order number works well.
- A key lives 24 hours from the first request. Keys of different organizations and modes never overlap: a test request never gets a live response.
- A retry with the same key, method, path and body gets the stored response: the same status and the same body byte for byte, with the
Idempotent-Replayed: trueheader. - We compare the body without whitespace between JSON elements, but field order and number spelling matter.
{"a":1,"b":2}and{"b":2,"a":1}are different requests. - The same key with a different body or path gets
409 idempotency_conflict.
Where the key is required
POST /v1/events/{id}/issue answers 400 invalid_request without a key. Orders, reservations and events don't require one, but without it a retry creates a new object. Send the key with every request that creates something.
What a retry returns
| First request | Retry with the same key |
|---|---|
answered 2xx | the same response |
answered 4xx, such as 409 sold_out | the same refusal, even if tickets later went back on sale. A new attempt needs a new key |
| still running | 409 idempotency_conflict: retry in a few seconds |
failed with 5xx before we started creating the object | runs again |
failed with 5xx while creating an order, an event or an issue | 409 idempotency_conflict with details.idempotency_state: "unknown", see below |
a reservation confirm answered 202 | runs again and shows the order's current state |
Cancelling a reservation, cancelling a ticket, reissuing and publishing are safe by themselves: after a failure on our side a retry simply runs again.
Unknown outcome
If creating an order broke off on our side, the order may already exist. A retry with the same key answers like this:
Response 409
{
"error": {
"code": "idempotency_conflict",
"message": "Результат запроса с этим Idempotency-Key неизвестен: он мог выполниться. Проверьте состояние, прежде чем повторять запрос с новым ключом",
"details": {
"idempotency_state": "unknown",
"order_id": "0193e0c5-1f20-7c3e-b6a1-9d4e2f7a8b10"
}
}
}Read the order from details.order_id with GET /v1/orders/{id}. An order in paid or issued status is already sold, so you don't need a second one. Create a new order with a new key only if there is no order or it is cancelled.
Where the key has no effect
POST /v1/devices/invites: every call creates a new invite.POST /v1/events/{id}/seats: a seat upload replaces every seat of the draft, so repeating the same file gives the same result.POST /v1/events/{id}/imports: the same guest list for the same event returns the earlier import withrepeated_file: trueand issues no tickets the second time.PUT /v1/events/{id}/cover: a retry sets the same cover.