For clean Markdown of any page, append .md to the page URL. For a complete documentation index, see https://docs.telcoflow.com/use-cases/llms.txt. For full documentation content, see https://docs.telcoflow.com/use-cases/llms-full.txt.

# Appointment Booking and Confirmation

An AI agent handles appointment scheduling, checks availability against a calendar system, and confirms bookings.

## Overview

This use case demonstrates:
- Calendar/scheduling system integration
- Multi-turn conversational data gathering
- Real-time availability checking
- SMS confirmation after booking
- Fallback connect to a human when automation cannot fulfill the request

**State flow:** PENDING -> ANSWERED -> DISCONNECTED (or -> ANSWERED -> CONNECTED -> DISCONNECTED on fallback)

## Example

```python
@client.on(events.INCOMING_CALL)
async def appointment_booking(call: ActiveCall):
    await call.answer()

    customer = await db.get_customer_by_phone(call.caller_number)
    existing_appointments = await calendar.get_upcoming(customer.id) if customer else []

    if existing_appointments:
        next_appt = existing_appointments[0]
        msg = (
            f"Hi {customer.name}, I see you have an appointment on "
            f"{next_appt.date}. Would you like to reschedule or book a new one?"
        )
        await call.send_audio(await tts.synthesize(msg))
    else:
        await call.send_audio(
            await tts.synthesize("Hi! I can help you book an appointment.")
        )

    # AI conversational loop to gather appointment details
    appointment_details = await ai_model.gather_appointment_info(call)

    # Check availability
    available_slots = await calendar.get_available_slots(
        date=appointment_details["date"],
        service=appointment_details["service"],
    )

    if available_slots:
        # Book the appointment
        booking = await calendar.create_booking(
            customer_id=customer.id,
            slot=available_slots[0],
            service=appointment_details["service"],
        )
        await call.send_audio(
            await tts.synthesize(
                f"You're booked for {booking.date} at {booking.time}. "
                "You'll receive a confirmation SMS shortly."
            )
        )
        await sms.send_confirmation(call.caller_number, booking)
    else:
        await call.send_audio(
            await tts.synthesize(
                "Unfortunately there are no slots available on that date. "
                "Let me connect you with our scheduling team."
            )
        )
        # Connect to the original callee and leave
        await call.connect()
        await call.close()
        return

    await call.disconnect()
```

## How It Works

1. The AI answers and checks if the caller has existing appointments
2. If so, it proactively mentions them and asks if the caller wants to reschedule
3. The AI gathers details conversationally: preferred date, time, and service type
4. It queries the calendar system for available slots
5. If a slot is available, the AI books it, confirms verbally, and sends an SMS
6. If no slots are available, the AI explains the situation, connects the caller to the original callee using `connect()`, and then leaves the call with `close()`

## Key Commands Used

- [`answer()`](/concepts/call-commands#answer) - Answer the incoming call
- [`send_audio()`](/concepts/audio-streaming#sending-audio) - Verbal confirmation and prompts
- [`connect()`](/concepts/call-commands#connectring_time_seconds60) - Fallback to callee for scheduling
- [`close()`](/concepts/call-commands#close) - Leave after connecting the caller to the scheduling team
- [`disconnect()`](/concepts/call-commands#disconnect) - End the call after a successful booking flow

## Related

- [AI Receptionist with Database Lookup](/use-cases/database-lookup) - Similar CRM integration pattern
- [Interactive Notifications](/use-cases/interactive-notifications) - Delivering confirmations interactively