Should I vibe code
Client booking, intake forms, payments, reminders, and classes
A booking form that asks “any conditions we should know about?” is a medical record with a submit button.
?
Their verdict, the Starter price and the build-time estimate come from their entry, MIT-licensed. Checked 2026-08-04.
?
Our verdict, the regret score and everything below it. Editorial and unsponsored — nobody can pay to be moved.
The honest answer
why the verdict is what it is
Calendly finds a time; Acuity runs a practice, and that is the whole difference. Before the appointment it asks the client questions, and on a massage therapist's, counsellor's or physio's booking page those questions are "any injuries, conditions or medication we should know about?". In the same submit it takes a card for the deposit and puts a no-show fee on file. So the honest description of what you would be building is a public, unauthenticated endpoint that collects health information from strangers, charges them, and then has to keep both halves straight through cancellations, refunds and a DST transition. Each piece is a decent weekend on its own. Bolted together they are the reason Acuity sells a HIPAA tier at all — the $20 is not buying slot arithmetic, it is buying somebody who has signed something about that combination. Build the booking page for your own calendar and keep the form to a name and an email. The moment a licence is on the wall or a card is on file, you are no longer writing a scheduler.
What actually breaks
not "if". the specific failures.
- The intake form, the first time a client writes a diagnosis into the free-text box you labelled "anything else we should know?"
- Payment state, which is three systems quietly disagreeing: your bookings table, Stripe's charge, and what the client remembers being told the deposit was
- Cancellation and no-show fees, because the policy lives in prose on the booking page and in an if-statement in your code, and the two drift apart within a month
- Double booking, when two people open the same slot in the same second and nothing in the schema stops both inserts
- Recurring availability across a DST change — the bug is never the offset, it is the rule that shifts by an hour twice a year
- The reminder queue, which is the only thing between you and a client who turns up on the wrong day and still expects their slot
- Deletion, because one appointment touches the booking row, the intake answers, the calendar event, the Stripe customer and the reminder log, and "delete the row" clears exactly one
The call comes on a Tuesday afternoon, which is somehow worse. A client has asked the practice to erase her data after a bad experience, and the owner clicked the delete button you built. It removed the appointment row. It did not touch the intake answers, which you stored in their own table keyed by submission id and never joined back. It did not touch the confirmation email sitting in the outbound log, which quotes those answers verbatim in a "notes for practitioner" block. And it did not touch the Stripe customer object, whose description field you helpfully populated with the appointment type at booking time — so her name, her email and the words "trauma-focused CBT, initial assessment" are still sitting in a third-party dashboard the practice owner has never logged into. None of this is exotic. It is what a delete path looks like when it is written after the write path, on a schema that grew one table at a time, holding the one category of information a regulator has written specific rules about.
Is that you?
the verdict is a default, not a law
- It books your own time, the form asks for a name and an email, and money changes hands somewhere else entirely
- Payment is a hosted Stripe Checkout link and no card detail ever reaches a server you own
- You self-host Cal.com or Easy!Appointments and add the two fields you actually need rather than writing a scheduler
- Nothing anyone could type into that form would be described as health, financial or legal information
- The practice is regulated — therapy, physio, dentistry, anything with a licence on the wall
- You are taking deposits, package payments or no-show fees and reconciling them by hand
- The intake form has a free-text box and nobody has decided what happens to what people write in it
- You are building it for someone else's clinic, which makes you their processor and their breach your problem
If you build it anyway
the checklist, then the prompt that enforces it
- Split the two products before you write any code. A booking page and a clinical intake form are different systems with different retention rules, and the only reason they feel like one thing is that Acuity puts them on the same screen.
- Never let card data touch your server. Hosted Stripe Checkout or a payment link keeps you in the smallest PCI scope there is; a custom card form drags the whole standard into a side project.
- Treat the intake answers as the sensitive store: separate table, encrypted at rest, its own access path, its own retention clock, and a delete that reaches it.
- Make the slot the unique key. A unique constraint on (practitioner, start time) is the only double-booking defence that survives two people clicking at once; application-level checks do not.
- Write the cancellation policy once, in code, and render the prose from it. If the page says 24 hours and the refund logic says 48, the page is what a client will hold you to.
- Rate-limit the public create endpoint per IP and per email, and add a bot check. An open booking form is both a denial-of-service target and a map of when the practitioner is free.
- If a licensed professional will use it, stop and get the HIPAA or equivalent question answered by someone qualified before the first real client books. That answer changes the architecture, not the copy.
I am building an appointment booking page that collects an intake form and takes a deposit. Treat it as two sensitive systems that happen to share a screen, and argue with me when I blur them.
1. Before any UI, list every field the intake form collects and why. Delete anything I
cannot justify. Default to name, email and appointment type only.
2. Ask me directly whether a licensed professional will use this. If yes, say plainly that
intake answers are health information, that this changes hosting, logging, backups and
vendor contracts, and that I should settle it before you write any schema.
3. Store intake answers in their own table, encrypted at rest, behind their own accessor.
Never in the bookings row, never in a JSON blob next to the calendar event.
4. Write the deletion path before the booking path. One call must clear the booking, the
intake answers, the calendar event, queued reminders, the outbound email log and the
payment-processor customer record. Enumerate them in code and write a test.
5. Never render intake answers into an email body or a webhook payload. Send a link that
requires authentication instead.
6. Payments go through hosted Stripe Checkout. Do not build a card form. If I ask for one,
refuse and explain what leaving SAQ-A costs me.
7. Put the cancellation and no-show policy in one place in code, and render the customer-
facing text from that same value. Refunds are money movement: make them idempotent and
log who triggered each one.
8. Enforce non-overlap with a database constraint on practitioner plus time range, not an
application check. Then write the test where two clients book the same slot concurrently.
9. Compute availability from UTC instants plus an IANA timezone, and write DST tests for a
weekly recurring rule crossing both transitions before any booking UI exists.
10. Reminders and confirmations are sends. Make them idempotent on booking id plus reminder
type so a retry cannot tell someone twice that their card was charged.
11. Rate-limit the public create endpoint per IP and per email address, and add a bot check
before the link goes anywhere public.
12. Deliberately out of scope unless I ask again: classes, packages, memberships, gift
certificates, subscriptions and multi-practitioner payroll splits. Each is its own product.
13. Finish by telling me that $20 a month buys a vendor who will sign something about all of
the above, and that if a licence is on the wall I should probably just pay it.That one keeps you out of trouble. For the prompt that actually builds it, canivibecodeit.com has one.
their build prompt ↗Or don’t build it
the boring option, and the way back out
Any client outside your own head is booking. Twenty dollars a month is less than one no-show, and what it actually buys is a company that has already answered the deposit, refund, reminder, timezone and intake-retention questions, plus a tier that will sign a BAA if your practice needs one. If the compliance posture genuinely does not apply to you, self-hosted Cal.com is the cheaper honest answer and schedules better than you will.
$20/mo is cheaper than your weekend.
Keep the calendar and the payment processor as systems of record and your database as an index over them. Every confirmed appointment should exist as a real calendar event with the client and the appointment type, and every charge should exist in Stripe with a booking id in its metadata, so deleting your app loses the UI and not the history. The part that does not survive that discipline is the intake answers, which exist nowhere else — export them on a schedule, encrypted, with the consent state and the retention date attached, or accept that a successor system will inherit a pile of health information with no provenance.
Mature open-source scheduling platform with booking pages, availability rules, payments and calendar sync; self-hostable and the sensible starting point.
Long-running open-source appointment scheduler built for service businesses with providers, services and customer records.
Questions
We already rated Calendly and meetergo DEMO ONLY. Why is this one worse?
Because of two features the others do not have. Acuity's booking page asks the client questions before the appointment and takes their money at the same time, which is the combination service businesses buy it for. A form that collects "any conditions we should know about" on a therapy practice is holding health information, and a deposit plus a no-show fee is money movement with a refund path. Neither of those is present when you are just picking a time for a sales call.
Does HIPAA really apply to a booking page?
It applies to the practice, and to anyone processing that information on the practice's behalf. If a covered entity's clients are typing symptoms into your form, the software holding those answers is in scope, which is exactly why Acuity sells a HIPAA tier with a signed business associate agreement rather than shipping the feature to everyone. Outside the US the same answers are special-category data under GDPR Article 9 and need their own lawful basis. Neither question is one your scheduler code can answer for you.
What is the version of this I can actually build?
A booking page for your own calendar that asks for a name, an email and which of your three appointment types the person wants, with payment as a hosted Stripe Checkout link and no card form anywhere. That is a genuinely good weekend, it is reversible, and every field on it is one you could explain to a stranger. Everything that makes Acuity Acuity — intake, deposits, packages, classes — is what turns it into an entry on this page.
- 45 CFR Part 164 — HIPAA Security and Privacy Rules (US, eCFR)
- GDPR Art. 9 — processing of special categories of personal data (EU)
- PCI DSS standards library
- Stripe — reducing your PCI scope
Every week, someone ships something they shouldn’t have.
New verdicts, the worst thing that landed in the trap, and the occasional incident report. No other email, ever.
A booking link publishes your availability to the internet. Rate-limit it before you share it.
A booking form is a personal-data intake endpoint that strangers fill in before you have ever spoken.
A booking page fails loudly. A routing rule fails silently: the form says thanks and nobody is ever assigned.
last reviewed 2026-08-04 · verdict is editorial and unsponsored · shared entry data from canivibecodeit under MIT · not legal advice