# How to build an appointment booking and reminder chatbot

> An appointment flow fetches real availability through a webhook, books the chosen slot and saves the date to a contact field. A campaign based on that date then sends reminders that let customers confirm, reschedule or cancel in one tap.

URL: https://on-chat.live/guides/appointment-booking-chatbot/
Last updated: 2026-10-27

Phone calls to book appointments tie up your front desk, and missed appointments cost you slots that someone else could have used. A booking flow on WhatsApp or SMS solves both: customers book in a few taps, and automatic reminders let them confirm or reschedule before the day.

This guide builds two connected pieces in On-chat's [flow builder](https://on-chat.live/flow-builder/):

1. a **booking flow** that offers real available slots, and
2. a **reminder campaign** that runs automatically before each appointment.

## How the pieces fit together

The booking flow and the reminder campaign are connected by one contact field that holds the appointment date. The flow writes the date when a customer books, and the campaign reads it to schedule reminders.

```
Booking flow:   Choose service → Get free slots (webhook) → Pick a slot → Confirm (webhook) → Save date to contact
Reminder campaign:   1 day before appointment → Confirm / Reschedule / Cancel
                     2 hours before → Short reminder
```

The key link is a **contact field** holding the appointment date. The booking flow writes it, and the campaign reads it.

## Step 1: Create the appointment date field

Create a contact field of type **date**, for example `appointment_date`. A campaign can only schedule events relative to a date field, so this is essential.

You may also want `appointment_service` (text) and `appointment_id` (text) to store details from your booking system.

## Step 2: Ask which service

Start the booking flow with **Send the contact a message**:

> Hi @contact.first_name! What would you like to book?

Quick replies: `Consultation`, `Follow-up`, `Cleaning`. Then **Wait for the contact to respond** and save the result as `service`.

## Step 3: Fetch real availability with a webhook

Add **Call a webhook** to ask your calendar or booking system for open slots:

- **Method:** `GET`
- **URL:** `https://api.your-clinic.com/slots?service=@results.service.category`

Return a short list your flow can show directly, for example:

```json
{
  "slots": [
    { "id": "s1", "label": "Tue 4 Nov, 10:00", "start": "2026-11-04T10:00:00+02:00" },
    { "id": "s2", "label": "Tue 4 Nov, 15:30", "start": "2026-11-04T15:30:00+02:00" },
    { "id": "s3", "label": "Wed 5 Nov, 11:00", "start": "2026-11-05T11:00:00+02:00" }
  ]
}
```

Then send the options, using the response in the quick replies:

> Here are the next available times:

Quick replies: `@(webhook.slots[0].label)`, `@(webhook.slots[1].label)`, `@(webhook.slots[2].label)`

Keep it to three options. If none suit, add a fourth quick reply, `Other time`, that opens a ticket so the front desk can help.

> Don't have a booking API? Start simpler: offer fixed choices like `Morning` / `Afternoon` and open a ticket for staff to confirm the exact time. You can add the webhook later without changing the rest of the flow.

## Step 4: Confirm the booking

After the customer picks a slot, **Call a webhook** again with `POST` to reserve it in your system:

```json
{
  "phone": "@contact.urn",
  "name": "@contact.name",
  "service": "@results.service.category",
  "slot": "@results.slot"
}
```

Have your API return the confirmed start time and a booking ID. On **Success**:

1. **Update the contact**: set `appointment_date` to the returned start time and `appointment_id` to the booking ID.
2. Send a confirmation:

> You're booked for @results.slot ✅ Reply CHANGE any time if you need to reschedule.

On **Failure** (for example, someone else took the slot a second earlier), apologise and loop back to fetch fresh availability.

## Step 5: Set up the reminder campaign

Now the part that cuts no-shows. Go to **Campaigns**:

1. Create a campaign based on a group, for example `Patients` (make sure the booking flow adds contacts to this group).
2. Add an event **1 day before** `appointment_date` that starts a short **reminder flow**.
3. Add a second event **2 hours before** that sends a brief message.

Because events are relative to each contact's own date, every customer gets reminders at the right time, and if the date changes the reminders move with it.

## Step 6: Build the reminder flow

The 1-day reminder should make the next action one tap away:

> Reminder: your @fields.appointment_service is tomorrow at @(format_datetime(fields.appointment_date, "tt:mm")). Can you make it?

Quick replies: `Yes, see you`, `Reschedule`, `Cancel`.

- **Yes**: thank them, and optionally **Call a webhook** to mark the appointment confirmed.
- **Reschedule**: **Enter another flow** and send them back into the booking flow, starting at the availability step.
- **Cancel**: call your API to free the slot, then ask (optionally) why. That data is gold.

On WhatsApp, a reminder sent more than 24 hours after the customer's last message must use an **approved message template**. Create a utility template for reminders and use it for the first message of the reminder flow.

## Step 7: Reach everyone

Not every customer uses WhatsApp. Flows run on any channel, so:

- send the same reminder over **SMS** to contacts without WhatsApp,
- or use a [voice flow](https://on-chat.live/ivr-voice-automation/) that calls and asks the customer to press 1 to confirm or 2 to reschedule.

## Test before launch

Test the booking flow, the saved date and the reminder campaign together before real customers use them.

1. Book through the **Simulator** and check the date lands in `appointment_date`.
2. Set a test appointment for tomorrow and confirm the campaign event is scheduled.
3. Try **Reschedule** and **Cancel** to make sure your booking system updates.

## What to track

Track how many customers confirm, reschedule or cancel, and compare no-shows before and after launch.

- **Confirmation rate** from the reminder flow results.
- **Reschedules versus cancellations**: a reschedule is a saved appointment.
- **No-shows** before and after launch, from your own booking system.

For clinics, see how this fits into [patient messaging for healthcare](https://on-chat.live/solutions/healthcare/). To go deeper on live data, read [making your chatbot dynamic with webhooks](https://on-chat.live/guides/dynamic-chatbot-webhooks/), or [start building for free](https://on-chat.live/org/signup/).

## Put this guide into practice

- [Visual flow builder](https://on-chat.live/flow-builder/): Build dynamic conversation flows without code: branch on answers, use live data from your systems and run one flow on WhatsApp, SMS and voice.
- [Healthcare](https://on-chat.live/solutions/healthcare/): Reduce no-shows with automated appointment reminders on SMS, WhatsApp and voice. Confirm, reschedule and follow up with patients automatically.

## Keep reading

- [How to Build a WhatsApp Chatbot Without Code](https://on-chat.live/guides/how-to-build-a-whatsapp-chatbot/): A step-by-step tutorial for building a dynamic WhatsApp chatbot in a visual flow builder, from your first message to live data and agent handoff.
- [Chatbot Flow Design: 12 Best Practices](https://on-chat.live/guides/chatbot-flow-design-best-practices/): Practical rules for designing chatbot conversation flows that customers finish: branching, fallbacks, personalisation, handoff and testing.
- [Make Your Chatbot Dynamic with Webhooks](https://on-chat.live/guides/dynamic-chatbot-webhooks/): Connect your chatbot flows to live data. Learn how webhooks, expressions and splits turn a scripted bot into one that answers with real information.
