voice ai for appointment booking: Build a Vapi + ElevenLabs Agent that books slots and sends reminders 24/7 A developer has published a step-by-step guide for building a voice AI appointment-booking agent that chains Vapi's speech-to-intent engine with ElevenLabs' neural text-to-speech, orchestrated through an n8n workflow connected to Google Calendar and Twilio. The system handles inbound calls, extracts booking intents and slots, creates calendar events, confirms via SMS, and places automated reminder calls, with OpenAI as a fallback when Vapi's intent confidence drops below 0.8. The writeup estimates a 6-8 hour build using free tiers and pay-as-you-go services. You can wire Vapi's speech-to-intent engine to ElevenLabs' neural text-to-speech, then glue the two together with an n8n workflow that talks to Google Calendar and Twilio. The result is a fully-automated "voice AI for appointment booking" that can take calls, create calendar events, confirm via SMS, and call the client back with a reminder generated on the fly. | Tool | Plan / Price | Role | |---|---|---| | Vapi | Free tier up to 5,000 minutes/month - check the pricing page | Speech recognition, intent extraction, phone number provisioning | | ElevenLabs | Free tier 10,000 characters/month - check the pricing page | High-quality voice synthesis for confirmations & reminders | | n8n | Self-hosted Docker free or Cloud starter $20 / month | Orchestrates API calls between Vapi, ElevenLabs, Google Calendar, Twilio, OpenAI | | Google Cloud - Calendar API | Free tier up to 1 million calls/month - check pricing | Stores appointment slots, provides event IDs and reminders | | Twilio | Pay-as-you-go ≈ $0.0085 per outbound call, $0.0075 per SMS | PSTN/SMS gateway for confirmations and reminder calls | | OpenAI optional | Free trial $18, then $0.002 per 1 k tokens | Fallback NLU when Vapi intent confidence is low | | Calendly optional | Free plan basic scheduling | Alternative booking UI if you prefer a web link over Google Calendar | Prices are accurate as of August 2026; always verify on the provider's pricing page. Estimated build time: 6-8 hours account setup ≈ 1 h, n8n workflow ≈ 3 h, testing ≈ 2 h . Below is a concrete, copy-paste-ready path from "zero" to a production-ready voice AI for appointment booking. | Intent | Sample utterances | Slots variables | |---|---|---| | book appointment | "I'd like to book a meeting", "Schedule a 30-minute call next Thursday at 2 pm" | date , time , duration , name , phone | | reschedule appointment | "Can we move my appointment to Friday?", "Change my booking" | event id , new date , new time | https://YOUR N8N DOMAIN/webhook/vapi-book . Tip: Vapi returns a JSON payload with the extracted slots and a confidence score. Keep the confidence 0.8 for direct processing; otherwise forward to OpenAI. EXAMPLE VOICE ID . https://YOUR N8N DOMAIN/ as an authorized redirect URI. credentials.json and store it in the n8n data folder /root/.n8n/ . Why OAuth? The Calendar API requires a refresh token for long-running workflows; n8n can store it automatically. Pull the official n8n Docker image latest tag as of Aug 2026 docker run -d \ --name n8n \ -p 5678:5678 \ -v ~/.n8n:/root/.n8n \ n8nio/n8n:latest http://localhost:5678 and set a strong | Credential | Service | Fields | |---|---|---| | Vapi API | Vapi | apiKey | | ElevenLabs API | ElevenLabs | apiKey | | Google Calendar OAuth2 | Google Calendar | upload credentials.json , authorize the account that owns the target calendar | | Twilio | Twilio | Account SID , Auth Token , From number a purchased Twilio number | The workflow consists of three logical parts: What this does: Accepts the JSON Vapi sends after intent extraction. { "nodes": { "parameters": { "httpMethod": "POST", "path": "vapi-book", "responseMode": "onReceived" }, "name": "Vapi Webhook", "type": "n8n-nodes-base.webhook", "typeVersion": 1, "position": 250, 300 } } The incoming payload looks like: { "intent": "book appointment", "confidence": 0.93, "slots": { "date": "2026-09-12", "time": "14:00", "duration": "30", "name": "Jane Doe", "phone": "+15551234567" } } Add a Function node after the webhook to merge date and time into an ISO-8601 string and compute the end time. js // Input: $json.slots const { date, time, duration } = $json.slots; const start = new Date ${date}T${time}:00Z ; const end = new Date start.getTime + Number duration 60000 ; return { json: { ...$json.slots, start iso: start.toISOString , end iso: end.toISOString } }; Add a Google Calendar node Operation: Create . Map fields: | Calendar field | Source | |---|---| | summary | {{ $json.name }} - Consultation | | description | "Booked via voice AI." | | start.dateTime | {{ $json.start iso }} | | end.dateTime | {{ $json.end iso }} | | attendees 0 .email | optional - if you collect email | | reminders.useDefault | false | | reminders.overrides 0 .method | popup | | reminders.overrides 0 .minutes | 10 | The node returns an id Google eventId we will need for reminders. Add a Twilio node Operation: Send SMS . {{ $json.phone }} Hi {{ $json.name }}, your appointment is confirmed for {{ $json.date }} at {{ $json.time }} {{ $json.duration }} min . Reply STOP to cancel. https://api.elevenlabs.io/v1/text-to-speech/{{ $env.ELEVENLABS VOICE ID }} xi-api-key: {{ $env.ELEVENLABS API KEY }} { "text": "Your appointment is booked for {{ $json.date }} at {{ $json.time }}. We will call you a day before as a reminder.", "voice settings": { "stability": 0.75, "similarity boost": 0.85 } } binary audio/mpeg . The node outputs an MP3 buffer; pipe it straight to Twilio Make Call node. Add a Twilio node Operation: Make Call .