Back to the build library
Any industry
Standard

No-Show Recovery Pipeline

Catch a no-show the moment it happens, run a staged rebooking sequence, and make the empty slot earn something instead of being written off.

Industry
Any industry
Build effort
Standard
Typical time to launch
1–2 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

A no-show is the only kind of lost sale that arrives on a schedule. You know the person's name, you know what they wanted, you know they chose a time, and you know exactly when they did not turn up. Every other lead in the business has to be found, qualified and persuaded. This one already did all of that and then simply failed to walk through a door. And yet in most operations the no-show is the single least-worked record in the database: the slot sits empty, somebody mutters about it, the appointment gets deleted or left to rot in the calendar, and the person is never contacted again.

The operational failure is that nobody owns the fifteen minutes after a missed appointment. At the moment the slot goes idle, the front desk is dealing with the person who did arrive. By the time the day settles down, the window has closed. The customer has moved on emotionally, assumed they are in trouble, or quietly booked with someone else. Worse, the appointment status itself is usually never updated. If nobody marks the record as a no-show, then nothing downstream can possibly fire: there is no event, no tag, no pipeline movement, and no report. The business cannot even count its no-shows, let alone recover them, because the data that would describe the problem is created by hand by the busiest person in the building.

The money leaks in three directions. First, the slot itself: capacity that was reserved, staffed and paid for, then consumed by nobody, and unlike most waste, it cannot be recovered later because time does not carry forward. Second, the acquisition cost: whatever was spent to produce that booking is written off in full, which quietly inflates the real cost per attended appointment well above the figure in the ad dashboard. Third, and largest over a year, the lifetime value of a customer who was one appointment away from starting and now never will. The fix is not shaming people into showing up. It is treating a missed appointment as a pipeline stage with an owner, a clock and a sequence attached, and treating the vacant slot as inventory that can be resold to someone on a waitlist while it is still worth something.

02

What gets built

Pipeline and stages

A dedicated No-Show Recovery pipeline. Appointments live on the calendar; recovery state lives here, so anyone can see at a glance who missed, who has been contacted, and who is back on the books.

  1. Scheduled: a future appointment exists. Records sit here only to be watched; nothing is worked.
  2. Awaiting Arrival: the appointment start time has passed and no arrival has been recorded. A holding stage with a short life, measured in minutes.
  3. Marked No-Show: the grace period expired. Entry point for everything that follows.
  4. Recovery In Progress: at least one recovery message has been sent, no answer yet.
  5. Reason Captured: the customer replied and told you why. The most valuable stage in the pipeline.
  6. Rebooked: a new appointment exists. Not yet proof of anything.
  7. Rebooked and Attended: the recovery actually worked. Terminal and good.
  8. Deposit Required: a repeat no-show who may rebook only with a card on file or a deposit taken.
  9. Unreachable: the ladder ran out with no response. Parked for the long-cycle nurture, not deleted.
  10. Do Not Rebook: the customer asked to be left alone, or the business decided. Terminal and quiet.

Calendars

  • Main service calendars: unchanged, but every one of them gets an explicit no-show grace period defined in minutes, by appointment type, so detection is a rule rather than a judgment.
  • Recovery slots calendar: a small number of protected slots per week reserved for rebooked no-shows, so the recovery message can offer a real time today or tomorrow rather than a date three weeks out. A recovery offer that cannot be honoured quickly is not a recovery offer.
  • Waitlist calendar: the same services, with availability derived from cancellations and no-shows rather than from the open grid. This is what WF-N7 sells into.
  • Buffers, per-day caps and minimum notice set per calendar so a same-day refill cannot be booked into a slot that has already started.

