RU
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-1042

Rules

  • The key counts in POST and DELETE requests. GET, PATCH and PUT don'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: true header.
  • 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 requestRetry with the same key
answered 2xxthe same response
answered 4xx, such as 409 sold_outthe same refusal, even if tickets later went back on sale. A new attempt needs a new key
still running409 idempotency_conflict: retry in a few seconds
failed with 5xx before we started creating the objectruns again
failed with 5xx while creating an order, an event or an issue409 idempotency_conflict with details.idempotency_state: "unknown", see below
a reservation confirm answered 202runs 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 with repeated_file: true and issues no tickets the second time.
  • PUT /v1/events/{id}/cover: a retry sets the same cover.