# We Built a Dental Clinic Booking Agent in One Prompt. Patients Book Over WhatsApp Now.
> A step-by-step walkthrough of building an AI booking agent for a dental clinic with three dentists. One prompt creates the agent, the data layer, and the WhatsApp integration. Patients message, pick a slot, and get a confirmed appointment.

Published: 2026-04-04
Tags: tutorial, agents, healthcare, whatsapp, getting-started, video


<YouTube id="a7A8fH-VCpc" />

## What You Need

- A Struere account (free tier works)
- Claude Code, Cursor, or another coding agent
- A WhatsApp-connected phone number through Meta Business Manager
- About 10 minutes

# A Dental Clinic With Three Dentists and No Receptionist

Dr. Erick, Dr. Marco, and Dr. Valentina run a dental clinic. General check-ups, teeth cleaning, whitening consultations, emergency appointments. Monday through Friday, 9 AM to 5 PM, 30-minute slots.

Patients call to book. Someone picks up, asks what they need, checks the schedule, finds a slot, confirms, hangs up. Repeat forty times a day. The person answering the phone could be treating patients instead.

We built a booking agent that handles the entire flow over WhatsApp. One prompt generated the agent, the data layer, and the booking logic. We connected WhatsApp through the dashboard. Ten minutes, start to finish.

This post walks through the full build from the video above.

# Two Ways to Build

Struere gives you two paths.

**Studio.** Open the dashboard, type what you need, and the agent builds everything for you. No local setup required.

**Local setup.** Use a coding agent (Claude Code, Cursor, Windsurf, whatever you prefer) to scaffold and sync the project from your terminal. You get version-controlled files and full editor support.

The video uses the local setup. You copy a setup prompt from the dashboard and send it to Claude Code. Claude downloads the Struere CLI, installs the skill so it knows the docs, and authenticates so your local files sync to the cloud.

# The Prompt

One prompt builds the entire agent. This is what we sent to Claude Code:

```
I need a booking agent for a dental clinic with 3 dentists.

Here's what it should do:

When a patient messages greet them warmly and ask what type of
appointment they need
Collect their full name and email
Offer available slots based on the schedule of the dentists.
When they confirm a slot, save the booking and add it directly
to the database
End the conversation with a clear confirmation — date, time,
and how to prepare
The clinic offers: general check-up, teeth cleaning, whitening
consultation, emergency appointment

Create:
* The agent definition with a calm, reassuring, professional tone
* An 'appointment' data type to store every booking
* A 'patient' data type to remember returning patients
* A 'dentist' data type to store dentist availability

The dentist's name is Dr. Erick, Dr. Marco, Dr. Valentina with
Default schedule: Monday to Friday, 9am-5pm, 30-minute appointments

Use these tools: entity.create, entity.query, entity.update.

When everything is ready run `struere sync`
```

Claude reads the prompt, generates the files, and syncs them to Struere. Three data types appear in the dashboard. The agent shows up with its system prompt, tools, and configuration.

# The Data Layer

Three entity types store everything the agent needs. Claude Code generates all three from the prompt, complete with fields and search indexes.

| Entity Type | Key Fields | Purpose |
|-------------|-----------|---------|
| **Dentist** | name, specialties, schedule, slotDuration | Stores each doctor and when they're available |
| **Patient** | fullName, email, phone | Tracks patients across multiple visits |
| **Appointment** | patientName, dentistName, date, timeSlot, type, status | Records every confirmed booking |

### Dentist

Each dentist record holds a name, a list of specialties (general, cleaning, whitening, emergency), and a schedule object. The schedule maps days of the week to start and end times. Claude pre-populates three records: Dr. Erick, Dr. Marco, and Dr. Valentina, all with Monday-to-Friday 9:00-17:00 availability and 30-minute slot durations.

The schedule structure matters because the agent reads it when a patient asks for availability. If Dr. Valentina only works Monday through Wednesday, the agent knows not to offer her on Thursday. You change one field in the database and the agent's behavior updates immediately. No prompt editing required.

### Patient

