ElevenLabs + Google Calendar, calls book themselves
Your phone rings, someone asks for “next Tuesday around five,” and suddenly you’re juggling calendars, time zones, and half-heard spelling over a noisy line. You try to be fast. But speed is where mistakes sneak in, and missed calls turn into lost bookings.
This is exactly what clinic managers and front-desk teams complain about, and honestly, service business owners feel it too. With voice booking automation, callers can book by conversation while your calendar stays accurate and confirmations go out automatically.
This workflow connects ElevenLabs to Google Calendar and Gmail, so availability checks and bookings happen without you touching the calendar. You’ll see what it does, what you need, and how the pieces fit together.
How This Automation Works
The full n8n workflow, from trigger to final output:
n8n Workflow Template: ElevenLabs + Google Calendar, calls book themselves
flowchart LR
subgraph sg0["Flow 1"]
direction LR
n0["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Webhook1"]
n1@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Available?1", pos: "b", h: 48 }
n2@{ icon: "mdi:location-exit", form: "rounded", label: "Check Availability Again", pos: "b", h: 48 }
n3@{ icon: "mdi:swap-vertical", form: "rounded", label: "Set Up Variables", pos: "b", h: 48 }
n4@{ icon: "mdi:location-exit", form: "rounded", label: "Book Appointment", pos: "b", h: 48 }
n5@{ icon: "mdi:location-exit", form: "rounded", label: "Get availability in a calendar", pos: "b", h: 48 }
n6@{ icon: "mdi:message-outline", form: "rounded", label: "Send a message", pos: "b", h: 48 }
n7["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Confirm Booking "]
n8["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Confirm Available Times"]
n9["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Sort Available Slots"]
n10@{ icon: "mdi:cog", form: "rounded", label: "Aggregate", pos: "b", h: 48 }
n11["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Confirm The Time's Unavailable"]
n12@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If", pos: "b", h: 48 }
n12 --> n5
n12 --> n4
n0 --> n3
n10 --> n11
n1 --> n8
n1 --> n2
n6 --> n7
n4 --> n6
n3 --> n12
n9 --> n10
n2 --> n9
n5 --> n1
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n1,n12 decision
class n0,n7,n8,n11 api
class n9 code
classDef customIcon fill:none,stroke:none
class n0,n7,n8,n9,n11 customIcon
The Problem: Phone Calls Don’t Scale Scheduling
Booking appointments by phone sounds simple until you do it all day. People ask for specific providers, locations, and services, then change their mind mid-sentence. You put them on hold, check the calendar, come back with options, and hope you didn’t miss a conflict. Meanwhile, new calls pile up, and the last thing you want is to double-book Dr. Sava at two locations at once. It’s stressful work, and it steals attention from the people already in your business.
It adds up fast. Here’s where it breaks down.
- A single “quick booking” can easily take about 10 minutes once you confirm service, location, email, and phone.
- Missed calls don’t wait for you to catch up, and many callers won’t leave a voicemail.
- Manual calendar checks lead to human errors, especially when you’re switching between screens and juggling multiple staff calendars.
- Confirmations get delayed or forgotten, which creates more reschedules and no-shows than you’d like to admit.
The Solution: Voice Calls That Check Availability and Book Automatically
This workflow turns an incoming voice assistant request into a real calendar action. It starts when ElevenLabs hits an n8n webhook with the caller’s details (service, location, date, time, name, email, phone). If the caller is only asking what’s open, the workflow checks Google Calendar, looks ahead across the next 30 days, and calculates conflict-free 30‑minute slots during your business hours. If the caller is ready to book, it creates the Google Calendar event with the right details and attendees, then sends a personalized confirmation email via Gmail. The caller gets an immediate spoken response back, so the conversation feels smooth instead of robotic.
The workflow begins with a webhook request from your ElevenLabs agent. Google Calendar handles conflict checks and event creation, while a small calculation step generates open time slots you can safely offer. Finally, Gmail sends the confirmation and n8n replies back to the voice agent so it can speak the result to the caller.
What You Get: Automation vs. Results
| What This Workflow Automates | Results You’ll Get |
|---|---|
|
|
Example: What This Looks Like
Say your front desk handles 12 booking-related calls a day, and each one takes about 10 minutes between calendar checks, collecting details, and sending a confirmation. That’s roughly 2 hours daily. With this workflow, the caller spends those 10 minutes talking to the agent, while your team does almost nothing beyond occasional exceptions. You get the bookings, the calendar events, and the emails without the back-and-forth.
What You’ll Need
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- ElevenLabs for the conversational voice agent.
- Google Calendar to check availability and create events.
- Gmail to send confirmation emails.
Skill level: Intermediate. You’ll connect accounts, paste a webhook URL into ElevenLabs, and tweak business hours and email text.
Don’t want to set this up yourself? Talk to an automation expert (free 15-minute consultation).
How It Works
A caller triggers the workflow via your voice agent. ElevenLabs sends a webhook request into n8n with the fields your agent collected, like date, time, location, and appointment type.
The request is cleaned up and routed. n8n maps the incoming fields into a consistent format, then decides if this is an “availability check” or a “book appointment” request based on which details are present.
Google Calendar does the hard truth check. For a specific time request, the workflow queries that slot and confirms there’s no conflict. If the time isn’t available, it looks up future events and computes open 30-minute slots during your business hours for the next 30 days.
Bookings and confirmations happen automatically. When it’s a booking request (or once the caller picks an open slot), n8n creates the Google Calendar event and sends a personalized confirmation email via Gmail, then returns a final response for the agent to speak.
You can easily modify business hours to include weekends based on your needs. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Webhook Trigger
Set up the inbound request that starts the booking flow and returns responses via response nodes.
- Add the Incoming Webhook Trigger node and set HTTP Method to
POST. - Set the Path to
2be0d61e-a2a0-48de-867e-4892849296b4. - Set Response Mode to
responseNodeso replies are sent by Return Availability Reply, Return Unavailable Notice, and Return Booking Reply.
Step 2: Connect Google Calendar
Authorize Google Calendar for all calendar operations used to check availability, list events, and create bookings.
- Open Query Calendar Slot and select the calendar to query. Credential Required: Connect your
googleCalendarOAuth2Apicredentials. - Open Lookup Future Events and select the calendar. Credential Required: Connect your
googleCalendarOAuth2Apicredentials. - Open Create Calendar Booking and select the calendar. Credential Required: Connect your
googleCalendarOAuth2Apicredentials.
Execution Flow: Route by Data Presence → Query Calendar Slot → Slot Availability Check determines if the requested time is available before proceeding.
Step 3: Set Up Input Mapping and Conditional Routing
Normalize incoming request fields and route to availability checks or booking creation based on required data.
- In Map Input Fields, add assignments for each input value. Examples: set fullName to
{{ $json.body.fullName }}, email to{{ $json.body.email }}, phone to{{ $json.body.phone }}, location to{{ $json.body.location }}, appointmentType to{{ $json.body.appointmentType }}, and date to{{ $json.body.date }} {{ $json.body.time }}. - In Route by Data Presence, confirm the OR conditions check for missing values with
{{ $json.fullName }}and{{ $json.email }}to route requests appropriately. - Ensure the flow connection is Incoming Webhook Trigger → Map Input Fields → Route by Data Presence.
⚠️ Common Pitfall: The Map Input Fields node contains duplicate assignments for appointmentType and location; make sure they match your incoming payload to avoid unexpected overwrites.
Step 4: Configure Availability Checks and Open Slot Discovery
Check a specific slot and, if needed, compute alternative open times over the next 30 days.
- In Query Calendar Slot, set timeMin to
{{ DateTime.fromFormat($('Map Input Fields').item.json.date, 'yyyy-MM-dd HH:mm').toISO({ suppressMilliseconds: true }) }}and timeMax to{{ DateTime.fromFormat($('Map Input Fields').item.json.date, 'yyyy-MM-dd HH:mm').plus({ minutes: 30 }).toISO({ suppressMilliseconds: true }) }}. - In Slot Availability Check, keep the condition
{{ $json.available }}set to true to branch on availability. - In Return Availability Reply, set Respond With to
textand Response Body to=Thank you for waiting! This time is available. - In Lookup Future Events, set Operation to
getAll, Return All totrue, timeMin to{{ $('Incoming Webhook Trigger').item.json.body.date }}, and timeMax to{{ DateTime.fromISO($('Incoming Webhook Trigger').item.json.body.date).plus({ days: 30 }).toISODate() }}. - In Compute Open Slots, keep the provided JavaScript Code to calculate 30 days of open 30-minute slots between 7:00 and 17:00 with a fixed
+02:00offset. - In Collect Open Times, aggregate the field available for output, then return the response via Return Unavailable Notice with Response Body set to
=Sorry, this time slot is unavailable right now. You may have another time in your mind?.
Step 5: Configure Booking Creation and Confirmation Email
Create the appointment in Google Calendar and send a confirmation email to the patient, then reply to the webhook.
- In Create Calendar Booking, set Start to
{{ DateTime.fromFormat($('Map Input Fields').item.json.date, 'yyyy-MM-dd HH:mm').toISO({ suppressMilliseconds: true }) }}and End to{{ DateTime.fromFormat($('Map Input Fields').item.json.date, 'yyyy-MM-dd HH:mm').plus({ minutes: 30 }).toISO({ suppressMilliseconds: true }) }}. - Configure Additional Fields in Create Calendar Booking with Summary set to
{{ $json.fullName }}, {{ $('Incoming Webhook Trigger').item.json.body.appointmentType }}, Location set to{{ $('Incoming Webhook Trigger').item.json.body.location }}, Attendees to{{ $('Incoming Webhook Trigger').item.json.body.email }}, and Description to{{ $json.fullName }} {{ $('Incoming Webhook Trigger').item.json.query.request }}. - Open Dispatch Confirmation Email and connect Gmail. Credential Required: Connect your
gmailOAuth2credentials. - In Dispatch Confirmation Email, keep the Subject and Message expressions so the date and appointment details render dynamically from
{{ $('Map Input Fields').item.json.date }}and{{ $('Map Input Fields').item.json.appointmentType }}. - Set Return Booking Reply to respond with
=Thank you. The appointment is scheduled on {{ ... }}to confirm the booking back to the caller.
Step 6: Test and Activate Your Workflow
Validate both availability and booking flows before enabling automation.
- Click Execute Workflow and send a POST request to the Incoming Webhook Trigger URL with a sample body containing
fullName,email,phone,location,appointmentType,date, andtime. - Confirm the availability path returns Return Availability Reply when a slot is free, and the open-slot path returns Return Unavailable Notice when it is not.
- For a booking, verify that Create Calendar Booking creates an event, Dispatch Confirmation Email sends the email, and Return Booking Reply returns the confirmation response.
- Toggle the workflow to Active when tests pass so it can accept live booking requests.
Common Gotchas
- Google Calendar credentials can expire or need specific permissions. If things break, check the connected Google account in n8n’s Credentials screen first.
- If you’re using Wait nodes or external rendering, processing times vary. Bump up the wait duration if downstream nodes fail on empty responses.
- Default prompts in AI nodes are generic. Add your brand voice early or you’ll be editing outputs forever.
Frequently Asked Questions
About an hour if your Google and ElevenLabs accounts are ready.
No. You’ll mostly connect accounts and edit business settings. The only “technical” part is copying a webhook URL into your ElevenLabs agent tools.
Yes. n8n has a free self-hosted option and a free trial on n8n Cloud. Cloud plans start at $20/month for higher volume. You’ll also need to factor in ElevenLabs usage costs for voice calls.
Two options: n8n Cloud (managed, easiest setup) or self-hosting on a VPS. For self-hosting, Hostinger VPS is affordable and handles n8n well. Self-hosting gives you unlimited executions but requires basic server management.
Yes, but you’ll want to be intentional about it. You can map “location” in the Map Input Fields step, then route to different calendars (or different event settings) before Create Calendar Booking runs. Common customizations include separate business hours per location, different appointment durations per service, and different confirmation email templates. If you keep it simple, start with one calendar per location.
Usually it’s expired Google authorization in n8n. Reconnect the Google Calendar credential, then re-test an availability check. If it still fails, confirm the calendar ID is correct and that the Google account has permission to read and create events on that calendar.
Plenty for most small teams. On n8n Cloud Starter, you’re mainly limited by monthly executions, while self-hosting depends on your server. In practice, this workflow handles one request per call, so capacity is usually about your voice provider limits and how busy your calendar queries get.
For voice scheduling, n8n is often the practical choice because you can handle branching logic (availability vs booking) and custom time-slot calculations in one place without awkward workarounds. Self-hosting is a big deal too if you’re volume-heavy or you want predictable costs. Zapier or Make can still work if you only need a very simple “create event then email” flow, but voice tools usually require a webhook-first design. If you’re on the fence, Talk to an automation expert and you’ll get a straight answer for your setup.
You set the rules once, and the workflow handles the repeatable stuff. That’s fewer missed calls, a cleaner calendar, and more bookings that don’t depend on someone being free to answer the phone.
Need Help Setting This Up?
Our automation experts can build and customize this workflow for your specific needs. Free 15-minute consultation—no commitment required.