Vapi + Google Calendar bookings with Gmail confirms
Your phone rings, someone asks for “next Tuesday,” you put them on hold, check the calendar, come back, and they’re gone. Or worse, you write it down, promise an email confirmation, then forget until the end of the day.
This Vapi Calendar booking setup hits busy practice managers and service business owners hardest. Consultants and coaches feel it too, just with different labels on the appointment types. The outcome is simple: fewer missed bookings, fewer double-bookings, and confirmations that go out automatically.
This workflow turns a natural voice conversation into a real Google Calendar event, then sends a Gmail confirmation. You’ll see how it works, what you need, and where people usually get tripped up.
How This Automation Works
The full n8n workflow, from trigger to final output:
n8n Workflow Template: Vapi + Google Calendar bookings with Gmail confirms
flowchart LR
subgraph sg0["Availability Analysi Flow"]
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/>Incoming Availability Webhook"]
n1["<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/>Reply Availability to Vapi"]
n2@{ icon: "mdi:location-exit", form: "rounded", label: "Fetch Calendar Busy Times", pos: "b", h: 48 }
n3@{ icon: "mdi:brain", form: "rounded", label: "Gemini Chat Engine", pos: "b", h: 48 }
n4["<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/>Format Occupied Times"]
n8@{ icon: "mdi:robot", form: "rounded", label: "Availability Analysis Agent", pos: "b", h: 48 }
n4 --> n8
n8 --> n1
n3 -.-> n8
n2 --> n4
n0 --> n2
end
subgraph sg1["Flow 2"]
direction LR
n5["<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/>Incoming Booking Webhook"]
n6["<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/>Send Booking Confirmation"]
n7@{ icon: "mdi:location-exit", form: "rounded", label: "Create Calendar Entry", pos: "b", h: 48 }
n9@{ icon: "mdi:message-outline", form: "rounded", label: "Dispatch Confirmation Email", pos: "b", h: 48 }
n7 --> n9
n9 --> n6
n5 --> n7
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 n8 ai
class n3 aiModel
class n0,n1,n5,n6 api
class n4 code
classDef customIcon fill:none,stroke:none
class n0,n1,n4,n5,n6 customIcon
The Problem: Appointment Booking Turns Into Back-and-Forth
Appointment scheduling looks easy until you’re doing it all day. People call when you’re in the middle of something, ask for availability in plain language, then change their mind twice. Meanwhile, your calendar is the source of truth, but it’s trapped behind a login and a human who has to interpret it. The cost isn’t only time. It’s interruptions, mistakes, and that nagging feeling that you’re always one slip away from a double-booking.
It adds up fast. Here’s where it breaks down in real businesses.
- Calls get missed after hours, which means bookings that never happen.
- Busy slots get read wrong, especially when timezones and lunch breaks are involved.
- “I’ll send a confirmation email” becomes another task, and honestly it’s the one that slips.
- Even one double-booked slot can cause refunds, awkward conversations, and a chaotic day.
The Solution: Voice Booking That Writes to Your Calendar
This n8n workflow gives your Vapi voice assistant two reliable “tools” it can call during a conversation: one to check availability and another to create the appointment. When a caller asks for open times on a specific date, Vapi hits an availability webhook. n8n pulls that day’s busy blocks from Google Calendar, cleans them up into readable time ranges, then asks an AI agent to identify realistic open windows based on your business hours. When the caller picks a slot and shares their details, Vapi calls the booking webhook. n8n creates the event in Google Calendar and immediately sends a professional confirmation email through Gmail, then returns a success message back to Vapi so the assistant can confirm it out loud.
The workflow starts with a Vapi-triggered webhook for either “check times” or “book it.” Google Calendar provides the schedule reality, the AI agent turns it into human-friendly options, and Gmail handles the written confirmation so customers aren’t guessing what they booked.
What You Get: Automation vs. Results
| What This Workflow Automates | Results You’ll Get |
|---|---|
|
|
Example: What This Looks Like
Say you book 8 appointments a day. Manually, a “quick call” often turns into about 10 minutes: check the calendar, propose times, write the event, send the email. That’s roughly 80 minutes daily. With this workflow, the caller gets options via Vapi, and once they confirm, n8n creates the event and sends Gmail automatically. Your effort becomes a quick review of the calendar, maybe 10 minutes total.
What You’ll Need
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Vapi for the voice assistant and tool calling
- Google Calendar to store availability and bookings
- Gmail to send confirmation emails automatically
- Google Gemini API key (get it from Google AI Studio)
Skill level: Intermediate. You’ll be comfortable connecting accounts and pasting webhook URLs into Vapi.
Don’t want to set this up yourself? Talk to an automation expert (free 15-minute consultation).
How It Works
Vapi triggers an “availability” webhook. When a caller asks for openings on a date, your assistant sends that date to n8n as a tool call.
Google Calendar is checked for busy blocks. n8n pulls the day’s occupied times, then formats them so they’re easy to reason about instead of a raw blob of timestamps.
An AI agent turns schedule data into options. The agent uses your business hours rules to identify open windows, then returns natural-language availability that Vapi can read back on the call.
Vapi triggers a “booking” webhook. After the caller picks a time and provides details like name, email, and appointment type, n8n creates the Calendar event and sends the Gmail confirmation.
You can easily modify appointment duration to match your service length 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 two inbound webhooks that power availability checks and appointment creation.
- Add and configure Incoming Availability Webhook with HTTP Method set to
POST, Path set toavailability-checker, and Response Mode set toresponseNode. - Add and configure Incoming Booking Webhook with HTTP Method set to
POST, Path set tocreate-appointment, and Response Mode set toresponseNode. - Copy each webhook’s production URL for your voice system to call.
Step 2: Connect Google Calendar
Configure the calendar lookups and appointment creation used by both webhook paths.
- Open Fetch Calendar Busy Times and select your calendar in the Calendar field.
- Set Time Min to
{{ $json.body.message.toolCalls[0].function.arguments.date.toDateTime().startOf('day') }}and Time Max to{{ $json.body.message.toolCalls[0].function.arguments.date.toDateTime().endOf('day') }}. - Credential Required: Connect your Google Calendar credentials in Fetch Calendar Busy Times.
- Open Create Calendar Entry and select the same calendar in the Calendar field.
- Set Start to
{{ $json.body.message.toolCalls[0].function.arguments["date and time"].toDateTime() }}and End to{{ $json.body.message.toolCalls[0].function.arguments["date and time"].toDateTime().plus(30, 'mins') }}. - Set Summary to
{{ $json.body.message.toolCalls[0].function.arguments["Appointment type"] }} Appointment for {{ $json.body.message.toolCalls[0].function.arguments.Name }}and Description toAppointment type: {{ $json.body.message.toolCalls[0].function.arguments["Appointment type"] }}.
Email: {{ $json.body.message.toolCalls[0].function.arguments.Email }} - Credential Required: Connect your Google Calendar credentials in Create Calendar Entry.
Step 3: Set Up the Availability Processing and AI Analysis
Format busy slots and use the AI agent to generate human-friendly availability windows.
- In Format Occupied Times, keep the JavaScript as provided to convert the calendar busy array into a readable list.
- Open Availability Analysis Agent and set Text to
These are the busy slots of the day: {{ $json.busySlots }}.
Here is the day for which the user is looking to book: {{ $('Incoming Availability Webhook').item.json.body.message.toolCalls[0].function.arguments.date }} - Confirm the system message under Options is the availability guidance for 9:00am–6:00pm.
- Ensure Gemini Chat Engine is connected as the language model for Availability Analysis Agent.
- Credential Required: Connect your Google Gemini credentials in Gemini Chat Engine (credentials should be added to the parent language model node, not the agent).
Step 4: Configure Booking Confirmation Actions
Send confirmation emails and respond to the booking webhook call.
- Open Dispatch Confirmation Email and set Send To to
{{ $('Incoming Booking Webhook').item.json.body.message.toolCalls[0].function.arguments.Email }}. - Set Subject to
Appointment Confirmation. - Set Message to the HTML template provided in the node, including the dynamic name, appointment type, and date/time expressions.
- Credential Required: Connect your Gmail credentials in Dispatch Confirmation Email.
- Open Send Booking Confirmation and keep the JSON response body so the calling system receives a confirmation message and tool call ID.
Step 5: Test and Activate Your Workflow
Validate both webhook paths end-to-end, then activate the workflow for production.
- Use Execute Workflow and send a POST request to Incoming Availability Webhook with a sample tool call payload that includes a
date. - Confirm the execution path runs Fetch Calendar Busy Times → Format Occupied Times → Availability Analysis Agent → Reply Availability to Vapi, returning a readable availability string.
- Send a POST request to Incoming Booking Webhook with
Name,Email,Appointment type, anddate and time. - Verify Create Calendar Entry creates the event, Dispatch Confirmation Email sends the email, and Send Booking Confirmation returns the success response.
- Toggle the workflow to Active once both paths succeed.
Common Gotchas
- Google Calendar credentials can expire or need specific permissions. If things break, check the n8n credential connection test and the selected calendar in both Calendar nodes first.
- If your AI availability reply feels “wrong,” it’s usually business hours text in the Availability Analysis Agent. Update the system message so it matches your actual hours, lunch breaks, and timezone.
- Gmail can silently fail when the sending account has security restrictions. Confirm the Gmail node is using the right inbox and that your Google account allows API access for sending.
Frequently Asked Questions
About an hour if your Google accounts are ready.
No. You’ll connect accounts in n8n and paste two webhook URLs into Vapi.
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 Google Gemini API usage costs, which depend on how many availability checks you run.
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. Change the default duration in the Google Calendar “Create Calendar Entry” node by updating the .plus(30, ‘mins’) expression. Common tweaks include setting different durations by appointment type, adding buffers between sessions, and adjusting the email wording so it matches each service.
Usually it’s expired or mis-scoped credentials in n8n. Reconnect the Google Calendar credential, then confirm both Calendar nodes are pointed at the same calendar and timezone. If it only fails during busy periods, you may be hitting Google API rate limits, so reduce parallel calls or add small delays.
A lot.
For voice booking, n8n is often the better fit because you can run two webhooks, add branching logic, and keep the “availability analysis” in one place without paying extra for every path. It also gives you the self-hosted option, which matters when call volume spikes. Zapier and Make are great for quick, linear automations, but voice flows rarely stay linear for long. Another point people miss is debugging: n8n makes it easier to inspect the exact payload Vapi sent and the exact Calendar response you received. Talk to an automation expert if you want help picking the simplest setup that still works under pressure.
Once this is live, bookings stop being a daily interruption and start being a background process. Set it up once, then let your calendar and confirmations take care of themselves.
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.