Custom fields

  • appointment_start_at and appointment_end_at (date/time), copied onto the contact record so workflows can do arithmetic without reading the calendar.
  • appointment_type (dropdown). What the slot was for. Drives copy, grace period and deposit policy.
  • provider_name (text or dropdown) and location_name (dropdown), who and where. Essential for multi-site and multi-provider reporting.
  • arrival_recorded_at (date/time). The single field that distinguishes attended from missed. If this is empty when the grace period ends, it is a no-show.
  • no_show_marked_at (date/time): starts the recovery clock.
  • no_show_count_90d and no_show_count_lifetime (number): the policy fields.
  • last_no_show_at (date/time).
  • no_show_reason (dropdown: Forgot, Work or childcare, Transport, Illness, Cost concern, Changed mind, Booked elsewhere, Wrong time in calendar, No reason given) and no_show_reason_free_text (long text).
  • no_show_reason_captured_at (date/time).
  • recovery_attempt_count (number): hard cap of 5 across the whole ladder.
  • last_recovery_contact_at (date/time). The field that prevents a second workflow from double-contacting.
  • rebooked_appointment_at (date/time) and rebook_lead_time_hours (number): how far out the new booking sits. Short lead times attend far better than long ones, and this field is how you prove it.
  • reliability_flag (dropdown: Reliable, Watch, Deposit Required, Do Not Rebook). The one field the front desk actually reads.
  • deposit_required (checkbox), deposit_link_sent_at and deposit_paid_at (date/time).
  • recovery_owner (user). A named person, never "the team".
  • preferred_channel (dropdown: SMS, Call, Email, WhatsApp): set from behavior, not from a guess.
  • waitlist_opt_in (checkbox) and waitlist_notice_window (dropdown: Any time, Same day only, 24h notice needed).
  • slot_refilled (checkbox) and slot_refilled_minutes (number): how long the vacated slot took to resell.
  • late_cancel_at (date/time). A cancellation inside the notice window is a different event from a no-show and must be measured separately.

Tags

no-show, no-show-recovery-open, no-show-reason-captured, no-show-rebooked, no-show-recovered, no-show-repeat, no-show-unreachable, late-cancel, deposit-required, deposit-paid, do-not-rebook, waitlist-member, recovery-escalated, recovery-cap-hit.

Forms and surveys

  • One-tap reason picker: a single question, six buttons, no login and no name field, served from the link in the first recovery text. It writes no_show_reason on tap, before the page even finishes loading, so an abandonment still captures the answer.
  • Rebook page: the reason picker's second step: live availability for the same service and provider, with the recovery slots calendar surfaced first.
  • Deposit page: for repeat no-shows: a short explanation of the policy in plain language, then the card capture, then availability unlocks. Never availability first.
  • Waitlist join form: name, service, provider preference, and waitlist_notice_window. Two questions longer than this and nobody completes it.

BO's role and guardrails

  • BO handles inbound replies to every recovery message across SMS, web chat and social DMs, which is most of the traffic this build generates: "sorry, can we do next week", "what time have you got", "I thought it was Thursday".
  • BO's jobs are narrow and three in number: classify the reason into no_show_reason, offer real availability, and confirm the rebooking. Nothing else.
  • Guardrails. BO never discusses or negotiates fees, deposits, or policy exceptions. Any message containing a fee, refund, complaint or legal word is handed to recovery_owner immediately with the thread attached. BO never gives clinical, legal or financial advice. BO never implies obligation, debt or consequence. BO never argues with a customer who says the appointment was a different time: it apologizes for the mix-up and offers times.
  • Escalation rules. Two consecutive turns without progress, any detectable distress or anger, any mention of a bereavement or hospital, or any request to speak to a person: hand off, tag recovery-escalated, create a task due in one hour.
  • BO's knowledge base holds services, durations, provider availability rules, the grace period, the deposit policy in the exact words the business will stand behind, and an explicit list of refusals.

Numbers and channels

  • The existing business number for all recovery SMS. The recovery message must land in the same thread as the booking confirmation and the reminder, or it reads as a scam.
  • Voice AI follow-up on day two for high-value appointment types and for contacts whose preferred_channel is Call. A short, polite, single-purpose call that offers two times and transfers to a human on request.
  • Email as the fallback channel where SMS consent is absent, and as the carrier for the longer policy explanation that does not belong in a text.
  • Internal channel: a Slack or Teams channel for same-day no-shows at locations with a waitlist, so a human can also work the phone while WF-N7 blasts the list.
03

How it runs, step by step