The patient entity stores fullName, email, and phone. When a new patient messages the agent, it asks for their name and email, then runs an `entity.query` against the patient table to check if they already exist. If the patient booked before, the agent pulls their record and skips the intake questions. If they're new, the agent creates a record with `entity.create`.

This matters for the repeat booking experience. A patient who got a cleaning last month and wants to schedule a whitening consultation doesn't have to spell out their name and email again. The agent matches them by phone number from the WhatsApp conversation and greets them by name.

### Appointment

The appointment entity ties everything together. Each record references a patient name, a dentist name, a date, a time slot, the appointment type (general check-up, teeth cleaning, whitening consultation, or emergency), and a status field (confirmed, cancelled, completed).

When the agent books a slot, it creates an appointment record and then queries existing appointments for that dentist on that date to confirm there's no double-booking. The status field lets the agent handle cancellations and reschedules without deleting data. A cancelled appointment stays in the database with status "cancelled" so the clinic has a full history.

### How They Connect

The booking flow touches all three entity types in sequence. The agent queries the **dentist** table to find who's available, queries the **patient** table to identify the caller, and creates an **appointment** record to finalize the booking. Three tools handle all of this: `entity.create` to save new records, `entity.query` to search existing ones, `entity.update` to modify them.

# Connecting WhatsApp

While Claude builds the agent, you set up WhatsApp in the dashboard.

1. Open **Integrations** and click **WhatsApp**
2. Click **Enable**, then **Add number**
3. Give the number a name
4. Complete the Facebook setup (Struere uses the Meta WhatsApp Cloud API)
5. Connect your WhatsApp Business account and select your number

Five steps. Takes about two minutes. Once the number is connected, you assign the booking agent to it. Every inbound message on that number goes to the agent.

The connection uses the Meta WhatsApp Cloud API through Kapso, which handles the infrastructure between your Struere agent and WhatsApp's servers. You don't manage webhooks, message queues, or delivery receipts. A patient sends a message, it arrives at the agent, the agent responds, and the response shows up in WhatsApp. The plumbing is invisible.

One thing worth knowing: each phone number maps to exactly one agent. If you want different agents for different purposes (booking vs. support vs. billing), you need separate numbers. Most clinics use a single number for everything and let the agent handle routing through its system prompt.

# Testing the Agent

Send a WhatsApp message to your connected number. The agent responds within seconds.

The conversation follows the flow you described in the prompt. The agent greets the patient, asks about the appointment type, collects their name and email, checks dentist availability in the database, offers open slots, and confirms the booking.

You can watch this happen live in two places. The **Chat** section of the dashboard shows every conversation the agent has with patients. Messages appear in real time as they arrive.

The **Data** section shows records as the agent creates them. You see the patient record appear when the agent saves their info. You see the appointment record appear when they confirm a slot.

For debugging, each message in the Chat section shows the tool calls the agent made. You can expand any message to see the exact `entity.query` or `entity.create` calls, the parameters passed, and the results returned. If the agent offers a slot that should be taken, you can trace exactly which query returned stale data and fix the issue.

# Sample Conversation

This is what a real booking looks like on WhatsApp. Maria wants a teeth cleaning with Dr. Chen (or in our case, one of the three dentists). The entire exchange takes about two minutes.

