Appointment Booking Agent
A voice agent that handles appointment scheduling, rescheduling, and confirmations for healthcare, salons, or service businesses.
Configuration
{
"agent": {
"name": "Appointment Assistant",
"language": "en-US",
"llmProvider": "gemini-2.5",
"llmModel": "gemini-2.5-flash-lite",
"llmTemperature": 0.5,
"sttProvider": "deepgram",
"sttModel": "nova-3",
"ttsProvider": "azure",
"ttsVoice": "en-US-JennyNeural",
"greetingMessage": "Hello! This is Dr. Smith's office. I can help you schedule, reschedule, or confirm an appointment. What would you like to do?",
"prompt": "..."
}
}
System Prompt
You are an appointment scheduling assistant for Dr. Smith's Medical Clinic.
## Your Capabilities
- Schedule new appointments
- Reschedule existing appointments
- Confirm upcoming appointments
- Cancel appointments
- Answer questions about office hours and location
## Office Information
- Hours: Monday-Friday 8 AM to 5 PM, Saturday 9 AM to 1 PM
- Address: 456 Health Center Drive, Suite 200
- Phone: 555-123-4567
## Appointment Types
- General checkup: 30 minutes
- Follow-up: 15 minutes
- New patient consultation: 45 minutes
- Physical exam: 60 minutes
## Guidelines
### Scheduling Flow
1. Ask what type of appointment they need
2. Check availability using the tool
3. Offer 2-3 available time slots
4. Confirm their selection
5. Get/verify patient name and phone number
6. Confirm all details before ending
### Date/Time Handling
- Always confirm dates: "That's Tuesday, January 15th at 2:30 PM, correct?"
- Speak times clearly: "two thirty in the afternoon"
- Offer morning, afternoon, or specific times based on preference
### Required Information for Booking
- Patient full name
- Phone number
- Type of appointment
- Preferred date/time
- Insurance (for new patients)
### Rescheduling
1. Look up existing appointment
2. Confirm what appointment they want to change
3. Get new preferred time
4. Offer available slots
5. Confirm the change
### Cancellation Policy
Mention: "Please note, we ask for 24 hours notice for cancellations to avoid a fee."
## Example Conversations
**New Appointment:**
Patient: "I need to schedule a checkup"
You: "I can help with that. Do you have a preference for morning or afternoon?"
Patient: "Afternoon works better"
You: "How about Tuesday the 15th at 2:30 PM, or Wednesday the 16th at 3 PM?"
Patient: "Tuesday works"
You: "Great! I have you down for Tuesday, January 15th at 2:30 PM. May I have your name?"
Patient: "John Smith"
You: "And what's the best phone number to reach you, Mr. Smith?"
Patient: "555-867-5309"
You: "Perfect. You're all set for a checkup with Dr. Smith on Tuesday, January 15th at 2:30 PM. We'll send a text reminder the day before. Is there anything else?"
**Confirmation Call:**
You: "Hi, I'm calling from Dr. Smith's office to confirm your appointment tomorrow at 10 AM. Can you confirm you'll be there?"
Patient: "Yes, I'll be there"
You: "Wonderful! As a reminder, please arrive 10 minutes early and bring your insurance card. See you tomorrow!"
Tools
Check Availability
{
"type": "function",
"function": {
"name": "check_availability",
"description": "Check available appointment slots",
"parameters": {
"type": "object",
"properties": {
"date": {
"type": "string",
"description": "Preferred date (YYYY-MM-DD)"
},
"appointment_type": {
"type": "string",
"enum": ["checkup", "followup", "new_patient", "physical"],
"description": "Type of appointment"
},
"time_preference": {
"type": "string",
"enum": ["morning", "afternoon", "any"],
"description": "Time preference"
}
},
"required": ["appointment_type"]
}
}
}
Book Appointment
{
"type": "function",
"function": {
"name": "book_appointment",
"description": "Book a new appointment",
"parameters": {
"type": "object",
"properties": {
"patient_name": {
"type": "string",
"description": "Patient's full name"
},
"phone": {
"type": "string",
"description": "Contact phone number"
},
"appointment_type": {
"type": "string",
"description": "Type of appointment"
},
"datetime": {
"type": "string",
"description": "Appointment date and time (ISO 8601)"
}
},
"required": ["patient_name", "phone", "appointment_type", "datetime"]
}
}
}
Reschedule Appointment
{
"type": "function",
"function": {
"name": "reschedule_appointment",
"description": "Reschedule an existing appointment",
"parameters": {
"type": "object",
"properties": {
"appointment_id": {
"type": "string"
},
"new_datetime": {
"type": "string",
"description": "New date and time"
}
},
"required": ["appointment_id", "new_datetime"]
}
}
}
Lookup Appointment
{
"type": "function",
"function": {
"name": "lookup_appointment",
"description": "Look up an existing appointment by phone number",
"parameters": {
"type": "object",
"properties": {
"phone": {
"type": "string"
}
},
"required": ["phone"]
}
}
}
Tool Handlers
func handleCheckAvailability(params map[string]any) (string, error) {
appointmentType := params["appointment_type"].(string)
timePreference := params["time_preference"].(string)
duration := getAppointmentDuration(appointmentType)
slots, _ := calendar.GetAvailableSlots(duration, timePreference, 3)
if len(slots) == 0 {
return "I don't see any availability for that time preference. Would you like to try a different day or time?", nil
}
response := "I have the following times available: "
for i, slot := range slots {
response += formatSlotForSpeech(slot)
if i < len(slots)-1 {
response += ", or "
}
}
response += ". Which works best for you?"
return response, nil
}
func formatSlotForSpeech(slot time.Time) string {
// "Tuesday, January 15th at 2:30 in the afternoon"
return slot.Format("Monday, January 2nd") + " at " +
formatTimeForSpeech(slot)
}
func formatTimeForSpeech(t time.Time) string {
hour := t.Hour()
minute := t.Minute()
period := "in the morning"
if hour >= 12 {
period = "in the afternoon"
if hour > 12 {
hour -= 12
}
}
if minute == 0 {
return fmt.Sprintf("%d o'clock %s", hour, period)
}
return fmt.Sprintf("%d %02d %s", hour, minute, period)
}
Outbound Confirmation Calls
func sendConfirmationCalls() {
tomorrow := time.Now().Add(24 * time.Hour)
appointments, _ := db.GetAppointmentsForDate(tomorrow)
for _, apt := range appointments {
initiateConfirmationCall(apt)
}
}
func initiateConfirmationCall(apt Appointment) {
client.Calls.Create(CallRequest{
AgentID: "appointment_confirmation",
To: apt.PatientPhone,
Variables: map[string]string{
"patientName": apt.PatientName,
"appointmentTime": apt.DateTime.Format("3:04 PM"),
"appointmentDate": apt.DateTime.Format("January 2"),
"doctorName": apt.DoctorName,
"appointmentType": apt.Type,
},
})
}
Confirmation Agent Prompt:
You are calling to confirm an appointment.
Greeting: "Hi, this is {{doctorName}}'s office calling for {{patientName}}. We're confirming your {{appointmentType}} appointment tomorrow, {{appointmentDate}} at {{appointmentTime}}."
If confirmed: "Wonderful! Please arrive 10 minutes early. See you tomorrow!"
If needs to reschedule: Use the reschedule tool.
If no answer: Mark for callback.
SMS Integration
func sendAppointmentConfirmation(apt Appointment) {
message := fmt.Sprintf(
"Your appointment with %s is confirmed for %s at %s. " +
"Reply CONFIRM to confirm or RESCHEDULE to change. " +
"Location: %s",
apt.DoctorName,
apt.DateTime.Format("Mon, Jan 2"),
apt.DateTime.Format("3:04 PM"),
apt.Location,
)
smsClient.Send(apt.PatientPhone, message)
}
Analytics
type BookingMetrics struct {
TotalCalls int
SuccessfulBookings int
Reschedules int
Cancellations int
NoShows int
AverageCallDuration time.Duration
BookingConversionRate float64
}
func trackBookingCall(call *Call, outcome string) {
metrics.Increment("appointments.calls.total")
metrics.Histogram("appointments.call_duration", call.Duration.Seconds())
switch outcome {
case "booked":
metrics.Increment("appointments.bookings.success")
case "rescheduled":
metrics.Increment("appointments.reschedules")
case "cancelled":
metrics.Increment("appointments.cancellations")
}
}
Next Steps
- Customer Support - Full support agent
- Variables - Dynamic content
- Webhooks - Calendar integration