One customer, end to end

  1. 9:00am, Tuesday. An appointment is scheduled for 10:00am. The record sits in Scheduled. The reminder ladder has already done its work the day before and two hours out; neither produced a confirmation tap.
  2. 10:00am. The appointment start time passes. No arrival has been recorded, so arrival_recorded_at is empty. The record moves to Awaiting Arrival and a countdown begins.
  3. 10:12am. The grace period for this appointment type is twelve minutes. It expires. The platform checks one last time for an arrival stamp, a cancellation, or a reschedule, none exists, and marks the record Marked No-Show. no_show_marked_at is stamped, no_show_count_90d increments to 1, the no-show tag is applied, and the slot is released on the waitlist calendar.
  4. 10:13am. Two things happen in parallel. The customer gets the first recovery text: warm, blameless, one question. And WF-N7 starts offering the now-empty 10:00am to 10:45am window to waitlist members who accept same-day notice.
  5. 10:19am. The customer taps Forgot on the reason picker. no_show_reason and no_show_reason_captured_at are written, the record moves to Reason Captured, the rest of the recovery ladder is canceled, and she is dropped straight onto the rebook page.
  6. 10:21am. She does not book. She closes the tab. Because the reason was captured and the ladder was canceled, a different and much gentler sequence takes over: one nudge in four hours, then one tomorrow morning, then stop.
  7. 2:20pm. The four-hour nudge arrives with two specific times in the message text rather than a bare link. She replies "the Thursday one works".
  8. 2:20pm. BO reads the reply, confirms Thursday 4:30pm against live availability, books it, and answers in the same thread. rebooked_appointment_at is written, rebook_lead_time_hours calculates to 50, the record moves to Rebooked, and the no-show-rebooked tag is applied.
  9. Immediately after. Because this contact now has one no-show on record, her reliability_flag is set to Watch. That does not change what she is charged or what she is told; it changes the confirmation treatment her new appointment receives.
  10. Thursday, 8:30am. The hardened confirmation sequence runs: an extra reminder the night before, a 90-minute-out text requiring a reply of Y to confirm, and the address with parking instructions attached, because "transport" and "wrong time in calendar" are two of the most common reasons and both are fixable with better information.
  11. Thursday, 3:05pm. She replies Y. The appointment is flagged confirmed and removed from the at-risk list the front desk reviews each morning.
  12. Thursday, 4:28pm. She arrives. arrival_recorded_at is stamped. The record moves to Rebooked and Attended, no-show-recovered is applied, reliability_flag is scheduled to return to Reliable after 90 clean days, and she flows into whatever post-service build the business runs: review request, onboarding, recall.
  13. Meanwhile, the original slot. A waitlist member accepted the 10:00am window at 10:31am. slot_refilled is true and slot_refilled_minutes is 19. The hour was not lost, and the business has a number that proves it.
  14. The alternative ending. Had she never replied, the ladder would have run its five attempts across seven days, moved her to Unreachable, dropped her into the quarterly win-back list, and stopped. Nobody would have chased her a sixth time, and nobody would have had to decide not to.
04

Automations in detail

WF-N1 · No-Show Detection and Marking

Why this workflow exists: every other workflow in this build depends on a reliable no-show event. Built by hand, that event is created inconsistently or not at all. This workflow creates it from the absence of data rather than the presence of it, which is the only way it happens every time.

Trigger: scheduled check running every 5 minutes against all appointments whose appointment_start_at is in the past 4 hours.

Conditions (all must be true to mark a no-show):

  • arrival_recorded_at is empty.
  • Appointment status is not Canceled, Rescheduled or Completed.
  • Now is later than appointment_start_at plus the grace period for this appointment_type: suggested defaults: 10 minutes for short service slots, 15 minutes for consultations, 20 minutes for anything requiring travel to site.
  • The appointment was not created inside the grace window itself, which otherwise produces false positives on walk-ins.

Actions, in order:

  1. Set appointment status to No-Show and stamp no_show_marked_at = now.
  2. Increment no_show_count_90d and no_show_count_lifetime; set last_no_show_at = now.
  3. Add tag no-show and no-show-recovery-open. Move record to Marked No-Show.
  4. Assign recovery_owner: the provider who was due to see them, or the front desk user on shift, by round robin. Never leave this empty.
  5. Release the slot to the waitlist calendar and fire WF-N7.
  6. If no_show_count_90d is 2 or more, add no-show-repeat and set reliability_flag = Deposit Required; if exactly 1, set reliability_flag = Watch.
  7. Post to the internal channel: "No-show: {{contact.first_name}}, {{appointment_type}} with {{provider_name}} at {{location_name}}, {{appointment_start_at}}. Slot released. Owner: {{recovery_owner}}."
  8. Continue to WF-N2.

