One vendor default put a wall on 13 booking paths

What we walked
Between 26 and 27 August 2026, an automated walker took the booking path on 221 med spa domains across North and South Carolina. It ran for about forty-one hours, unattended, and it walked each domain once. Every finding in this article is deterministic: the pipeline’s language-model stage never ran on any of the 32 runs, at a total spend of $0.00, so nothing here was written or judged by a model. A detector either saw a thing on screen or it did not.
The sample is not a survey. These domains came off an outbound prospecting queue — med-spa-type businesses found through metro text searches, then filtered by a predicate that exists to find people worth writing to. That predicate excludes practices we had already written a friction brief about, which means some of the sites most likely to have something wrong with them were never in the set. Whatever this measures, it biases the finding rate down.
It is also concentrated. 188 of the 221 are in the Charlotte area, with 13 in Greenville, 12 in Charleston, 4 in Sumter and 3 in Columbia. One of the 221 is our own test domain rather than a practice.
What the walk does, what it refuses to touch, and what counts as a finding are all described on the methodology page. This article is about what it found.
A quarter of the paths we could walk had a finding
36 of 140, or 25.7%.
The denominator is the part worth arguing about, so here it is in full. 140 is the walked population: the domains where the walker reached a booking surface and something happened there. It is the first three lanes below added together. It excludes the 19 domains where a vendor’s robots file forbade entry and the 62 where the walk never reached a booking surface at all, because in those 81 cases nothing was walked and counting them either way would be inventing a result.
| Lane | Domains | What it means |
|---|---|---|
| Findings | 40 | At least one screenshot-backed defect or wall on the booking path |
| Clean | 27 | Reached selectable appointment times, or a fillable form with no wall |
| Incomplete | 73 | Stalled at the booking vendor’s first screen |
| Robots-blocked | 19 | A booking vendor’s robots file forbids entry |
| Unreachable | 62 | Never reached a booking surface |
| Total | 221 |
Those are the lanes as the walker flagged them, before review. The review described below moved four domains out of Findings, to 36. It did not move the population, and it did not move the 140 — the four rejected domains had all been walked to a booking surface, so they stay in the denominator and simply re-lane. Only the numerator changes.
There is a narrower framing available and it is worth stating once so nobody has to reconstruct it. Of the sites walked all the way to a verdict — findings plus clean, and nothing else — the rate is 36 of 67, or 53.7%. That number is not the headline and should not be quoted as one. Its denominator of 67 is 30% of the audited population, because it discards the 73 incomplete walks, which are exactly the cases where nothing was proven in either direction. Throwing away every inconclusive result roughly doubles the rate. That is what discarding inconclusive results does, and it is the reason we lead with 25.7%.
The largest single class was a wall
Thirteen of the reviewed findings are the same thing: a phone-verification wall.
The walker reached a practice’s online booking, and before any appointment time was displayed, the flow asked for a name, an email address and a phone number, then sent a code to that phone and waited for it. No times before the form. A visitor has to hand over a working mobile number and read an SMS to find out whether there is a Thursday slot.
That is the finding, stated as what was on screen. It is not a claim that anybody abandoned the form.

