Back to the build library
Fitness & wellness
Standard

Class Booking and Waitlist

Run class calendars with real capacity limits, an automatic waitlist that promotes in order, and no-show policy that enforces itself.

Industry
Fitness & wellness
Build effort
Standard
Typical time to launch
2–3 weeks
On this page
The problemWhat gets builtHow it runsAutomations in detailWhat changesBefore you start
Want this built for you?

Bring your stack to a call and we will scope it against how your business actually runs.

Book a call
01

The problem

Class capacity is the one genuinely scarce resource a studio has, and most studios manage it with a mixture of a spreadsheet, a WhatsApp group and a coach who knows everybody. It works until it does not. The 6:30pm class is booked solid with twelve people, three of them do not turn up, and five people who wanted that slot were told it was full. The studio delivered nine paid-for places and turned away five customers in the same hour. Nobody notices, because the class looked full on paper.

Underneath that, three separate failures compound. The first is that there is no waitlist, or there is one and nobody works it, so a cancellation at 4pm for a 6:30pm class simply becomes an empty mat. The second is that no-shows have no consequence, which means the people who book speculatively keep doing it and the people who actually want the slot learn not to bother trying. The third is that the front desk absorbs all of it: every booking question, every swap, every “is there space in the Saturday class”, answered one message at a time by someone who should be selling memberships.

The money leaks in both directions. Unfilled capacity is revenue you have already paid a coach to deliver. Turned-away members are the ones who churn, because a member who cannot get into the class they want stops trying within about three weeks. And the admin time spent on manual booking management is the single biggest consumer of front-desk hours in most studios. The fix is not a better spreadsheet. It is capacity enforced by the calendar, a waitlist that promotes itself in order with a response window, a no-show policy that applies automatically and fairly, and an assistant that handles the booking traffic so the front desk does not have to.

02

What gets built

Calendars

The calendar configuration is the heart of this build, more than the pipeline is.

  • One class calendar per class type, not one per room. Each carries its own capacity, its own duration, its own booking window and its own cancellation cutoff. A 12-place strength class and a 20-place mobility class in the same studio are two calendars.
  • Capacity set per calendar, with the hard limit enforced at booking time. When capacity is reached the booking widget switches to waitlist mode rather than showing the class as unavailable. The difference between a waitlist that fills and one that does not is whether members can see it.
  • Booking window: opens 14 days ahead, closes 30 minutes before class start. Members booking two minutes before class is an attendance problem disguised as a convenience feature.
  • Cancellation cutoff: 4 hours before start. Inside that window, canceling still frees the place for the waitlist but counts as a late cancellation against the member.
  • Coach assignment with Google Calendar two-way sync, so a coach's own block removes availability.
  • Intro or beginner calendar with a lower capacity and a flag that routes first-time bookers to it where appropriate.
  • One-to-one calendar for PT and assessments, separate from class capacity entirely, round-robin across coaches.
  • Staff Cover calendar: internal, used when a coach calls in sick, so the cover request goes to the right group rather than a group text.

Pipelines and stages

The booking itself lives on the calendar, not in a pipeline. Two light pipelines handle the exceptions, which is where the operational work actually is.

Waitlist Management: one opportunity per waitlist entry, which makes the queue auditable:

  • Waitlisted: in the queue, position recorded.
  • Offered: a place has opened and the offer is out, response window running.
  • Confirmed: accepted and converted to a booking.
  • Declined: actively said no.
  • Expired: did not respond inside the window.
  • Class Passed: never promoted, class happened.

Attendance Exceptions: one opportunity per strike event:

  • No Show Recorded, Late Cancellation Recorded, Warning Sent, Restriction Applied, Appeal Raised, Strike Cleared, Restriction Lifted.

Custom fields

On the contact record:

  • Membership Type and Class Credits Remaining: checked at booking time.
  • Entitled Class Types: multi-select. Prevents a members-only class being booked by a drop-in.
  • Concurrent Bookings Held: number, incremented on booking and decremented on attendance or cancellation. Enforces the hold limit.
  • No Show Count 30 Days and Late Cancel Count 30 Days: numbers, recalculated nightly on a rolling window.
  • Total Strikes 30 Days: the sum of the two above, and the field the policy reads.
  • Booking Restricted Until: date. Any booking attempt checks this first.
  • Restriction Count Lifetime: number. A second restriction is a conversation, not another automated warning.
  • Waitlist Conversion Count and Waitlist Expired Count: tells you who actually takes the places they ask for.
  • Attendance Streak: number of consecutive booked classes attended. Used for recognition, and as the signal that someone reliable deserves the benefit of the doubt on a first strike.
  • Preferred Class Types and Preferred Times: text, written from booking history, used by BO for suggestions.
  • Last Class Attended and Days Since Last Class.
  • SMS Consent, SMS Consent Date, SMS Consent Source, Marketing Consent: kept separate from transactional.