Exit and safeguards: if an arrival is recorded after marking (a genuinely late customer) a reverse workflow fires: undo the no-show, decrement the counters, remove the tags, cancel every pending step in WF-N2 and WF-N4, and restore reliability_flag. Build this. Without it, your late arrivals get apology texts for missing an appointment they are sitting in.

WF-N2 · Immediate Recovery Reach-Out

Trigger: record enters Marked No-Show.

Conditions: no do-not-contact, sms-stop or do-not-rebook tag; a consented channel exists; recovery_attempt_count is less than 5.

Actions, in order:

  1. Wait 1 minute. Just enough to let a manual correction land before the message goes out.
  2. Branch on channel. SMS consent → SMS. No SMS consent but valid email → email. Neither → create a call task for recovery_owner due in 30 minutes and exit.
  3. Branch on quiet hours. If now is outside 08:00–20:00 local, hold until 08:00. A no-show at 7:50pm gets its first message the next morning, not at ten past eight at night.
  4. Send SMS: "Hi {{first_name}}, we had you down for {{appointment_time}} today with {{provider_name}} and missed you. Everything okay? No problem at all if something came up. One tap tells us what happened and gets you a new time: {{reason_link}}"
  5. Email variant: subject "We missed you today". Same blameless framing, two paragraphs, the six reason buttons inline, then one link to availability.
  6. Increment recovery_attempt_count; stamp last_recovery_contact_at; move to Recovery In Progress.
  7. Wait 2 hours. Condition: no reply, no reason captured, no rebooking. Send second SMS, this time with real times in the body: "No rush {{first_name}}, I've got {{slot_1}} or {{slot_2}} free this week if either suits. Just reply with the day and I'll hold it."
  8. Increment recovery_attempt_count. Hand the thread to BO for reply handling.

Copy rules that matter more than the sequence: never lead with the fee, never use the word "failed", never say "you did not attend", and never ask for an explanation as a condition of rebooking. The first message exists to reopen a conversation, not to settle an account. The fee conversation, where one exists, belongs in WF-N6 and belongs to a human.

Exit conditions: reason captured; rebooking created; inbound reply received; any opt-out tag; reliability_flag set to Do Not Rebook; recovery_attempt_count reaches 5.

WF-N3 · Reason Capture and Branch

Why it matters: the reason is the whole asset. Recovery rates vary enormously by reason, and so do the fixes: "forgot" is a reminder problem, "transport" is an information problem, "cost concern" is a sales problem, and "booked elsewhere" is a speed problem. Without this field you will spend a year sending the same message to four different problems.

Trigger: reason picker tapped, or BO classifies an inbound reply into a reason.

Actions:

  1. Write no_show_reason, no_show_reason_free_text where given, and no_show_reason_captured_at. Capture on tap, not on submit.
  2. Cancel all pending steps in WF-N2 and WF-N4. This is the most-missed step in builds like this and the cause of most "why are you still texting me" complaints.
  3. Add tag no-show-reason-captured; move to Reason Captured.
  4. Branch on reason:
    • Forgot or Wrong time in calendar → straight to the rebook page; set reliability_flag = Watch; flag the contact for the hardened confirmation treatment in WF-N5.
    • Transport → rebook page plus an automatic follow-up containing the address, parking, public transport notes and a map link.
    • Work or childcare → rebook page filtered to first-of-day, last-of-day and weekend availability only. Offering the same mid-morning slot again is why this reason repeats.
    • Illness → suppress all recovery messaging for 72 hours, send one short "get well, no rush" message, then offer times. Never charge a fee on this branch automatically; route it to a human.
    • Cost concern → no rebook page. Create a task for recovery_owner due in 4 hours for a human conversation, and send "Totally understand. Let me get {{owner_first_name}} to give you a call so we can talk through the options properly."
    • Booked elsewhere → one honest message: "Completely fine, {{first_name}}, thanks for telling us. If it doesn't work out we'll be here." Set reliability_flag unchanged, add to the 90-day win-back audience, exit the build.
    • Changed mind → one value-led message with a single soft offer of a short no-obligation call, then exit to nurture.
    • No reason given → continue to WF-N4.

Exit: every branch terminates in one of rebooked, human-owned, or nurture. No branch loops back into the ladder.

WF-N4 · The Recovery Ladder

Trigger: record is in Recovery In Progress with no reply after WF-N2's second message.

