Designing notification content in a dental clinic: the fields a reminder needs, why template variables are the exposure decision, and per-channel consent.
Key takeaways
- Appointment and treatment data is personal data of a sensitive kind. Which part of it reaches a handset is chosen by whoever built the template.
- A reminder works on four fields: first name, time, clinic identity, and a confirm-or-change route. The procedure name is not one of them.
- A template variable wired to a free-text field in another system is the most common way a clinical description lands in a message nobody meant to send.
- Consent is stored per channel and per purpose, with a time and a source. One boolean per patient cannot answer "why was this message sent".
Notification content is a design decision, not a by-product of whichever fields exist in the system. A reminder can say "your appointment tomorrow at 10:00" and do exactly the same job as one that names a procedure. What follows is a technical description of message and workflow design, not medical, legal or financial advice.
The message that goes out, and the fields behind it
A real appointment reminder reads: "Hello Dana, a reminder for your appointment at the clinic tomorrow, Tuesday, at 10:00. Reply 1 to confirm, 2 to change." That message does the whole job: it identifies the recipient, gives a time, and gives a route to act.
What it does not do is describe why the appointment was booked. The distance between the two versions is one line in the code that assembles the message:
| Field | In the handset message | In the internal diary | In the patient file |
|---|---|---|---|
| First name | Yes | Yes | Yes |
| Time and duration | Time only | Time and duration | Time and duration |
| Practitioner name | Not required | Yes | Yes |
| Procedure type | No | Internal code only | Yes |
| Clinical notes | No | No | Yes |
| Amount payable | In a separate payment message | Yes | Yes |
| Confirm or cancel route | Yes | Yes | Not applicable |
The handset column is the shortest of the three, and that is the point. Lock screens render previews, shared household devices exist, and a screenshot of a message travels. The reminder mechanism itself - scheduling, and what happens on a no-show - is taken apart in automated appointment reminders and reducing no-shows.
Why are template variables the real exposure decision?
Because a WhatsApp Cloud API template is not free text. It is a structure with numbered variables, {{1}}, {{2}} and so on, and what goes into each one is decided by the code that sends it. A sensible reminder template looks like this:
{{1}}- first name only.{{2}}- a full datetime in one consistent format.{{3}}- the clinic name or a callback number.
The common failure is not in the template but in the mapping: somebody wires {{2}} to the diary's "appointment title" field, and that field holds free text written by clinical staff. From then on the message reports to the recipient whatever the staff typed in the title. A template variable belongs on a structured field and never on a free-text one. For current build and running costs, see how much a chatbot costs.
Two documented constraints worth designing around:
- Outside the 24-hour window you may only initiate with an approved template. Every inbound message from the patient opens and resets a 24-hour customer service window, and inside it you can reply in free text.
- A template is reviewed before it is approved. Content and structure are submitted to Meta up front, which is a good moment to confirm the template has no slot a clinical description could leak into. The submission process itself is unpacked in WhatsApp template approval.
Consent as a record per channel and per purpose
A single "agrees to receive messages" flag answers one question and leaves three open. The record that answers all four carries recipient, channel, purpose and time:
| Channel | Purpose | Example of what is sent |
|---|---|---|
| Appointment reminder | Time plus a confirm route | |
| SMS | Appointment reminder | Same content, fallback channel |
| Documents and invoices | Receipt, payment confirmation | |
| Marketing outreach | An offer, a periodic check-up prompt |
Separating the fourth row from the first is the difference between a patient who can stop marketing while still receiving reminders, and a patient forced to choose between everything and nothing. Each row also carries a source - where the consent was captured, an intake form or a reply message - and a time. A practical comparison of the channels themselves sits in SMS vs WhatsApp vs email for reminders.
What does a payment link need to know about the treatment?
Nothing. A payment page works on four values: a charge identifier, an amount, a currency and an expiry. The procedure name is not needed to collect money, and it is what turns the link into a document that must not be forwarded. The build walkthrough is in how to create a WhatsApp bot.
A workable charge shape:
charge_id- opaque and unguessable, never a running number.patient_ref- an internal reference, not an ID number and not a full name in the URL.amountandcurrency- the figure as it appears on the invoice, VAT handled per the clinic's own setting.expires_at- an expiry. A payment link with none is a link that still works a year later.invoice_id- the pointer to the invoice, which is the document that carries the detail.
The detail lives on the invoice, and the invoice goes to whichever channel was designated for documents. The short message on the phone points at it and does not contain it.
Who sees what: roles over three stores
Practical separation starts with three separate stores, not with one permission column on one table:
- Diary and appointments - times, practitioner, attendance status. Reception needs full access.
- Clinical file - diagnoses, treatments, imaging. Clinical staff only.
- Charges and documents - invoices, receipts, balances. Bookkeeping access.
The role that produces most of the trouble is the external supplier: whoever runs the phone system, the reminder service or the chat channel. Sometimes they need the diary, and almost never the clinical file. That separation is enforced at the data layer rather than the screen, for instance with row-level policies of the kind documented in PostgreSQL Row Security Policies.
What actually breaks
- A free-text diary title sent as a variable. The description staff wrote for themselves becomes the body of the message.
- A cancelled appointment whose reminder still went out. The cancellation updated the diary and not the send queue.
- A payment link with no expiry. Two months later somebody clicks it again and pays twice.
- Consent captured once with no channel. You cannot answer why a specific message went out on a specific channel.
- One template serving two purposes. A reminder that doubles as an offer mixes two things a patient would have separated.
- Imaging sent through the chat. A file that leaves for a chat thread is no longer governed by the file's retention policy.
Sources
Frequently asked questions
Is it acceptable to put the dentist's name in the reminder?
That is the clinic's decision, not a technical rule. From a design standpoint the practitioner name is an extra field that is not needed to confirm or move an appointment. If you do include it, make it a separate structured field rather than part of a free-text string pulled from the diary.
Which is better for reminders, WhatsApp or SMS?
WhatsApp gives a two-way reply path so confirmation and cancellation happen in the same thread, which shortens handling. SMS depends on no account or app and makes a good fallback. Many clinics run both with identical content and pick per patient based on stored consent.
How do you know the reminder actually arrived?
Through the message status updates delivered on the webhook, not through the fact that the API call succeeded. A successful send means the message was accepted for processing. Store the message ID and the latest status per reminder, and alert on reminders that stall.
Do Hebrew and English need separate templates?
Yes. A template is submitted for approval with a declared language, so two languages are two templates sharing a name with different language codes. Storing a language preference per patient prevents the case where somebody who chose Hebrew gets an English reminder because that template was approved first.
Keep reading
Related service
WhatsApp Cloud API
Templates, a two-way inbox and reminders on the official Meta API.
About the author
Yehonatan Saadia
Freelance automation, web & MVP developer
I'm Yehonatan Saadia, a senior developer who builds business automation, custom websites, and MVPs for small and mid-sized companies across the US, Europe, and Israel. These guides come from real client work, not theory.
Work with meHave a project like this?
Tell me what you're trying to automate or build. I reply within 24 business hours with a few targeted questions, then we walk through it on a free 30-minute call, with no commitment. You come away with a scope, a timeline and a fixed price - or a straight answer that it isn't worth building.
