Waitlist
Last updated: October 27, 2026
Waitlist
When a bookable is sold out and the event has waitlist_enabled, customers can join the waitlist straight from the widget. Promotion is FIFO per bookable (by waitlist_entries.created_at).
How it works
- The customer joins → a
WaitlistEntryis created inwaiting. - Capacity frees up (booking cancelled, hold expired, booking edited) →
OfferSpotOnCapacitypromotes the next waiting entry: stateoffered, a 64-charoffer_token, andexpires_at= now + 24 h (OfferSpotOnCapacity::DEFAULT_OFFER_TTL_HOURS). The customer gets aWaitlistSpotOfferedNotificationwith the/waitlist/claim/{token}link. - The customer opens the link — they must be logged in as the entry's user — and clicks Claim: state
claimed, then a redirect to the booking review page pre-seeded with the bookable and people count. - Completing that booking marks the entry
fulfilled(thewaitlist_entry_idis carried through; aBookingCreatedlistener is the safety net). - Decline →
cancelledand the next waiting entry is promoted immediately. waitlist:expire-claims(every 5 min) expires stale offered/claimed entries and promotes the next in line.
States
waiting → offered → claimed → fulfilled
↘ expired ↘ cancelled (declined)
Two kinds of entry
waitlist_entries.kind splits the table in two lifecycles that never mix:
capacity(default) — the sold-out flow above: account users queueing for freed capacity, FIFO promotion, claim link gated by token and the matching authenticated user.walkin— the door queue: staff take same-day walk-in parties on an Area, the guest is a name/phone pair (no account), the offer goes out over SMS/mail, and the claim page is token-only. Walk-in rows never auto-promote and are seated by hand — see door ops.
Permissions
Owner, admin and manager see waitlist state on the widget and in the booking flow. Joining and claiming are customer actions — the claim link is gated by the 64-char token and the matching authenticated user, no staff role needed. Walk-in queue writes need bookings.seat.