> **Maria:** Hi, I'd like to book an appointment
>
> **Agent:** Welcome to Sunny Dental Clinic! I'd be happy to help you book an appointment. We offer the following services:
>
> - General check-up
> - Teeth cleaning
> - Whitening consultation
> - Emergency appointment
>
> Which type of appointment are you looking for?
>
> **Maria:** Teeth cleaning please
>
> **Agent:** Great choice. Could I get your full name and email address so I can set up your appointment?
>
> **Maria:** Maria Santos, maria.santos@email.com
>
> **Agent:** Thank you, Maria. Let me check our available slots for you.
>
> I have openings for teeth cleaning this week:
>
> **Dr. Erick:**
> - Thursday, April 17 at 10:00 AM
> - Thursday, April 17 at 2:30 PM
> - Friday, April 18 at 9:00 AM
>
> **Dr. Marco:**
> - Thursday, April 17 at 11:00 AM
> - Friday, April 18 at 10:30 AM
>
> **Dr. Valentina:**
> - Thursday, April 17 at 9:00 AM
> - Friday, April 18 at 1:00 PM
>
> Which slot works best for you?
>
> **Maria:** Thursday at 9 AM with Dr. Valentina
>
> **Agent:** Your appointment is confirmed. Here are the details:
>
> **Appointment Confirmation**
> - Type: Teeth cleaning
> - Dentist: Dr. Valentina
> - Date: Thursday, April 17, 2026
> - Time: 9:00 AM
> - Duration: 30 minutes
>
> **How to prepare:**
> - Brush and floss before your visit
> - Arrive 5 minutes early
> - Bring your insurance card if applicable
>
> If you need to reschedule or cancel, just message us here. See you Thursday, Maria!

Behind the scenes, the agent made four tool calls during this conversation. First, an `entity.query` on the patient table to check if Maria exists. She didn't, so it ran `entity.create` to save her record. Then it ran `entity.query` on the appointment and dentist tables to find open slots across all three doctors. Finally, `entity.create` to save the confirmed appointment.

The whole exchange took under 90 seconds. No hold music, no phone tag, no missed calls.

# Human Takeover

Sometimes you need to step in. A patient asks a question the agent can't answer. An edge case comes up that needs a human.

Send a message from the dashboard chat panel. The agent stops replying. You have full control of the conversation. You can also take over from your WhatsApp Business phone.

The patient sees a seamless conversation. They don't know the agent stopped and a human started. When you're done, the agent can resume.

# The Result

Open the database after a few test conversations. You see patient records with names and emails. You see appointment records with dates, times, dentists, and appointment types. The dentist table has three records with their schedules.

The booking agent handles the full loop: greet, collect info, check availability, book, confirm. Patients get a clear confirmation message with the date, time, and preparation instructions.

What you have at this point is a working booking system with no custom backend code. The agent logic lives in a system prompt. The data model lives in three entity types. The WhatsApp connection lives in the dashboard. If you want to change the appointment types, you edit the prompt. If you want to add a fourth dentist, you create a record in the database. If you want to change the slot duration from 30 minutes to 45, you update the dentist records. The agent adapts to whatever data it finds.

# Key Takeaways

- One prompt generated the agent, three data types, and the system prompt
- The agent checks real dentist availability before confirming any slot
- WhatsApp connection took under two minutes through the dashboard
- Patients complete the full booking loop without human intervention
- The entire build took 10 minutes from zero to working agent

# Next Steps

The next video covers two additions: Google Calendar integration (so bookings sync to each dentist's calendar) and automations like appointment reminders sent 24 hours before the slot.

For a production deployment example, read the [Smile Studio case study](/blog/automate-dental-appointment-booking-ai-agent) where a clinic eliminated missed calls and recovered thousands in lost bookings.

If you run into issues, join the [Discord](https://discord.gg/struere). We answer questions there.

## Frequently Asked Questions

### Can I customize the appointment types beyond general checkups?

Add fields to the appointment entity type for procedure, duration, and equipment needed. The agent's system prompt controls which questions it asks during booking.

### Does this integrate with Google Calendar?

Struere has a built-in Google Calendar integration. Add calendar.freeBusy and calendar.create to the agent's tools, connect Google through the dashboard, and the agent checks real availability before confirming slots.

### How do I handle multiple clinic locations?

Add a location field to the dentist entity type and include location selection as one of the agent's first questions. The agent filters available dentists by the patient's chosen location.

### What happens when all slots are booked?

The agent tells the patient no slots are available for their preferred time and suggests the next opening. You can also add a waitlist entity type to let patients queue for cancellations.

### Can patients cancel or reschedule through WhatsApp?

The agent looks up existing appointments by patient phone number, updates the status to cancelled, and offers to rebook. Add appointment.updated triggers to notify the dentist when changes happen.