On the booking record:

  • Class Type, Class Start, Coach, Booking Source (Self Serve, BO, Front Desk, Waitlist Promotion, Recurring).
  • Attendance Status: dropdown: Booked, Attended, No Show, Canceled In Window, Canceled Late, Canceled By Studio.
  • Waitlist Position At Booking: number, zero for direct bookings. Useful for reporting on how much revenue the waitlist is actually recovering.
  • Promotion Offered At and Promotion Response: timestamps and outcome, so the response window can be tuned on evidence.

Tags

  • booking-reliable: Attendance Streak of 10 or more. Gets the benefit of the doubt on a first strike.
  • strike-1, strike-2, strike-3: applied by the policy workflow, cleared by the rolling recalculation.
  • booking-restricted: active restriction. Checked by every booking path including BO and the front desk.
  • waitlist-active: currently queued for at least one class.
  • waitlist-no-response: two or more expired promotions in 30 days. Deprioritised in the queue, which is fairer to everyone else.
  • class-favorite-evening, class-favorite-morning, class-favorite-weekend: derived from history, used for fill campaigns.
  • first-time-booker: no attendance yet. Triggers the extra orientation detail in the confirmation.
  • appeal-open: suspends policy automation while a human looks at it.
  • do-not-contact: permanent suppression, transactional messaging excepted only where your rules allow.

Forms and surveys

  • Class Booking Widget: the public booking surface, embedded on the site and in the member area. Shows real remaining places, switches to a Join Waitlist button at capacity, and displays the current waitlist length honestly. “Full: 3 on the waitlist” converts better than “Full”.
  • Waitlist Join: captures the member, the class instance, and a confirmation that they can be messaged at short notice.
  • Cancellation Form: one screen with the class named, the cutoff status shown plainly (“this is inside the 4-hour window and will count as a late cancellation”), and a reason dropdown. Showing the consequence before the click reduces late cancellations on its own.
  • Strike Appeal: short form: which strike, what happened. Applies appeal-open and routes to the named override person.
  • Class Feedback: one question sent after a first class with a new coach or class type.
  • Timetable Request: a standing form asking members what times they want that do not exist. The accumulated answers are the best timetable-planning data a studio can have, and almost nobody collects it.

BO's role and guardrails

  • What BO does. This is where BO earns its place. The booking traffic is relentless and almost entirely routine. BO answers “what time is the Thursday evening class”, “is there space Saturday morning”, “who is teaching tonight”. Books, cancels and swaps classes by SMS and web chat. Puts members on waitlists and tells them their position. Handles waitlist confirmations and declines. Suggests alternatives when a class is full, using Preferred Class Types and Preferred Times. Explains the cancellation window and the no-show policy in plain terms. Tells a member how many credits they have left.
  • What BO never does. Never overrides capacity, not for anyone, for any reason. An over-capacity class is a safety issue, not a customer-service one. Never clears a strike or lifts a restriction. Never waives a late-cancellation charge. Never books a member into a class type they are not entitled to. Never gives training, injury, nutrition or medical advice in any form. Never quotes a membership price or a class-pack price. It routes to the front desk.
  • Escalation rules. A member disputing a strike or a restriction is routed to the named override person the same day, with appeal-open applied so policy automation stops. Any mention of injury, pain or illness goes to a coach immediately with no automated response beyond an acknowledgement. Any request to cancel a membership (as distinct from canceling a class) goes straight to a human. The keyword overlap between the two makes this a frequent and consequential misread, so handle it explicitly. Anything BO cannot classify with confidence is escalated rather than guessed.
  • Tone. Fast, factual, no filler. Booking messages are read in a hurry, often one-handed.

Numbers and channels

  • One dedicated number per site, A2P 10DLC registered, declared primarily as appointment reminders with a secondary marketing use case.
  • SMS carries everything time-critical: confirmations, reminders, waitlist promotions, cancellations by the studio. Waitlist promotion is SMS-first with push as a parallel channel if you have an app: email is far too slow for a 15-minute window.
  • Email carries the weekly timetable, the policy explanations, and anything with detail.
  • Web chat on the site and member area, answered by BO.
  • An inbound webhook for check-in events, and a second for class-instance changes pushed from the timetable if it is managed elsewhere.
  • Internal Slack channel #class-ops for coach-cover requests, low-attendance alerts and over-capacity exceptions.
03