Global conditions checked before every step: no rebooking exists, no reason captured, no opt-out tag, recovery_attempt_count under 5, quiet hours respected, and last_recovery_contact_at more than 12 hours ago.

Actions, in order:

  1. Wait until 10:00am the next day. Send SMS, attempt 3: "Morning {{first_name}}, still happy to get you booked in for your {{appointment_type}}. Want me to find you a time this week? Reply YES and I'll send two options."
  2. Wait 1 day. Branch on appointment_type and preferred_channel. For high-value types, or where preferred_channel = Call: place a voice AI call between 11:00 and 16:00 local. Script: identify the business, say the appointment was missed and that there is no issue, offer two specific times, offer transfer to a person, end inside 45 seconds. Everything else: send email, attempt 4, subject "Still want to get this sorted?", with a three-line body and one availability button.
  3. On an unanswered call: leave a voicemail, then send the SMS version of the same offer. Never leave a second voicemail.
  4. Wait 3 days. Attempt 5, the last one, and say so plainly: "Last one from me, {{first_name}}, I don't want to keep bothering you. If you'd still like to come in, book any time here: {{booking_link}}. Otherwise no problem at all and we'll leave it with you."
  5. Wait 2 days. No response → add no-show-unreachable, move to Unreachable, remove no-show-recovery-open, add to the quarterly win-back audience, close the owner's task with an outcome note.

Stop conditions: any inbound reply of any kind; any rebooking; reason captured; STOP or unsubscribe; recovery_attempt_count reaches 5. The cap is enforced by the field, not by counting steps. Otherwise a re-entry from a second no-show restarts the count and someone gets ten messages.

WF-N5 · Rebooking and Confirmation Hardening

Why: a rebooked no-show is statistically the most fragile appointment on your calendar. Treating it exactly like a first-time booking is how you get the same empty slot twice.

Trigger: new appointment created for a contact carrying the no-show tag.

Actions:

  1. Write rebooked_appointment_at; calculate rebook_lead_time_hours; add no-show-rebooked; move to Rebooked; close the recovery task.
  2. Condition: if rebook_lead_time_hours is greater than 168 (more than a week out) add the contact to the extended confirmation track. Long lead times are where recovered bookings die.
  3. Immediate confirmation SMS: "You're booked, {{first_name}}, {{appointment_type}} with {{provider_name}}, {{appointment_time}}, {{location_name}}. Here's the address and parking: {{location_link}}. Reply C to add it to your calendar."
  4. Send calendar invite by email with the location, duration and what to bring.
  5. Wait until 48 hours before. Send reminder with a single question: "Still good for {{appointment_time}} on {{day}}? Reply Y to confirm or R to move it."
  6. Wait until 24 hours before. Condition: no Y received. Send second reminder and create a task for the front desk to call during the working day. A human call to an unconfirmed recovered booking is the highest-yield phone call in this entire build.
  7. Wait until 2 hours before. Condition: still no confirmation. Send final reminder: "We're all set for you at {{appointment_time}}, see you shortly. If something's changed, reply R and we'll move it, no problem." Simultaneously add the slot to the waitlist calendar as at risk, so a standby can be warmed up without being promised anything.
  8. On arrival: stamp arrival_recorded_at, move to Rebooked and Attended, add no-show-recovered, and schedule reliability_flag to reset to Reliable after 90 days with no further no-show.
  9. On a second no-show: WF-N1 fires again, no_show_count_90d reaches 2, and the record is routed to WF-N6 instead of back into the ladder.

Exit: attended, canceled with notice, or no-show again.

WF-N6 · Repeat No-Show Policy and Deposit Gate

Trigger: no_show_count_90d reaches 2, or reliability_flag set to Deposit Required.

Conditions and branches:

  • Second no-show with a reason captured both times → one more chance, but only into a first-of-day or last-of-day slot, with the hardened confirmation track and a card on file.
  • Second no-show, no contact either time → deposit gate applies before any booking can be made.
  • Third no-show in 90 days → set reliability_flag = Do Not Rebook, move to that stage, notify the owner, and stop all automated outreach. A human decides whether to re-admit them, and that decision is logged in a note.