All 13 came from one vendor default
Here is the part that changes how the number should be read.
All thirteen confirmed walls, across twelve practices, are AestheticRecord’s default hosted online-booking flow. Not thirteen practices arriving separately at the same policy. One vendor’s default configuration, shipped thirteen times, on sites whose owners in all likelihood never chose it and may not know it is there. The screenshots show the vendor’s own chrome: the same modal, the same copy, the same order of operations.
It is worth being fair about the other side of this. SMS verification before booking is a defensible feature. It cuts fake bookings and no-shows, and a vendor that ships it as a default is not doing anything underhanded. What the data records is that the wall stands before any appointment times are shown. It does not measure what that costs anyone, and we are not going to pretend otherwise.
Vendor detection uses 37 URL fingerprints recorded per frame and per signal. 135 of the 221 domains showed at least one identified vendor. Counts are distinct domains; a domain running two vendors is counted under each.
| Vendor | Domains | Vendor | Domains |
|---|---|---|---|
| Vagaro | 26 | Zenoti | 4 |
| AestheticRecord | 16 | AestheticsPro | 4 |
| Square | 16 | PatientNow | 3 |
| Boulevard | 12 | MassageBook | 2 |
| GlossGenius | 9 | GoHighLevel | 2 |
| Acuity | 9 | Setmore | 2 |
| Jane | 9 | Portrait | 2 |
| Mangomint | 9 | Booker | 2 |
| Moxie | 8 | 5 other vendors | 1 each |
| Mindbody | 7 | ||
| Fresha | 4 | ||
| Meevo | 4 |
Vendors appearing on a single domain are collapsed into that last row deliberately. In a sample that is 85% one metro, a one-domain vendor cell names a practice by elimination.
Two things this table undercounts. White-label booking subdomains carry no vendor fingerprint at all, and 18 such signals were logged; another 181 signals pointed at booking hosts we do not yet recognise. “No vendor identified” does not mean “no vendor.”
Four findings we threw out
The walker originally flagged 17 phone-verification findings. On 7 September the operator opened all 17 against their screenshots and their walked URLs, and rejected four.
Those four had fired on Square gift-card checkout pages. The deep walker had followed a gift-card affordance as though it were a booking path, and the gate heuristic then matched the phone field on the gift-delivery form. The screenshots make it unambiguous: they are gift-card purchase pages, not booking flows. Each of those four domains carried no other finding, so the findings lane moved from 40 to 36, and phone-verification from 17 to 13.
The rejected findings were not deleted. They sit in the run files with a verdict of
rejected, because over-reporting is the expected failure mode of an automated walker,
and a pipeline that quietly drops its own mistakes cannot be audited for them. The fix is
a single rule, stop treating gift-card and store-checkout URLs as booking affordances, and
it is currently parked rather than shipped.
This is also why the headline is 25.7% and not the 28.6% the unreviewed count would have produced.
The other 25 findings
38 findings across 36 domains. Two domains carry two each; the rest carry one.
| Class | Count | What the walker recorded |
|---|---|---|
| phone_verification | 13 | A name/email/phone form with SMS verification stands before any appointment times |
| phone_only | 11 | No online booking mechanism found on the pages walked |
| broken_booking_link | 4 | The booking link resolves to an error page (404, 429, or a dead URL) |
| mobile_breakage | 3 | Page renders wider than a 390px viewport |
| login_wall | 2 | The booking path resolves to a login form with no visible new-patient route |
| widget_failure | 2 | The embedded booking widget rendered nothing after a 22-second settle |
| account_wall | 1 | An account sign-in or creation form stands before any appointment times |
| form_error | 1 | The booking or contact form threw a page error while it was being filled |
| ssl_or_redirect | 1 | The booking URL did not load (redirect loop) |
| Total | 38 |
Every row says what was on screen when the screenshot was taken. None of them says what a visitor did, would have done, or lost.


What we could not see
The honest half of this audit is larger than the findings half, and burying it would make the 25.7% less trustworthy rather than more.
73 domains were incomplete — a third of the entire sample. The walker’s click grammar stalled at a booking vendor’s first screen, with neither appointment times nor a wall visible. Nothing was proven about those sites in either direction. This lane measures our walker, not their booking paths, and the vendors that appear most often in it are simply the ones whose first screens we cannot yet drive.
19 domains were robots-blocked. Every route to booking led to a known booking vendor whose robots file forbids entry, so the flow could not be photographed. We honour robots files rather than routing around them. Worth noting whose choice that is: the practice did not make it, their vendor did.
62 domains were unreachable, and this lane needs its composition stated, because the name oversells it. 47 of the 62 are an absence claim by a detector: nothing on the homepage offered a way to book, and no tap-to-call link was found. Unusual affordances and white-label subdomains get missed, and five further domains are explicitly marked as blocked from making an absence claim at all, because a widget frame never expanded or a page never rendered. The remainder is smaller and more literal: four robots files disallowing every booking path, three SSL failures, two booking pages that rendered empty after the long settle, and one stopped by the audit’s own read-only guard.
What this does not measure
A headless browser is not a patient. One visit per site, inside one 41-hour window, on an unattended machine. There is no retry across days. Two of the four broken-link findings were HTTP 429s, and a 429 for our bot is not proof of a 429 for a human — we may have tripped our own rate limit.
Thresholds are measurements, not verdicts. widget_failure means the widget rendered
nothing after a 22-second settle on audit day. It does not mean permanently broken.
mobile_breakage is one specific measurement: the page renders wider than a 390px
viewport.
phone_only counts a business model as a finding. Eleven of the 36 are “no online
booking found”, which a practice can fairly call a deliberate choice rather than a defect.
This audit asks whether somebody can book online, so it counts — but the number without it
is 25 of 140, or 17.9%, and anybody who prefers that framing is entitled to it.
Detection is deliberately narrow. A phone-verification finding requires a visible telephone input plus verification language on screen; a payment-upfront finding requires actual card-entry UI, never deposit language. These rules undercount rather than overcount. The four gift-card rejections are not a counter-example — those came from walking the wrong affordance, not from a loose rule.
Every figure here is pinned to two dates: measured 27 August 2026, reviewed 7 September 2026. Sites get fixed. Some of these will have been.
How to check your own
You do not need a walker for this, and it takes about ten minutes.
- Open your own site on your phone, not your laptop, and book yourself an appointment. Go all the way to the last screen before it would be confirmed.
- Count the screens before you see a real appointment time. That number is what this whole article is about. If a form, a login, or a verification code comes first, you have found the same thing we found 16 times.
- Check what your booking button actually points at. Broken and misrouted booking links were four of these findings, and they fail silently. Nobody emails to tell you.
- If you use a hosted booking vendor, go and look at its default settings. Thirteen of the findings in this audit are a default nobody chose.
If you would rather we walked it, we will do that for free, and you keep the written report either way.