How it runs, step by step

  1. A member opens the Class Booking Widget on Monday and looks at Wednesday 6:30pm strength. Capacity is 12 and 12 are booked, so the button reads “Full: join waitlist (2 waiting)”.
  2. She taps it. The Waitlist Join form captures her against that class instance. The platform creates a Waitlist Management opportunity at Waitlisted with position 3, applies waitlist-active, and sends SMS: “You are 3rd on the waitlist for Wednesday 6:30pm strength. If a place opens I will text you and you will have a short window to confirm. Reply SWAP if you would rather take a different class.”
  3. Tuesday afternoon, a booked member cancels through the Cancellation Form. The form shows him that he is outside the 4-hour window, so it is a free cancellation. His booking Attendance Status becomes Canceled In Window, his Concurrent Bookings Held decrements, and the class place is released.
  4. The waitlist promotion workflow fires within seconds. It finds position 1 in the queue for that class instance. That member carries waitlist-no-response from two prior expired offers, so the workflow deprioritises her to the back of the queue and moves to position 2.
  5. Position 2 is offered the place. Because the class is more than 4 hours away, the response window is 30 minutes. SMS: “A place has opened in Wednesday 6:30pm strength. Reply YES in the next 30 minutes and it is yours. Reply NO and I will pass it on.” Their opportunity moves to Offered and Promotion Offered At is stamped.
  6. Thirty minutes pass with no reply. The opportunity moves to Expired, Waitlist Expired Count increments, and the workflow immediately offers the place to the next in line: our member, now effectively position 1.
  7. She gets the offer SMS and replies YES within four minutes. BO confirms, the booking is created with Booking Source Waitlist Promotion and Waitlist Position At Booking 3, her opportunity moves to Confirmed, and Waitlist Conversion Count increments. The remaining waitlist re-numbers.
  8. She gets the standard confirmation: class, time, coach, address, what to bring, and the cancellation policy stated in one line with the cutoff time spelled out as an actual time rather than “4 hours before”.
  9. Wednesday, 24 hours before: reminder email with the class details and a one-tap cancel link. Two hours before: reminder SMS. Both carry the cancel link, deliberately: making cancellation easy is what makes the waitlist work.
  10. She checks in at 6:26pm. The check-in webhook sets Attendance Status to Attended, increments Attendance Streak, decrements Concurrent Bookings Held, writes Last Class Attended, and updates Preferred Class Types and Preferred Times from the pattern.
  11. Meanwhile a different member who was booked into the same class does not show and did not cancel. Ninety minutes after class start, the attendance reconciliation workflow sets his Attendance Status to No Show, increments No Show Count 30 Days to 2, recalculates Total Strikes 30 Days, and applies strike-2.
  12. Because this is strike 2 and he does not carry booking-reliable, he gets the second-strike message: the count, the policy in plain words, what happens at three, and the appeal route. The Attendance Exceptions opportunity moves to Warning Sent.
  13. Eleven days later he no-shows again. Total Strikes 30 Days hits 3. The policy workflow applies booking-restricted, writes Booking Restricted Until seven days out, increments Restriction Count Lifetime, cancels his forward bookings (releasing those places to their waitlists, which is the point), and notifies the front desk.
  14. He messages back disputing the last one. He says he checked in but the scanner did not register. BO does not argue or adjudicate. It applies appeal-open, which suspends the policy automation, routes to the named override person with the three strike records attached, and replies: “Passed to [Name], who will look at it today and come back to you.”
  15. The override person checks the door log, finds the scan, clears the strike, and lifts the restriction. The opportunity moves to Strike Cleared and then Restriction Lifted, Total Strikes 30 Days drops to 2, and he gets a short message confirming it with no bureaucratic hedging.
  16. Separately, Thursday's 7am class has 3 booked against a capacity of 14 at the 18-hour mark. The low-attendance workflow posts to #class-ops and fires a fill campaign to members tagged class-favorite-morning who have no booking that day: “Space in tomorrow's 7am if you want it: quiet one, good for working on form. [link]” Two book. The class runs rather than being canceled.
04

Automations in detail

Workflow 1: Booking Validation and Confirmation

Trigger. Any booking attempt, from the Class Booking Widget, from BO by SMS or chat, or from the front desk.

Conditions and branches. Validation runs in this order, and the first failure stops the booking.

  • Restriction check. If booking-restricted is applied and Booking Restricted Until is in the future, refuse with: “Bookings are paused on your account until [date] because of [n] missed classes in the last month. If that is not right, reply APPEAL and [Override Person] will look at it today.”
  • Entitlement check. If the class type is not in Entitled Class Types, refuse and offer the classes they can book.
  • Credits check. If Class Credits Remaining is zero on a pack-based membership, refuse and route to the front desk. Never let BO sell the top-up.
  • Hold limit check. If Concurrent Bookings Held is at the limit, refuse with: “You are holding [n] classes already, which is the maximum. Cancel one and I will book this straight away.”
  • Capacity check. If places remaining is zero, do not refuse: route to Workflow 2 and join the waitlist. This is the most important branch in the build.
  • Booking window check. If the class starts in under 30 minutes, refuse and suggest the next instance.