Actions on the deposit branch:

  1. Set deposit_required = true; add tag deposit-required; move to Deposit Required.
  2. Disable the open booking link for this contact so the gate cannot be walked around.
  3. Send the policy message: written once, in plain words, approved by the owner, and never improvised: "Hi {{first_name}}, we'd still love to see you. Because we've held two slots that went unused, we now take a small deposit to confirm the booking. It comes straight off your bill on the day, and it's fully refundable if you give us 24 hours' notice. Here's the link to book and confirm: {{deposit_booking_link}}"
  4. Stamp deposit_link_sent_at. Wait 3 days. No action → one reminder. Wait 7 days. Still nothing → move to Unreachable and stop.
  5. On payment: stamp deposit_paid_at, add deposit-paid, unlock availability, and run WF-N5 with the full hardened track.
  6. On attendance: apply the deposit to the bill, reset reliability_flag to Watch, and remove the gate.

Non-negotiables: the amount, the refund window and the application of the deposit are commercial decisions for the business and must be settled, written down and reviewed by the client's own adviser before launch, including whether a deposit or fee is permissible at all in the relevant sector and jurisdiction. Never let an automation levy a charge against a stored card without an explicit, separately captured authorization for exactly that. Never apply this branch automatically to the Illness branch of WF-N3.

WF-N7 · Same-Day Slot Refill from Waitlist

Why: the recovery sequence protects the customer relationship. This workflow protects today's revenue, and it is the one that pays for the build.

Trigger: slot released by WF-N1, or a cancellation inside the notice window.

Conditions: remaining slot duration is at least the minimum bookable length; the slot starts more than 45 minutes from now; the provider has not already been reassigned.

Actions, in order:

  1. Build the audience: contacts with waitlist_opt_in = true, matching appointment_type, matching provider_name where the waitlist entry specified one, whose waitlist_notice_window permits today, and who hold no do-not-rebook or opt-out tag. Order by how long they have waited.
  2. Send to the first 5 only: "{{first_name}}, a slot just opened with {{provider_name}} today at {{slot_time}}. First to reply YES gets it." Sending to the whole list produces five disappointed people and one booking.
  3. Wait 8 minutes. No YES → send to the next 5. Repeat up to three rounds, then stop.
  4. First YES wins: book immediately, confirm in the same thread, set slot_refilled = true, calculate slot_refilled_minutes from no_show_marked_at.
  5. Every later YES gets an immediate, specific apology and a concrete alternative: "That one's gone, sorry: genuinely quick. I can do {{alt_slot_1}} or {{alt_slot_2}}, or I'll keep you first in line for the next opening." Never leave a late YES unanswered; that is how you lose a waitlist.
  6. Post the outcome to the internal channel so the front desk stops working the phone for that slot.

Exit: slot filled; slot start time within 45 minutes; three rounds exhausted.

WF-N8 · Late Cancellation Handling

Why it is separate: a customer who cancels four hours out behaved well. A customer who said nothing did not. Collapsing the two into one tag destroys both your reporting and your tone.

Trigger: appointment canceled, with appointment_start_at less than the notice window away: 24 hours is the usual setting.

Actions:

  1. Stamp late_cancel_at; add tag late-cancel. Do not increment no_show_count_90d.
  2. Release the slot and fire WF-N7 immediately.
  3. Send: "Thanks for letting us know, {{first_name}}, no problem at all. Want me to get you back in? {{booking_link}}"
  4. Wait 1 day. No rebooking → one reminder with two concrete times. Wait 4 days. Still nothing → add to the win-back audience and exit.
  5. Track late cancellations as their own series. A rising late-cancel rate alongside a falling no-show rate is the build working exactly as intended, and it will look like a problem on any dashboard that counts them together.

Exit: rebooked, or two attempts made.

WF-N9 · Daily At-Risk Review and Weekly Reporting

Trigger: scheduled, 08:15 each working day, and 08:00 each Monday.

Daily actions:

  1. Build the at-risk list for today: appointments with no confirmation reply, plus every contact whose reliability_flag is Watch or Deposit Required.
  2. Post it to the internal channel and create one call task per record for the front desk, due before the appointment.
  3. List yesterday's no-shows still in Recovery In Progress with no reply, assigned by owner, so nothing silently ages.

Weekly actions:

  1. Email the owner a single digest: no-show rate by appointment_type, by provider_name, by location_name and by day of week and time of day; reason distribution; recovery rate; median slot_refilled_minutes; slots never refilled.
  2. Flag any provider, slot time or appointment type whose no-show rate is more than 1.5 times the account average, because that is an operational problem a recovery sequence cannot fix.

