DEV Community

Midas Tools
Midas Tools

Posted on

How to Automate Appointment Booking with AI (No Custom Code Required)

Every missed call is a missed appointment. For dentists, law firms, salons, and consultants, the phone is still the #1 booking channel — and most of them miss 30–40% of calls because staff are busy or it's after hours.

AI can fix this. Here's exactly how to build an automated appointment booking system using existing tools — no custom development required.


What You're Building

A phone system that:

  • Answers calls 24/7 in a natural voice
  • Asks the right qualifying questions
  • Checks availability in real time
  • Books the appointment and sends confirmation
  • Escalates to a human when needed

Cost: ~$50–150/month in tools. Time to set up: 1–2 days.


The Stack

Layer Tool Cost
Voice AI Vapi.ai or Bland.ai $0.05–0.10/min
Scheduling Cal.com or Calendly Free–$12/mo
Calendar Google Calendar Free
CRM / Notifications Slack + email Free
AI Brain Claude or GPT-4o ~$20/mo

Vapi is the best choice right now for production-grade voice AI. It handles STT (speech-to-text), LLM orchestration, and TTS (text-to-speech) in one platform, with sub-500ms latency that makes conversations feel natural.


Step 1: Set Up Your Scheduling Backend

First, configure Cal.com so it exposes availability via API.

# Cal.com API — get available slots
curl -X GET 'https://api.cal.com/v1/slots?eventTypeId=YOUR_EVENT_ID&startTime=2026-02-28T00:00:00Z&endTime=2026-03-07T00:00:00Z' \
  -H 'Authorization: Bearer YOUR_CAL_API_KEY'
Enter fullscreen mode Exit fullscreen mode

This returns a list of open time slots. Your AI will call this in real time during the conversation.

Create one event type per service (e.g., "30-min Consultation", "Initial Exam", "Follow-up"). Set buffer times and limits so the calendar never gets over-booked.


Step 2: Build the Vapi Assistant

Create a new assistant in Vapi's dashboard or via API:

{
  "name": "Booking Assistant",
  "model": {
    "provider": "anthropic",
    "model": "claude-sonnet-4-5",
    "systemPrompt": "You are a friendly booking assistant for [Business Name]. Your job is to help callers schedule appointments. Be warm, concise, and professional. Always confirm the appointment details before booking. If the caller has an emergency or complex issue, offer to transfer to a staff member."
  },
  "voice": {
    "provider": "elevenlabs",
    "voiceId": "21m00Tcm4TlvDq8ikWAM"
  },
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_available_slots",
        "description": "Get available appointment slots for the next 7 days",
        "parameters": {
          "type": "object",
          "properties": {
            "service_type": {
              "type": "string",
              "description": "Type of appointment requested"
            }
          }
        }
      },
      "server": {
        "url": "https://your-api.com/get-slots"
      }
    },
    {
      "type": "function",
      "function": {
        "name": "book_appointment",
        "description": "Book an appointment slot",
        "parameters": {
          "type": "object",
          "properties": {
            "slot_time": { "type": "string" },
            "name": { "type": "string" },
            "phone": { "type": "string" },
            "service": { "type": "string" }
          },
          "required": ["slot_time", "name", "phone", "service"]
        }
      },
      "server": {
        "url": "https://your-api.com/book-appointment"
      }
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

The key insight: give your assistant exactly two tools — one to read available slots, one to write a booking. That's it. Don't over-engineer it.


Step 3: Build the API Endpoints

You need two simple serverless functions. Here's the booking one in Node.js:

// /api/book-appointment.js
export default async function handler(req, res) {
  const { slot_time, name, phone, service } = req.body;

  // Book via Cal.com API
  const booking = await fetch('https://api.cal.com/v1/bookings', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.CAL_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      eventTypeId: getEventTypeId(service),
      start: slot_time,
      responses: {
        name,
        email: 'phone-booking@yourbusiness.com', // placeholder
        phone
      },
      metadata: { source: 'phone_ai' }
    })
  });

  const result = await booking.json();

  // Notify staff via Slack
  await fetch(process.env.SLACK_WEBHOOK, {
    method: 'POST',
    body: JSON.stringify({
      text: `📅 New AI booking: ${name} | ${service} | ${slot_time} | ${phone}`
    })
  });

  res.json({ success: true, bookingId: result.id });
}
Enter fullscreen mode Exit fullscreen mode

Deploy to Vercel in 30 seconds:

vercel deploy --prod
Enter fullscreen mode Exit fullscreen mode

Step 4: Wire Up the Phone Number

In Vapi, go to Phone NumbersBuy a number. You'll get a real phone number for ~$2/month. Assign your assistant to it.

Now test it: call the number and say "I'd like to book an appointment for next Tuesday."

If it works, you have a 24/7 booking agent.


Step 5: Tune the Conversation Flow

The system prompt matters more than the code. Good booking assistants:

Qualify first, book second. Before offering slots, ask:

  • What type of appointment do you need?
  • Is this your first visit?
  • (For medical) Are you an existing patient?

Handle objections: "I'm not sure if I need the 30-min or 60-min session" → give a clear decision rule.

Confirm before finalizing: Always read back the appointment details. "So that's a consultation on Tuesday March 3rd at 2 PM — does that work for you?"

Set expectations for follow-up: "You'll receive a confirmation text within a few minutes."


Real-World Performance Numbers

Based on deployments in dental and legal practices:

  • Call answer rate: 100% (vs. 60–70% with human staff)
  • Booking conversion: 55–65% of callers who reach the AI book an appointment
  • Average handle time: 2–4 minutes
  • After-hours bookings: 20–30% of all bookings happen outside business hours
  • Cost per booking: $0.15–0.50 (vs. $3–8 for a human receptionist)

What This Doesn't Replace

Be honest with your clients: the AI handles routine bookings well. It struggles with:

  • Complex insurance questions
  • Callers who are upset or in distress
  • Unusual requests that don't fit standard slots
  • Relationship-building with high-value clients

The solution: build a graceful escalation path. When confidence is low or the caller asks to speak to someone, transfer immediately. Don't let the AI hold someone hostage.


Getting Started Today

  1. Sign up for Vapi.ai (free trial)
  2. Connect your Google Calendar via Cal.com
  3. Write a system prompt specific to your business
  4. Deploy two API endpoints
  5. Buy a $2/month phone number
  6. Test with 20 mock calls before going live

The whole thing can be live in a weekend. The ROI from capturing after-hours bookings alone typically pays for it in the first month.


Building AI automations for small businesses is what we do at RooxAI — if you'd rather have this set up for you than DIY it, that's an option too.

Top comments (0)