Actions in order, on a valid booking.

  1. Create the booking with Attendance Status Booked, write Class Type, Class Start, Coach and Booking Source.
  2. Increment Concurrent Bookings Held. Decrement Class Credits Remaining if applicable.
  3. Decrement the calendar's remaining places.
  4. Send the confirmation SMS immediately: “Booked: [Class Type], [day] [time], with [Coach]. Free cancellation until [actual cutoff time]. Cancel here: [link]” Note the cutoff as a real clock time, not “4 hours before”; members misread the relative version constantly.
  5. If first-time-booker, send the orientation email as well: where to park, what to bring, arrive 10 minutes early, the coach's name and photo.
  6. Schedule the reminder sequence: email 24 hours before with a cancel link, SMS 2 hours before with a cancel link.
  7. If this booking took the class to capacity, update the widget state so the next visitor sees waitlist mode rather than a disabled button.
  8. If this booking took the class from below to at or above the minimum viable attendance, cancel any pending low-attendance workflow for that instance.

Stop and exit. Exits on confirmation, on refusal, or on the member abandoning. Every refusal path offers an alternative rather than ending in a dead stop.

Workflow 2: Waitlist Join and Queue Management

Trigger. A booking attempt into a class at capacity, or a direct Waitlist Join submission.

Conditions and branches.

  • Run the same restriction, entitlement and credits checks as Workflow 1. A restricted member cannot join a waitlist either.
  • If the member is already on this class instance's waitlist, confirm their existing position rather than creating a duplicate entry.
  • If the member already has a confirmed booking for a class overlapping this one, warn before adding: “You are already booked into [other class] at that time. Want me to waitlist you for this and cancel the other if it comes through?”
  • If the waitlist is longer than twice the class capacity, say so honestly and suggest an alternative instance instead. A position of 26 is not a waitlist, it is a disappointment with a delay on it.

Actions in order.

  1. Create a Waitlist Management opportunity at Waitlisted, with the class instance, the timestamp and the queue position calculated from existing entries.
  2. Apply waitlist-active.
  3. Do not decrement Class Credits Remaining or increment Concurrent Bookings Held. A waitlist place costs nothing until it converts.
  4. SMS: “You are [position] on the waitlist for [Class Type] [day] [time]. If a place opens I will text you and you will have a short window to confirm. Reply SWAP if you would rather look at another class.”
  5. Offer the nearest alternative with space in the same message where one exists within 24 hours of the requested time.
  6. On SWAP, hand to BO to find and book an alternative, and remove the waitlist entry.
  7. Four hours before class start, if still at Waitlisted, send one honest message: “Still [position] on the waitlist for tonight and it is unlikely to open up now. [Alternative class] has space if you want it: [link]”
  8. At class start, move any remaining entries to Class Passed and remove waitlist-active if the member has no other live waitlist entries.
  9. Nightly, recalculate Waitlist Expired Count over the rolling 30 days and apply or remove waitlist-no-response at the threshold of 2.

Stop and exit. Exits on promotion (Workflow 3), on SWAP, on the member leaving the waitlist, or at class start.

Workflow 3: Waitlist Promotion

Trigger. A place becomes available on a class with a non-empty waitlist: a member cancels, a booking is canceled by the policy workflow, or capacity is increased by staff.

Conditions and branches.

  • Queue order. Offer to the lowest position first, except that anyone carrying waitlist-no-response is moved behind those without it. Fairness to the people who do respond beats strict first-come ordering.
  • Response window branch. If the class starts in more than 4 hours, the window is 30 minutes. If it starts in 4 hours or less, the window is 15 minutes. If it starts in under 90 minutes, offer to the top three simultaneously on a first-reply-wins basis and say so explicitly in the message: sequential offers cannot fill a slot that close to start.
  • Quiet hours branch. If the promotion would send before 07:00, hold it until 07:00 and shorten the window accordingly. If the class starts before 08:00 and the promotion could not be sent in time, auto-decline the remaining queue and notify the coach that the class is running one short.
  • Skip conditions. Skip anyone now restricted, out of credits, or holding a conflicting booking.

Actions in order.

  1. Select the next eligible member. Move their opportunity to Offered, stamp Promotion Offered At.
  2. Send SMS immediately: “A place has opened in [Class Type] [day] [time]. Reply YES in the next [window] minutes and it is yours. Reply NO and I will pass it on.” Send a parallel push notification if an app exists.
  3. Start the response timer.
  4. On YES: create the booking through Workflow 1's action block with Booking Source Waitlist Promotion and Waitlist Position At Booking set to their original position. Move the opportunity to Confirmed, increment Waitlist Conversion Count, write Promotion Response as Accepted, re-number the remaining queue, and send the standard confirmation with the cutoff time.
  5. On NO: move to Declined, write Promotion Response as Declined, and offer the place to the next in queue within seconds. A decline is a gift. Thank them for it: “No problem, thanks for the quick reply.”
  6. On window expiry: move to Expired, increment Waitlist Expired Count, write Promotion Response as No Response, send “The place has gone to the next person on the list. You are still on the waitlist for future openings.” and offer the place to the next in queue.
  7. Repeat down the queue until the place is filled or the queue is exhausted.
  8. If the queue is exhausted and the place is still open, release it to the public booking widget and, if the class is within 24 hours and below minimum viable attendance, hand to Workflow 6's fill campaign.
  9. Log every promotion, response and timing to the reporting layer. The response-window setting should be tuned on this data after a month, not guessed twice.