Exit: runs indefinitely.

05

What changes

What is different afterwards

  • No-shows become countable. Before the build they are an anecdote; after it they are a number with a reason attached, broken down by provider, service, location, day and hour. Most businesses discover their no-shows are concentrated in two or three identifiable pockets rather than spread evenly, and that finding alone usually changes a scheduling rule.
  • The fifteen minutes after a miss has an owner. The first message goes out while the slot is still warm, every time, whether the front desk is free or not, and the person who missed hears something blameless rather than nothing at all.
  • The empty slot gets resold. A waitlist that is actually triggered by the vacancy, within minutes, converts a dead hour into a booked one often enough to change the economics of the whole build.
  • Recovered bookings are treated as fragile. The hardened confirmation track exists because a rebooked no-show is the appointment most likely to vanish again, and treating it differently is what stops the second miss.
  • Repeat offenders are handled by policy rather than by mood. Who gets another chance, who gets a deposit gate and who gets neither is decided by two counter fields and written rules, applied identically to everyone, which is both fairer and much easier to defend.
  • Nobody gets chased forever. Five attempts across seven days, then the record is parked in a quarterly win-back audience and left alone. The cap is enforced by a field, so a second no-show cannot quietly restart it.
  • The reason data starts fixing upstream problems. "Forgot" sends you to the reminder ladder. "Transport" sends you to the confirmation content. "Work or childcare" sends you to your opening hours. "Booked elsewhere" sends you to your speed-to-lead. The recovery sequence stops being the whole answer and becomes the safety net underneath better scheduling.

Metrics to watch

  • No-show rate: missed appointments as a share of scheduled, measured weekly and segmented by appointment type, provider, location, day of week and hour of day. The segmented view is the useful one; the headline number hides everything.
  • Detection coverage: the share of missed appointments that were marked automatically rather than by hand. Until this is near total, every other metric here is understated.
  • Reason capture rate: of no-shows contacted, the share that produce a no_show_reason. This is driven almost entirely by how fast and how blameless the first message is.
  • Recovery rate: of no-shows, the share that rebook. Then the honest version: the share that rebook and attend. Report both; the gap between them is where the hardened confirmation track earns its place.
  • Median time from no_show_marked_at to first contact. Target is under five minutes. If this drifts above an hour, the build is no longer doing the one thing it exists to do.
  • Median time to rebooking, and rebook_lead_time_hours distribution. Shorter lead times attend better; if your recovery bookings are all landing three weeks out, the recovery slots calendar is too small.
  • Slot refill rate and median slot_refilled_minutes: the waitlist's performance, and the clearest financial readout in the build.
  • Second no-show rate among recovered bookings: the measure of whether hardening works.
  • Reason distribution over time. Watch the mix, not just the volume. A falling "forgot" share means your reminders improved; a rising "booked elsewhere" share means your competitors got faster.
  • Late-cancel rate alongside no-show rate. These should move in opposite directions as the build matures. Counting them together will make success look like failure.
  • Deposit gate outcomes: how many were gated, how many paid, how many attended, how many were lost. If almost nobody converts through the gate, the policy is functioning as an exit rather than a filter, and that should be a deliberate choice.
  • Opt-out rate on recovery messages. The early warning that tone or frequency has drifted. Review the copy before touching the cadence.
06

Before you start

Prerequisites

  • Appointment outcomes must be recorded. This is the whole build. Someone, or something, has to mark attended, canceled or no-show the same day, ideally an arrival stamp at reception or on the technician's phone. If outcomes are recorded inconsistently, fix that before automating anything on top of it.
  • Agreed grace periods per appointment type, in minutes, written down. Without them, detection is a judgment call and detection stops happening.
  • A named recovery owner per location and shift, with cover. Several branches queue a human task; if nobody works those tasks, the branches become a worse experience than silence.
  • A written policy on fees, deposits and repeat no-shows, approved by the owner before launch. Automations will send this policy verbatim to real customers, so it has to be a position the business will defend on the phone.
  • Reminders already working. A recovery pipeline bolted onto a business with no reminder sequence is treating a symptom. Build or verify the reminder ladder first; recovery should be catching the residue, not the bulk.
  • Deduplicated contacts. Two records for one person produces two recovery sequences and a very bad impression.
  • A real waitlist, with waitlist_opt_in and waitlist_notice_window captured at booking. WF-N7 cannot sell an empty list, and retro-fitting one later is far harder than asking one extra question at booking.

