Eight workflows. Every one checks sms-opt-out before any SMS step and falls back to email rather than skipping the message entirely, because a booking confirmation is information the guest needs.
1. Booking Intake and Instant Confirmation
Trigger: a Booking Request form submission, a slot taken from the booking page, a booking captured by BO over SMS or web chat, a booking taken by the voice assistant, or a third-party platform booking arriving by integration.
Conditions and branches:
- Match the phone number and email against existing guests. On a match, link to the guest record and carry visit_count, last_visit_date, dietary_notes, seating_preference and no_show_count forward. A returning guest should never be asked twice for the same thing.
- If party_size is above your large-party threshold, do not confirm. Create the booking in Inquiry, apply large-party, send the Large Party Inquiry form, and alert the duty manager with a 60-minute response task.
- If the slot has no capacity, do not hold it. Offer the two nearest available times and the Waitlist Join link.
Actions in order:
- Create the booking in Held - Unconfirmed, write reservation_datetime, party_size, service_period, inventory_type and source_channel. Apply res-unconfirmed.
- Set release_deadline: 4 hours for a booking made more than 48 hours out, 60 minutes for a booking made inside 48 hours, 15 minutes for a same-day booking.
- Within 1 minute: send the confirmation request by SMS. [Venue] - holding a table for [party_size] on [day] at [time]. Tap to confirm: [link]. Need to change it: [link]. We hold unconfirmed tables for [window], so a tap now locks it in.
- Within 1 minute: send the same by email with a calendar attachment, the address, parking note and your cancellation terms quoted verbatim.
- On confirm: set confirm_status Confirmed, stamp confirmed_at, swap res-unconfirmed for res-confirmed, move to Confirmed, cancel the release clock, and evaluate workflow 3.
- If guest_type is VIP, additionally notify the duty manager immediately rather than waiting for the service sheet.
- If the date carries peak-date, or no_show_count is 2 or more, pass to workflow 3 for a card or deposit.
Exit: confirmed, released, routed to a human, or waitlisted.
2. Unconfirmed Chase and Auto-Release
Trigger: booking sits in Held - Unconfirmed.
Actions in order:
- At 50 per cent of the release window: one reminder. Still holding [day] at [time] for you - one tap confirms it: [link]. If plans changed, no problem, tap here and we will give the table to someone else: [link].
- At 15 minutes before release_deadline: final notice naming the exact release time.
- At release_deadline: release the capacity back to the calendar, move to Canceled - In Policy with cancellation_reason Unconfirmed, and send one plain message: We have released the table for [day] at [time] since we did not hear back. If you still want it, here is live availability: [link]. No hard feelings either way.
- Immediately on release: fire workflow 6 to backfill from the waitlist.
- Increment a soft counter on the guest record. A guest who fails to confirm three times gets no-show-history treatment on the next booking, meaning a card on file rather than a refusal.
Exit: guest confirms, cancels, or the hold is released. No guest receives more than two chase messages here.
3. Deposit or Card-on-File Capture
Trigger: booking reaches Confirmed and deposit_required evaluates true.
Conditions: deposit_required is set by your own rule set, typically party_size above a threshold, a date tagged peak-date, a private dining or exclusive-use booking, or a guest carrying no-show-history. The amount lives in your payment configuration and is never written into a message by the automation.
Actions in order:
- Send a Stripe payment or card-authorization link with the terms in plain words: what is held, when it is released, and what happens on a late cancellation or no-show, quoted from your published policy. Set deposit_status Requested, apply deposit-unpaid.
- Wait 12 hours. Not completed: one reminder. Wait 12 more hours: second reminder naming the date the hold lapses.
- At 48 hours unpaid, or 24 hours before arrival, whichever comes first: alert the duty manager with a task to call. Do not auto-cancel a deposit booking - a human makes that decision, because the guest may simply have a card problem.
- On payment or authorization: set deposit_status Held, swap deposit-unpaid for deposit-held, switch card_on_file, move to Secured, and send a receipt plus a restatement of the terms.
- On completed visit: set deposit_status Released and trigger the release or redemption in Stripe according to your policy.
- On a no-show or late cancellation: do not charge automatically. Create a task for the duty manager to decide and to contact the guest first. Set deposit_status Retained only after a human has acted.
Exit: deposit held, booking canceled by a human, or visit completed.
4. Pre-Arrival Enrichment and Reconfirmation Ladder
Trigger: scheduled relative to reservation_datetime, on any booking in Confirmed or Secured.
Actions in order:
- 72 hours before: move to Pre-Arrival, apply nothing loud, and send the Pre-Arrival Details form. [Venue] - looking forward to [day]. Two minutes here and we will have the table set up the way you want it, including anything you cannot eat: [link]. Skip the dietary questions for a returning guest whose answers you already hold, and instead ask them to confirm: Last time we noted [preference] - still right?
- On form submission: write occasion, dietary_notes, accessibility_needs, seating_preference and special_request. If an allergy is declared, set allergy_flag, apply allergy-present, and run the allergy branch in workflow 5.
- 48 hours before: if the form is not completed, one short nudge with the two questions that matter most - any allergies, and any occasion - answerable by reply.
- 24 hours before: the reconfirmation. Two buttons only. [Venue] tomorrow at [time] for [party_size]. Still good? Tap YES. Need to change or cancel? Tap here - the earlier we know, the better for both of us.
- On YES: set confirm_status Reconfirmed, stamp reconfirmed_at, apply res-reconfirmed, move to Reconfirmed. Stop reminding.
- 6 hours before, if still not reconfirmed: one last SMS, and add the booking to the at-risk list on the service sheet so the host stand knows. Do not cancel the booking - most unreconfirmed guests still arrive.
- 2 hours before, if still not reconfirmed and party_size is above the threshold: create a task for the duty manager to telephone. A large unreconfirmed party is the single most expensive thing in your book.
- 90 minutes before: the arrival message to every booking - time, address, parking or door detail, the host's name, and a reply route if they are running late. Cap total messages for this booking at four, counted in reminder_count.
Exit: reconfirmed, canceled, rescheduled, or arrival time passes.
5. Allergy, Accessibility and Special Request Routing
Trigger: allergy_flag set, accessibility_needs populated, or special_request containing text, from any source including the voice assistant.
Actions in order:
- Immediately: post to the service channel with the booking, the date, the exact wording the guest used, and the guest's contact. Never summarize an allergy; pass the words through.
- Immediately: create a task for the duty manager on shift for that service, due within 4 hours, to review with the kitchen and reply to the guest in writing.
- Wait 4 hours. Task not complete: escalate to the general manager. Wait 4 more hours: escalate again and flag the booking on the service sheet as unacknowledged. This chain should never go quiet.
- Human reply sent: log it against the booking so there is a record of what was promised to the guest, by whom, and when.
- Suppress the pre-arrival offer on any booking with allergy_flag set until the acknowledgement is logged. Selling a tasting flight to a guest whose allergy you have not yet answered is the wrong order of operations.
- Accessibility branch: notify the host stand and, where relevant, housekeeping or maintenance, with a task to confirm the specific arrangement - step-free route, accessible facilities, a particular table - and a written reply to the guest.
- Carry forward: write confirmed dietary and accessibility detail to the guest record so the next booking starts from it, within whatever retention period you have set.
Exit: acknowledgement logged. The workflow does not close itself on a timer.
6. Cancellation, No-Show and Waitlist Backfill
Trigger A - cancellation: guest uses a cancel link, replies CANCEL, cancels through BO, or a human cancels the booking.
- Capture cancellation_reason from the picker. Branch on timing against your policy window: outside it, move to Canceled - In Policy; inside it, move to Canceled - Late, increment late_cancel_count, and create a duty-manager task rather than taking any automated financial action.
- Release the capacity to the calendar immediately. This is the step that pays for the build.
- Send a short, graceless-free acknowledgement with a rebooking link: Canceled - thanks for telling us, it genuinely helps. Whenever you want to come back: [link].
- Immediately fire the backfill: query waitlist-active records matching the date and party size, ordered by waitlist_flexibility then by join time. Message the first three simultaneously with a first-come link and a 20-minute expiry. [Venue] - a table for [party_size] has just come free on [day] at [time]. First to tap takes it: [link]. Expires in 20 minutes.
- After 20 minutes with no taker: message the next five, widening to Same Day Any Time flexibility. After a further 30 minutes: release the slot to the public booking page and, if the date is within 48 hours, post it to your social channels.
- On a waitlist guest taking the slot, create the booking as Confirmed directly, skip the hold clock, and run workflow 4 from whichever point the lead time allows.
Trigger B - no-show: 20 minutes past reservation_datetime with no Arrived mark.
- Create a host-stand task to check the floor before anything else happens. Automation must not declare a no-show while the guest is standing at the bar.
- On confirmation from the host, move to No-Show, increment no_show_count, and release the capacity.
- Wait 2 hours, then send one message, written to learn rather than to scold: We had you down for [time] tonight and missed you - hope everything is all right. If something went wrong on our side, tell me and I will fix it. Capture any reply against cancellation_reason.
- At no_show_count 2: apply no-show-history, which makes a card on file a condition of the next booking. Never block a guest automatically; that decision belongs to the owner.
Exit: slot resold, or the service period ends.
7. Pre-Arrival Offer and Occasion Enrichment
Trigger: booking reaches Pre-Arrival with the details form complete, allergy_flag clear or acknowledged, and 36 or more hours remaining.
Conditions and branches: offer by occasion and guest_type, never a generic list.
- occasion Anniversary or Birthday: offer exactly two things - a bottle on arrival and something written on a plate. [Day] is a bit of an occasion. Two things we can have ready: a chilled bottle on the table when you sit down, or dessert with a message on the plate. Either, both, or neither - tap here: [link].
- occasion Business: offer the quieter table and a set-menu pre-order to save time, not celebration extras.
- inventory_type a room: offer early check-in, late checkout, parking, and breakfast added in advance - in that order, and never more than three.
- guest_type First Visit: offer nothing to buy. Send one message about what to expect and where to park. An unsold first visit that goes well is worth more than an upsold one that feels transactional.
- guest_type VIP: no automated offer. Create a task for the duty manager to make a personal call.
Actions in order:
- Set upsell_offered and apply upsell-offered. Send one message, on the guest's preferred channel, between 10:00 and 19:00 local.
- On acceptance: take payment through Stripe where your policy is to pre-charge, write upsell_items, set upsell_accepted, apply upsell-accepted, and post the item to the service channel so the kitchen, bar or housekeeping sees it on the sheet.
- No response after 24 hours: one reminder only if more than 24 hours still remain before arrival. Otherwise stop. One ask, one reminder, then silence.
- Never offer anything to a booking that is unconfirmed, carries an unacknowledged allergy flag, has a complaint logged against the guest record, or sits inside 12 hours of arrival.
Exit: accepted, declined, or the arrival window opens.
8. Daily Service Sheet, Post-Visit Review and Weekly Reporting
Trigger A: scheduled, 08:00 daily.
- Apply res-today and res-tomorrow, then build the service sheet by service period: time, name, party size, confirmation state, guest_type, visit_count, occasion, dietary_notes, allergy flags, accessibility needs, seating preference, pre-ordered extras and deposit state. Send it to the service channel and to the duty manager.
- Include three summary lines: total covers, covers reconfirmed, and bookings at risk because they are unreconfirmed inside 24 hours.
- Create one task per allergy flag not yet acknowledged, and one per large party not yet called.
Trigger B: stage moved to Completed.
- Wait 20 minutes after the completion mark, then send the two-question Post-Visit Feedback message. Twenty minutes is long enough to be out of the door and short enough to still be thinking about it.
- Score 4 or 5: reply with thanks and one direct review link to the single platform you most need. One link, not four.
- Score 3 or below: send no review link at all. Post to the service channel, create a duty-manager task to make personal contact within 24 hours, and log the resolution against the guest record.
- No response after 48 hours: stop. Do not chase feedback.
- Wait 14 days, and if consent_marketing is on, send one rebooking message referencing what you know - the occasion, the table they liked, the dish they mentioned. Then nothing for 90 days unless they engage.
Trigger C: scheduled, Monday 09:00.
- Send the owner and general manager the weekly report: covers by service period against capacity, no-show rate split by confirmation state, late cancellation rate with reasons, waitlist backfill rate and median refill time, pre-arrival form completion, occasion capture, attachment rate by offer type, channel mix with the direct versus third-party split, feedback scores and review volume, and repeat-visit rate.
- Flag any service period where reconfirmation rate fell below your threshold, and any day where released capacity went unsold, with the slot times, so the next week's staffing and promotion can respond to it.
Exit: none. The daily sheet and the weekly report run permanently.