Stop and exit. Exits when the place is filled, when the queue is exhausted, or at class start. Exits immediately if the original canceling member rebooks inside the offer window. In which case the offer is withdrawn with an apology and the member goes back to position 1 with priority on the next opening.

Workflow 4: Cancellation Handling

Trigger. Submission of the Cancellation Form, a cancel link tap in a reminder, or a cancellation instruction handled by BO.

Conditions and branches.

  • In-window branch. More than 4 hours before class start. Free cancellation.
  • Late branch. 4 hours or less before start. Counts as a strike.
  • Studio cancellation branch. Staff canceling the class itself. Never counts against any member, and triggers a different message entirely.
  • Keyword disambiguation. If the instruction arrived as bare CANCEL by SMS, treat it as the global opt-out keyword and process the opt-out, then reply explaining how to cancel a class instead. If it arrived with a class reference, or as a reply to a specific reminder, treat it as a booking cancellation and confirm which class before acting.

In-window actions.

  1. Set Attendance Status to Canceled In Window.
  2. Decrement Concurrent Bookings Held, restore Class Credits Remaining if applicable, increment the calendar's remaining places.
  3. Fire Workflow 3 immediately. Speed here is the whole value of the waitlist.
  4. SMS: “Canceled: [Class Type] [day] [time]. No charge, credit back on your account. Want me to find you another slot this week?”
  5. If the member has canceled 3 or more times in window in 30 days, notify the front desk quietly. Not a strike and not a message to the member, but worth a human noticing.

Late branch actions.

  1. Show the consequence before confirming: “This is inside the [cutoff] window, so it will count as a late cancellation. Still want to cancel?” Require an explicit confirmation.
  2. On confirmation, set Attendance Status to Canceled Late, increment Late Cancel Count 30 Days, recalculate Total Strikes 30 Days.
  3. Release the place and fire Workflow 3 with the short response window.
  4. Hand to Workflow 5 for the strike messaging, so the policy copy lives in one place only.
  5. Do not charge anything automatically unless your published terms provide for it and the member agreed to those terms.

Studio cancellation actions.

  1. Set every booking on the instance to Canceled By Studio. No strikes, no credit consumption, credits restored.
  2. SMS every booked member and every waitlisted member immediately: “Sorry: tonight's [Class Type] is canceled. [Reason in one short clause]. Your credit is back. [Alternative class] has space if you want it: [link]”
  3. Post to #class-ops and notify the coach.
  4. Open a Staff Cover request first where the cause is coach illness, and only cancel if cover cannot be found within the configured window.
  5. 24 hours later, send one follow-up to everyone affected offering help rebooking. Studio-caused disruption is worth over-serving.

Stop and exit. Exits once the cancellation is processed and the waitlist has been fired.

Workflow 5: Attendance Reconciliation and No-Show Policy

Trigger. Scheduled, 90 minutes after every class start. Also triggered by the check-in webhook for the positive case.

Conditions and branches.

  • Attended. A check-in event matched the booking.
  • No show. Booking still at Booked, no check-in, class has passed.
  • Reporting-only mode. A build-level switch that records strikes but sends no member messaging and applies no restrictions. Run this for the first two weeks, always.
  • Reliability branch. If the member carries booking-reliable and this is their first strike in the window, record it but send the gentler first-strike copy and do not count it toward restriction. Ten consecutive attendances buys one benefit of the doubt.
  • Appeal branch. If appeal-open is applied, record the event but take no action and send nothing.

Attended actions.

  1. Set Attendance Status to Attended, write Last Class Attended, reset Days Since Last Class.
  2. Increment Attendance Streak. At 10, apply booking-reliable.
  3. Decrement Concurrent Bookings Held.
  4. Recalculate Preferred Class Types and Preferred Times, and the class-favorite- tags.
  5. If this was a first class with a new coach or class type, wait 3 hours and send the one-question Class Feedback.
  6. At a streak of 25, send a short recognition message. No gimmicks, no badges: “25 classes in a row booked and attended. Genuinely impressive consistency.”

