Most salons, dental offices, and appointment shops send a reminder text and stop there. It reduces no-shows a little. But a one-way reminder — "Reminder: your appt is Tuesday at 2pm" — creates a second problem it never solves: the client who can't make it has no way to tell you except calling during business hours, which they won't. So they ghost. Or worse, they call the day-of, you scramble, and the slot sits empty.

A two-way confirm text fixes both ends. The client replies C to confirm, X to cancel, or R to reschedule — and the reschedule reply hands them your open slots automatically. No front-desk phone tag. No double-booking because two staff members "penciled someone in" for the same 3pm.

Full disclosure: I work for ReadySMS, so I've got a horse in this race. But the flow below works on any platform that supports keyword routing and calendar triggers. I'll just show you exactly how we wire it up with GoHighLevel, because that's where most local shops already keep their calendar.

Why one-way reminders leave money on the table

Run the math on a mid-size salon. Say you book 400 appointments a month at an average ticket of $75. A typical no-show rate for appointment businesses without confirmation hovers somewhere around 10–15% (industry approximations — yours will vary). Call it 12%, so 48 no-shows a month.

If a working confirm-and-reschedule flow recovers even a third of those — because the client who would have ghosted now taps R and rebooks two days out — that's 16 appointments × $75 = $1,200/month you weren't collecting. The SMS cost to do it is rounding error, and I'll show that below.

The double-booking angle is subtler but real. When cancellations only arrive by phone, the freed slot doesn't get released back into the calendar until someone manually clears it. Two staff sell it to two clients. A reply-driven cancel that writes straight back to the GHL calendar removes the slot the instant the text lands.

The full flow, step by step

Here's the sequence, mapped to GHL calendar triggers on one side and ReadySMS keyword routing on the other.

  1. Booking created → GHL fires an "appointment booked" trigger → ReadySMS sends the confirmation-request text (immediately or on a delay).
  2. 24 hours before → reminder text with the same reply options, in case they never answered the first.
  3. Reply C → GHL appointment status flips to Confirmed, contact tagged, no further reminders sent.
  4. Reply X → status flips to Cancelled, slot released to the calendar, optional "want to rebook?" follow-up.
  5. Reply R → ReadySMS returns the next available slots pulled from the calendar; client picks one; GHL reschedules.
  6. Reply STOP → handled automatically and separately (more on that below — it must not be treated as a cancel).

The whole thing runs without a human touching it until someone genuinely needs help.

Writing the confirm text so it fits one segment

Keep the first message tight. An SMS segment is 160 GSM-7 characters; go over and it splits into 153-char multipart pieces, and each piece bills. Drop in a single emoji and your limit collapses to 70 characters per segment. So skip the emoji here.

A clean one-segment confirm:

Hi Dana, it's Vera Salon. You're booked Tue 6/10 at 2:00pm w/ Alex. Reply C to confirm, X to cancel, R to reschedule.

That's 116 characters — one segment. At the standard rate that's $0.02 + $0.0045 carrier = $0.0245 to send. Even at 400 bookings a month, each getting a confirm plus a 24-hour reminder (800 outbound segments), you're at $19.60/month in send cost. Against $1,200 in recovered revenue, the ratio speaks for itself. If you want to run your own numbers, the cost calculator does the segment math for you.

The reschedule reply will be longer — you're listing slots — and may run to 2 segments. Budget for it, but it only fires for the fraction of clients who actually tap R.

Keyword routing: C, X, R — and the ones you must handle differently

The magic is in routing inbound single letters to different actions. C, X, and R each map to a distinct GHL workflow branch. This is straightforward to set up, but there are two traps.

Trap one: STOP is not a cancel. If someone texts STOP, that's a compliance opt-out, not "cancel my haircut." ReadySMS handles STOP / UNSUBSCRIBE automatically — the opt-out is honored and propagates so the contact can't be messaged again across any campaign. You do not want STOP flowing into your "cancel appointment" branch and getting a chatty "sorry to see you go, want to rebook?" reply. That reply to someone who just opted out is exactly the kind of thing that generates a complaint.

Trap two: HELP needs a human. Route HELP (and free-text that doesn't match a keyword) to a real person or an "we'll call you" path, not into the automated tree.

If you want the deep version of this — how to branch STOP, HELP, and YES-style keywords cleanly without a human in the loop — we wrote a whole piece on building a keyword routing tree. Worth reading before you go live.

Quiet hours: don't text a cancel confirmation at 11pm

Someone books online at 10:45pm. Your "appointment booked" trigger fires and, without protection, would fire a text at 10:45pm. That's a TCPA quiet-hours problem and a good way to annoy the person you just won.

ReadySMS enforces quiet hours automatically based on the recipient's area — sends outside permitted local hours are held and released when the window opens. So that late-night booking confirmation queues and goes out at, say, 9am the next morning. You don't have to build the delay logic yourself or babysit timezones.

This matters more than people think for appointment reminders specifically, because reminders and confirmations get sent at odd hours precisely when bookings and cancellations happen at odd hours.

Register the campaign correctly or delivery quietly dies

Here's the part local shops skip and then blame the platform when texts stop landing. Appointment confirmations are transactional / customer-care messages, not marketing. If you register your 10DLC campaign under a marketing use case and then send transactional confirmations through it — or vice versa — carriers can silently filter your traffic. No error, no bounce, the text just doesn't arrive.

We broke down exactly why this happens in why a use-case mismatch silently drops delivery. The short version: match the campaign use case to what you actually send. For a salon running confirmations, that's a customer-care / low-volume mixed campaign.

Standard 10DLC registration in ReadySMS runs roughly ~$10/mo per brand and ~$20/mo per campaign, approval typically 1–3 days, handled in-app. Most single-location appointment businesses never need brand vetting on top of that — throughput on a standard registration is plenty for a few hundred confirmations a day. If you're a multi-location group pushing serious volume, here's when vetting is worth $40.

What it costs, all in

Line itemCost
10DLC brand registration~$10/mo
10DLC campaign registration~$20/mo
800 outbound segments (Starter, confirm + 24hr reminder × 400 bookings)~$16/mo
Reschedule replies (assume ~60 clients tap R, ~2 segments each)~$2.40/mo
Total~$48/mo

Against ~$1,200/month in recovered no-show revenue at a mid-size salon, the flow pays for itself many times over. And you get the 2,500 free credits to start — enough to run the whole thing for a couple weeks before you spend a dollar on send.

The practical takeaway

A one-way reminder tells people about their appointment. A two-way confirm-and-reschedule flow lets them act on it — confirm, cancel, or rebook — without a phone call, and writes every one of those actions straight back to your calendar so the slot is never double-sold.

The three things that make it work and that people get wrong: route C/X/R to distinct actions while keeping STOP and HELP out of that tree, let quiet-hours enforcement handle the odd-hour bookings so you're not texting at midnight, and register the campaign under the transactional use case so your confirmations actually arrive.

If you're already running your calendar in GHL, the GHL setup guide walks through connecting the two-way sync so inbound replies land in both places. Start with the free credits, wire up the confirm text first, and add the reschedule branch once you see the replies coming in.