Integrations and provisioning

  • Two-way calendar sync (Google Calendar, Microsoft 365 or Outlook) so the slot released by WF-N1 is genuinely free and the refill cannot double-book a provider.
  • Practice management, EHR or field-service system. Where appointment status lives in another system, decide which one is authoritative and sync in that direction only. Two systems both writing appointment status will produce phantom no-shows, and the apology texts that follow are the kind of error customers remember.
  • Payments: Stripe, Square, PayPal or Authorize.net: only if the deposit gate is in scope. Confirm card-on-file and refund handling before building WF-N6.
  • Accounting sync (QuickBooks or Xero) if deposits are taken, so held funds are visible in the books rather than only in the platform.
  • Slack or Microsoft Teams for the internal no-show and refill notifications. Email for these dies within two weeks.
  • Number provisioning on the existing business number, with call forwarding and recording configured. Recovery messaging from a second, unfamiliar number performs badly and gets reported as spam.
  • Authenticated email sending domain (SPF, DKIM and DMARC) before the first email send, since recovery email goes to people who are, by definition, currently disengaged.
  • Branded short-link domain for reason and booking links. Generic shorteners get filtered by carriers.

SMS registration, consent and timing

  • Complete A2P 10DLC brand and campaign registration before sending. Register this traffic as customer care or appointment notification, and submit sample messages that match what WF-N2, WF-N4 and WF-N7 actually send: same shape, same length, same opt-out language.
  • Consent must predate the first recovery message. A booking is not blanket consent to be texted. Capture SMS consent at booking or intake with an unticked box naming the business, the message types, that frequency varies, that message and data rates may apply, and how to stop, and store the timestamp, the source and the exact wording shown.
  • Quiet hours: hold all outbound to 08:00–20:00 in the contact's local time, narrower than the legal floor on purpose. A missed-appointment message at 9pm reads as a debt collection notice.
  • Honor STOP mechanically on every channel, and make an opt-out close the recovery pipeline record as well as stopping the messages. Keep email and SMS suppression visible to each other.
  • Enforce the attempt cap in a field, not in the step count, so re-entry cannot restart it. Five contacts across seven days is the ceiling, and the fifth message should say it is the last one.
  • Waitlist blasts need their own consent basis and their own frequency cap. A standby offer is marketing in most readings, not a transactional notice, and it should be opt-in and easy to leave.

Tone and conduct rules to set before launch

  • Never automate a consequence. Fees, gates and refusals are human decisions, communicated by a human or by pre-approved copy a human signed off. An automation that charges or refuses on its own will eventually do it to the wrong person on the worst possible day.
  • Never imply blame or debt in automated copy. No "failed to attend", no "you owe", no "this is your second offense".
  • Always build the reversal path. Late arrivals, mis-marked appointments and calendar sync errors are inevitable; the undo workflow in WF-N1 is not optional.
  • Cap total outbound per contact across all builds. If recovery, reminders, review requests and nurture are all live, define a global message ceiling per contact per week so they do not stack.

Where regulated or sensitive data is involved

  • In healthcare or any setting handling protected health information, get a signed business associate agreement covering the platform in place before real patient data enters it, and restrict access to no_show_reason and no_show_reason_free_text by role.
  • Keep the message clinically silent. Reference the time and the location, never the service, the department, the condition or the reason for the visit. "We missed you this morning" is appropriate; naming the procedure is a disclosure to anyone who sees the screen.
  • Treat the Illness branch carefully. A free-text reason may contain health information the business did not ask for. Decide in advance where it is stored, who can read it, how long it is kept, and whether it should be captured at all.
  • Where appointment attendance carries contractual, insurance or benefit consequences, the no-show record may be relied on by third parties. Log how the status was set and keep the reversal history.
  • Define a retention period for recovery data you can defend, and apply it.
  • None of this is legal advice. Have the client's own counsel review the consent language, the fee and deposit policy, the retention schedule, and any sector-specific rules on charging for missed appointments before launch. If the policy cannot be reviewed in time, launch WF-N1 through WF-N5 and WF-N7 and leave the deposit gate switched off. The build works without it.

Scope, pricing and provisioning for a build like this are quoted per account. Book a call at bookings.appbo.io to walk through your appointment data and decide what to switch on first.

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