No-show actions.

  1. Set Attendance Status to No Show, reset Attendance Streak to zero, remove booking-reliable.
  2. Increment No Show Count 30 Days, recalculate Total Strikes 30 Days, decrement Concurrent Bookings Held.
  3. Create an Attendance Exceptions opportunity at No Show Recorded.
  4. Strike 1: apply strike-1. Wait 1 hour, then SMS: “Missed you at [Class Type] tonight. No issue at all. Just a heads up that canceling more than [cutoff] ahead frees the place for someone on the waitlist. Three missed in a month pauses bookings for a week.” Informational, not punitive.
  5. Strike 2: apply strike-2, move the opportunity to Warning Sent. Wait 1 hour, then SMS: “That is 2 missed classes in 30 days. One more pauses bookings for 7 days. If something is making classes hard to get to, reply and we will sort it. That is a genuinely better outcome than a pause.”
  6. Strike 3: apply strike-3 and booking-restricted, write Booking Restricted Until as today plus 7 days, increment Restriction Count Lifetime, move the opportunity to Restriction Applied.
  7. Cancel every forward booking the member holds, and fire Workflow 3 on each released place. This is where the policy pays for itself.
  8. SMS: “Bookings are paused on your account until [date]: 3 missed classes in 30 days. Your forward bookings have been released. If any of those were wrong, reply APPEAL and [Override Person] will look at it today.”
  9. Notify the front desk and #class-ops.
  10. If Restriction Count Lifetime is 2 or more, do not send the automated message. Create a task for the front desk to call instead. A second restriction is a retention conversation.
  11. On APPEAL or Strike Appeal form submission: apply appeal-open, suspend all policy automation for that member, route to the Override Person with every strike record attached, and reply “Passed to [Override Person], who will look at it today and come back to you.” Nothing else.
  12. On a strike being cleared: decrement the relevant counter, recalculate Total Strikes 30 Days, remove the matching strike tag, and if Total Strikes falls below 3 remove booking-restricted, clear Booking Restricted Until, move to Restriction Lifted, and send a short, unhedged confirmation.
  13. Nightly, recalculate both 30-day counters on the rolling window, drop expired strikes, and lift any restriction whose date has passed with a message: “Bookings are open again on your account. [link]”

Stop and exit. Runs per class instance. The strike ladder exits on an appeal, on a cleared strike, or on the rolling window dropping the event.

Workflow 6: Low Attendance Fill Campaign

Trigger. Scheduled, every 2 hours. Selects class instances starting in the next 48 hours whose booked count is below the minimum viable attendance set for that class type.

Conditions and branches.

  • Branch A: 24–48 hours out. Soft fill: one targeted message to the most likely segment.
  • Branch B: 4–24 hours out. Broader fill plus a decision prompt to the studio manager on whether to run or cancel.
  • Branch C: under 4 hours. No campaign. Notify the coach and the manager with the final count and let them decide.
  • Exclude members already booked that day, members with booking-restricted, members out of credits, and members at the hold limit. A fill message to someone who cannot book is pure irritation.
  • Cap fill-campaign messages at one per member per week. This is marketing messaging and needs Marketing Consent, not just SMS Consent.

Branch A actions.

  1. Post to #class-ops: “[Class Type] [day] [time] has [n] booked against a minimum of [m]. Fill campaign going out to [segment size] members.”
  2. Select members carrying the matching class-favorite- tag whose Preferred Times overlap the slot.
  3. SMS: “Space in [day]'s [time] [Class Type] if you fancy it: quiet one, good session for working on form. [booking link]”
  4. Wait 6 hours. If still below minimum, widen the segment to all members with the matching time preference regardless of class type and send the same message with the class described.

Branch B actions.

  1. Send to the widened segment immediately if Branch A has not already covered them.
  2. Create a decision task for the studio manager at the 12-hour mark: run, cancel, or merge with an adjacent class.
  3. If the manager chooses cancel, hand to Workflow 4's studio-cancellation branch, which handles the member messaging properly rather than leaving it to a coach's group text.
  4. If the manager chooses merge, notify every booked member with the new time and require a confirmation reply, treating non-confirmers as cancellations with no strike.

Stop and exit. Exits when booked count reaches the minimum, when the manager decides, or at class start.

Workflow 7: Reminder, Swap and Member Self-Service

Trigger. Booking confirmed (schedules the reminders), plus inbound member messages handled by BO.

Conditions and branches.

  • Suppress the 2-hour SMS reminder if the member has already checked in, early arrivals exist and a reminder after arrival reads as sloppy.
  • If the member has do-not-contact, send transactional reminders only where your rules allow and nothing else.
  • Branch BO's handling by intent: availability question, book, cancel, swap, waitlist position, credits balance, policy question, or escalate.

Reminder actions.

  1. 24 hours before: email with class, time, coach, address, what to bring, and a cancel link.
  2. 2 hours before: SMS with time, coach and a cancel link. Keep it under two lines.
  3. If the class is a member's first ever, add a 12-hour-before SMS with the arrival instruction: “Come 10 minutes early tomorrow and ask for [Coach]. They will show you where everything is.”
  4. 30 minutes after class start with no check-in and no cancellation, send nothing. The reconciliation workflow handles it at 90 minutes; a mid-class “where are you” message is intrusive and often wrong.

Swap actions.

  1. On a swap request, BO identifies the current booking and the desired alternative.
  2. Check capacity on the target. If space exists, book the new class first, then cancel the old one. Order matters, canceling first can lose both places to a waitlist in the seconds between.
  3. If the target is full, offer the waitlist on the target while keeping the existing booking: “[Target] is full: I have put you 2nd on the waitlist and kept your [existing class] booking. If the swap comes through I will cancel the other one.”
  4. If the original class starts within the cancellation cutoff, warn that the swap will count as a late cancellation before doing anything, and require confirmation.

