A reservation is a temporary hold on a ticket quota - the seats your customer is currently working through in checkout should not be bookable by anyone else, but if the checkout is abandoned the seats need to flow back into the pool. That is exactly what a reservation does.
Reservations exist for tickets (/api/v4/tickets/reservations) and for events (/api/v4/events/reservations). For tours the availability conflict is resolved at order creation or during request handling - there is no dedicated reservations route for tours.
This page covers lifecycle, refresh mechanics and edge cases. Concrete curl examples live on the tickets page under "Create a reservation".
Full endpoint and schema reference: Swagger.
Mental model
A reservation attaches to a ticket plus date/time plus quantity:
TicketReservation
├── ticket_id .... which ticket
├── start_at ..... when (date for normal, date+slot for time_slot)
├── quantity ..... how many seats
├── token ........ string, identifies the reservation in PUT/DELETE/order
└── valid_until .. expiry time
As long as valid_until is in the future, the seats are blocked and show up as taken in capacity / capacities. Once valid_until passes, the seats are automatically available again - you do not have to call DELETE.
Lifecycle
POST /reservations
│
▼
┌──────────────┐
│ valid │ ◀──── PUT /reservations/:token
│ │ extends valid_until
│ │
└──────┬───────┘
│
┌────────────┴────────────┐
▼ ▼
DELETE /reservations/:token valid_until reached
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ released │ │ expired │
│ (immediate) │ │ (passive) │
└─────────────┘ └─────────────┘
│ │
└────────────┬────────────┘
▼
seats back in the available pool
Endpoints
| Endpoint | Action |
|---|---|
POST /api/v4/tickets/reservations | Create a reservation, returns token |
PUT /api/v4/tickets/reservations/:token | Change quantity and extend valid_until |
DELETE /api/v4/tickets/reservations/:token | Release the reservation, seats free immediately |
Note: the endpoints are nested under /tickets/reservations (for ticket reservations) or /events/reservations (for event reservations), not at /reservations directly. Reservations exist as a sub-resource of the parent resource.
Lifetime and refresh
- Default lifetime: 5 minutes from
created_at. Usually enough for a lean checkout (confirm headcount, contact details, payment). - Refresh via PUT: each PUT resets
valid_untilto "now + 5 minutes". You can do this any number of times, but: - Hard cap: between
created_atandvalid_untilthere can never be more than 60 minutes. A single reservation can therefore live at most one hour, even with many refreshes. Longer checkout flows should detect when they approach the cap and either release the reservation or finalize the booking.
API users with the right permissions can set valid_until explicitly at creation (within the 60-minute cap). Public and shop tokens cannot - they always get the 5-minute default.
What happens at expiry
An expired token returns a validation error on PUT or when you try to use it in an order ("reservation not valid anymore"). There is no automatic resurrection - on expiry you must create a new reservation, which can mean the seats are gone in the meantime.
You do not need to DELETE expired tokens. The server cleans them up.
Reservation in the order
If the reservation is still valid and you create an order, pass the token in the order item:
{
"order": {
"items": [
{ "ticket_id": 247, "quantity": 2, "reservation_token": "RESERVATION_TOKEN" }
]
}
}
The server then takes the seats from that reservation, not from the free pool. If the reservation expired in the meantime, order create comes back with a conflict.
Once the order is finalized, the reservation is consumed. No DELETE needed.
Pitfalls
- The reservation token is the id. For PUT and DELETE use the token string from the create response, not the numeric
id. - More reservations = more pressure on availability display. Every valid reservation reduces the capacity other customers see. On checkout abandonment, actively call DELETE - otherwise the seats hold for 5 minutes for no reason.
- Refresh is also a quantity update. A PUT without a body does not refresh - it requires the
quantityfield, and the lifetime is extended at the same time. To extend lifetime only, send the current quantity again. - There is no lookup. You cannot ask the API "is this token still valid?". You only learn it is gone on PUT/DELETE/order-use. So a successful PUT doubles as your health check.
- Tours have no dedicated reservation route. Tour seats materialize with request confirmation or order finalize. The
tickets/reservationspattern does not map to tours - the request mechanism handles the availability conflict instead. - 60-minute cap. Long checkouts (login + address + payment + 3DS challenge) can run tight. Once you cross the 50-minute mark, either finalize or release and start again.
Related pages
- Tickets - the only resource with reservations; concrete curl examples
- Concepts - quota, order, order finalize
- Authentication - token types, which can set
valid_until - Best Practices - idempotency and retries