Jetron TicketFluid

Reservations

How holds, reservation tokens, and the X-Device-ID header work.

A reservation prices an attendee's cart and holds the stock for the checkout window, so tickets can't be sold out from under them while they pay.

const { data: reservation } = await client.createReservation('my-event', {
  items: [{ sku: 'ticket-type-uuid', quantity: 2 }],
  promoCode: 'EARLYBIRD', // optional
})

The response contains everything your checkout page needs:

FieldPurpose
reservationTokenUUID identifying the attendee's cart. Echo as X-Device-ID on order/release calls.
quoteReferenceOpaque handle to the priced, server-held quote. Send back when creating the order.
total / totalFeesPriced cart, in the smallest currency unit (Money).
discount / promoCodeApplied promo discount, if any.
itemsPer-ticket price and fee breakdown.
clientExpiresAtDeadline to drive your checkout countdown.

The X-Device-ID header

The reservationToken doubles as a device/cart identifier, sent as the X-Device-ID header:

  • Recommended: generate one stable UUID per attendee (persist it in the browser, e.g. localStorage) and send it on every call. Each attendee then maps to exactly one reservation, and repeated POST calls refresh and extend the same hold instead of holding fresh stock.
  • If omitted when reserving, the server mints a token and returns it, but it also falls back to reusing a single reservation per client IP + event, so distinct attendees behind the same IP (offices, campus networks) would share a cart. Supply your own per-attendee token in production.
  • Required when creating an order: echo the reservationToken verbatim.
// Refresh/extend an existing hold for the same attendee
await client.createReservation(
  'my-event',
  { items: [{ sku: 'ticket-type-uuid', quantity: 3 }] },
  { deviceId: reservation.reservationToken },
)

Expiry and release

Holds expire on their own after the checkout window. Use clientExpiresAt to show a countdown and prompt the attendee to re-reserve when it lapses.

To free the stock early (e.g. the attendee empties their cart):

await client.releaseReservation('my-event', {
  deviceId: reservation.reservationToken,
})
// → { released: true }

If no token is supplied, the server falls back to releasing the reservation held for your client IP + event; 400 is returned when there is nothing to release.

Availability reflects holds

quantityLeft on the tickets endpoint already subtracts stock held in other attendees' reservations, so what you display is what can actually be bought right now.

On this page