Self-service actions.

  1. Availability questions: answer with real remaining places and offer to book in the same message. Never answer with a link alone when the answer is known.
  2. Waitlist position: state the position and the honest likelihood based on historical promotion rates for that class instance pattern.
  3. Credits balance: state the number and the expiry date. Route any top-up to the front desk.
  4. Policy questions: answer in plain language with the actual cutoff times and strike counts, and link to the published policy.
  5. Anything about money, injury, membership cancellation, or a disputed strike: escalate per the guardrails, same day.

Stop and exit. Reminders exit at class start or on cancellation. BO's handling exits on resolution or escalation.

Workflow 8: Weekly Capacity Review and Timetable Intelligence

Trigger. Scheduled, Mondays at 07:00.

Conditions and branches. The digest always sends. Separate branches fire for persistent over-demand and persistent under-demand.

Digest actions.

  1. Calculate per class instance for the previous week: capacity, booked, attended, no-shows, late cancellations, waitlist length at peak, waitlist conversions.
  2. Compute utilization as attended divided by capacity, and the gap between booked and attended, which is the no-show cost in places.
  3. List the five most over-subscribed slots by peak waitlist length, and the five most under-subscribed by utilization.
  4. Summarize strike activity: new strikes, restrictions applied, appeals raised, strikes cleared.
  5. Summarize waitlist performance: offers made, accepted, declined, expired, and median response time.
  6. Email the studio manager and post to #class-ops.
  7. Include the week's Timetable Request submissions verbatim. Members asking for a 9:30am Tuesday class is the cheapest market research available.

Over-demand branch.

  1. If a class instance pattern has had a waitlist of 5 or more for 3 consecutive weeks, create a task for the manager with the recommendation to add a second instance or raise capacity if the space safely allows.
  2. Notify the members who were repeatedly waitlisted on that pattern when a new instance is added, before it goes on the public timetable: “You have been on the waitlist for Wednesday 6:30pm a few times. We have added a 7:45pm on Wednesdays. First look goes to you: [link]”

Under-demand branch.

  1. If a class instance pattern has run below minimum viable attendance for 3 consecutive weeks, create a task for the manager with the utilization history and the Timetable Request data for alternative times.
  2. If a decision is made to retire the slot, notify every member who attended it in the last 8 weeks individually, with the nearest alternatives and an offer to talk to a human. Quietly removing a class somebody organizes their week around is a churn event.

Stop and exit. One-shot weekly. The over- and under-demand branches exit when the manager closes the task.

05

What changes

The first change is that capacity becomes real. A class with twelve places holds twelve people, the thirteenth person goes on a visible waitlist rather than being told no, and when somebody drops out the place gets refilled automatically in the order people asked for it. The combination of a visible waitlist and fast promotion is what converts canceled places back into attended places, and it is almost entirely mechanical. The studio does not have to do anything.

The second change is that no-shows stop being free without anyone having to play enforcer. The policy applies itself, the member is warned twice in plain language before anything happens, the restriction is time-boxed and appealable, and the appeal suspends the automation while a person looks. That combination is what makes a no-show policy survivable: studios that enforce without warning generate complaints, and studios that warn without enforcing change nothing. The deliberate carve-outs. The reliability benefit of the doubt, the second-restriction human call, the reporting-only launch mode. Are what stop a correct policy from costing you good members.

The third change is the front desk's day. Most of the booking traffic in a studio is four questions asked a hundred times, and once BO handles availability, booking, canceling, swapping and waitlist positions, the person at the desk is free to do the things that actually generate revenue. This is the least glamorous benefit of the build and usually the one the owner notices first.

The fourth is that the timetable starts being designed on evidence. Peak waitlist length tells you where to add capacity; sustained low utilization tells you what to retire; the timetable request form tells you what to put there instead. Most studios make these decisions on instinct and a coach's opinion.

Metrics to watch

  • Utilization by class instance: attended divided by capacity. The headline operating metric, and the one that should move first.
  • The booked-to-attended gap, expressed in places rather than percentages. “We lost 34 places to no-shows last week” lands differently than “8 percent no-show rate”.
  • Waitlist conversion rate: offers accepted divided by offers made. Below about half means the response window is wrong or the messaging channel is too slow.
  • Median waitlist response time, used to tune the window on evidence after the first month.
  • Places recovered by the waitlist per week: the clearest revenue number this build produces. Count bookings with Booking Source Waitlist Promotion.
  • No-show and late-cancellation rates, trended weekly through the launch of enforcement. Expect both to fall in the first month and then plateau.
  • Restrictions applied, appeals raised, strikes cleared. A high appeal-success rate means your check-in data is unreliable, not that members are gaming you.
  • Turn-away volume: waitlist joins that reached Class Passed without promotion. This is unmet demand, and it is the number that justifies adding classes.
  • Classes canceled for low attendance, before and after the fill campaign goes live.
  • Front-desk booking interactions per week versus BO-handled interactions, as the measure of admin load actually shifted.
  • Attendance streak distribution across the member base, as a retention leading indicator. Members who can reliably get into the classes they want keep coming.
  • Opt-out rate as the guardrail on the fill campaigns, which are the only genuinely marketing messages in the build.

Capacity rules, cancellation windows and no-show policy need to match your own terms and your own timetable, so this build is configured per studio. Book a call at bookings.appbo.io to work through yours.

06

Before you start

Decisions to make before you build

  • Capacity per class type. Not per room: per class type. A strength class in the same room as a mobility class usually has a different safe capacity, and the calendar needs to hold each separately.
  • Your cancellation window. This guide uses 4 hours before class start as the free-cancellation cutoff, with a late cancellation counted the same as a no-show. Shorter windows are friendlier and make the waitlist less effective; longer ones are harsher and fill better. Pick one and publish it.
  • Your waitlist response window. This guide gives a promoted member 30 minutes to confirm when the class is more than 4 hours away, and 15 minutes when it is closer. Too long and the slot dies unfilled; too short and members miss the message.
  • Your no-show policy. The default here is three strikes in a rolling 30 days, then a booking restriction for 7 days. Decide the counts, the window, the consequence, and whether the consequence is a restriction, a charge, or a conversation. Make sure it is in your membership terms before you enforce it.
  • Your booking horizon and limits. How far ahead members can book, and how many classes they may hold at once. Unlimited forward booking is how one member ends up holding nine Saturday slots.
  • Whether late cancellation counts as a no-show. It should, otherwise the policy is trivially gamed.

Integrations to connect

  • Google Calendar two-way sync for every coach, so a coach blocking out their own time removes the class from availability rather than leaving members booking into a session nobody will teach.
  • Your access control or check-in system: the attendance data is what makes the no-show policy real. Without it you are enforcing a policy on guesses. Mindbody, Glofox, TeamUp, Zen Planner and most door systems can push a check-in event through Zapier, Make, or a direct webhook.
  • Stripe for class packs, drop-ins, and late-cancellation charges if your policy includes them.
  • Your membership system, so entitlement can be checked at booking time: is this member allowed into this class type, do they have credits left, is their payment current.
  • Slack if you want the internal low-attendance and over-capacity alerts in a channel rather than by email.

Numbers and messaging compliance

  • Provision a dedicated number for the studio and complete A2P 10DLC brand and campaign registration before launch. Booking and waitlist messaging is high volume and time-critical, so filtered traffic is not a minor inconvenience here. It breaks the build.
  • Most of this build is transactional messaging: booking confirmations, reminders, waitlist offers, cancellation notices. Collect SMS consent at signup anyway, with a separate unticked checkbox, and store consent source, date and IP.
  • Waitlist promotion messages are time-critical and should be exempt from quiet hours only where your own policy and local rules allow it. A 6am class promoting at 5:15am is a real case. Decide the rule deliberately rather than discovering it: the safer default is to send promotions no earlier than 7am and to auto-decline anyone on the waitlist for an early class who has not confirmed by then.
  • Honor STOP, UNSUBSCRIBE, CANCEL, END and QUIT. Note the collision risk: CANCEL is both a global opt-out keyword and the word members naturally use to cancel a class. Handle this explicitly. Treat bare CANCEL as the opt-out keyword and require a class reference or a confirmation step for a booking cancellation, and make sure your reply copy tells members which word to use.
  • Keep marketing messaging on a separate consent flag so a member who opts out of promotions still receives their class reminders where your rules permit.

Health data and legal

  • Keep any pre-participation or health screening separate from the booking flow, stored with restricted visibility, and never read by booking automation. A booking confirmation should never reference a member's health information.
  • If your no-show policy involves charging a fee, it must be clearly disclosed in the membership terms the member agreed to, and the amount must be in those terms rather than in any automated message. Charging a fee a member was never told about is a consumer-protection problem.
  • A booking restriction applied automatically should always be appealable to a human, and the automation should say so. Members with genuine reasons for repeated cancellations exist, and a policy with no override will cost you more in churn than it saves in capacity.
  • Set a retention period for attendance records and apply it.
  • None of this is legal advice. Have your own counsel review your cancellation and no-show terms, your fee disclosures and your messaging consent language before you enforce anything automatically.

Internal prerequisites

  • Accurate check-in discipline. If members get into class without scanning, the no-show policy will punish people who attended. Get this right before switching enforcement on: run the build in reporting-only mode for two weeks first.
  • A published, visible cancellation and no-show policy. Enforcement without publication generates complaints you cannot defend.
  • A named person who handles appeals and overrides, with the authority to clear a strike.
  • Agreement from coaches that the class list in the platform is the only class list. A coach keeping their own parallel list is how double-booking happens.
Field notes

Build it with us.

Every build on this page is something we configure, test and hand over with the SOPs your team needs to run it.

Book a call