The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "AI Receptionist - Vapi Webhook",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "vapi-receptionist",
"responseMode": "responseNode",
"options": {}
},
"id": "3c193697-0c81-48cb-87eb-5926c8925862",
"name": "Webhook (Vapi Tool Call)",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
-560,
272
]
},
{
"parameters": {
"jsCode": "// Vapi sends: { message: { toolCalls: [ { id, function: { name, arguments } } ] } }\nconst body = $input.first().json.body;\nconst call = body.message?.toolCalls?.[0] || body.toolCalls?.[0];\nif (!call) {\n throw new Error('No toolCalls found in payload');\n}\n\nlet args = call.function.arguments;\nif (typeof args === 'string') {\n try { args = JSON.parse(args); } catch (e) { args = {}; }\n}\n\nreturn [{\n json: {\n toolCallId: call.id,\n toolName: call.function.name,\n name: args.name || '',\n phone: args.phone || '',\n service: args.service || '',\n date: args.date || '',\n time: args.time || ''\n }\n}];"
},
"id": "8f8cfb5c-f922-4eb4-a310-e3c94f263086",
"name": "Parse Tool Call",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-336,
272
]
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 1
},
"conditions": [
{
"leftValue": "={{$json.toolName}}",
"rightValue": "check_availability",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
}
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 1
},
"conditions": [
{
"leftValue": "={{$json.toolName}}",
"rightValue": "book_appointment",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
}
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 1
},
"conditions": [
{
"leftValue": "={{$json.toolName}}",
"rightValue": "lookup_appointment",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
}
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 1
},
"conditions": [
{
"leftValue": "={{$json.toolName}}",
"rightValue": "cancel_appointment",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
}
}
]
},
"options": {}
},
"id": "2f7ece4f-806c-408d-a580-75944a8a4e88",
"name": "Route by Tool Name",
"type": "n8n-nodes-base.switch",
"typeVersion": 3,
"position": [
-112,
272
]
},
{
"parameters": {
"documentId": {
"__rl": true,
"value": "YOUR_GOOGLE_SHEET_ID_HERE",
"mode": "list",
"cachedResultName": "Appointments_Template",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID_HERE/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": 506913772,
"mode": "list",
"cachedResultName": "Appointments",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID_HERE/edit#gid=506913772"
},
"filtersUI": {
"values": [
{
"lookupColumn": "date",
"lookupValue": "={{$json.date}}"
}
]
},
"options": {}
},
"id": "fe7b9d7e-0274-4869-94a4-bc55e45326be",
"name": "Get Bookings For Date",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
128,
0
],
"alwaysOutputData": true,
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// Compare fixed business slots vs already-booked rows for the date\nconst allSlots = ['09:00','10:00','11:00','12:00','14:00','15:00','16:00','17:00'];\nconst booked = $input.all().map(i => i.json.Time).filter(Boolean);\nconst free = allSlots.filter(s => !booked.includes(s));\n\nconst toolCallId = $('Parse Tool Call').first().json.toolCallId;\n\nreturn [{\n json: {\n results: [{\n toolCallId,\n result: free.length\n ? `Available slots: ${free.join(', ')}`\n : 'No slots available for that date, please pick another day.'\n }]\n }\n}];"
},
"id": "189ae8ce-be95-4b00-95b1-8ea83d3b7427",
"name": "Build Availability Reply",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
352,
0
]
},
{
"parameters": {
"operation": "append",
"documentId": {
"__rl": true,
"value": "YOUR_GOOGLE_SHEET_ID_HERE",
"mode": "list",
"cachedResultName": "Appointments_Template",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID_HERE/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": 506913772,
"mode": "list",
"cachedResultName": "Appointments",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID_HERE/edit#gid=506913772"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"name": "={{$json.name}}",
"phone": "={{$json.phone}}",
"service": "={{$json.service}}",
"time": "={{$json.time}}",
"date": "={{$json.date}}",
"Status": "Booked"
},
"matchingColumns": [],
"schema": [
{
"id": "toolCallId",
"displayName": "toolCallId",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "toolName",
"displayName": "toolName",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "name",
"displayName": "name",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "phone",
"displayName": "phone",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "service",
"displayName": "service",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "time",
"displayName": "time",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "date",
"displayName": "date",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "Status",
"displayName": "Status",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {}
},
"id": "fcb3cb49-0010-41bc-baac-5f7b1e22eb1f",
"name": "Append Booking Row",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
128,
192
],
"alwaysOutputData": true,
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const t = $('Parse Tool Call').first().json;\nreturn [{\n json: {\n results: [{\n toolCallId: t.toolCallId,\n result: `Booked ${t.service || 'appointment'} for ${t.name} on ${t.date} at ${t.time}. Confirmation sent.`\n }]\n }\n}];"
},
"id": "f8afe849-e48c-4493-bd3c-3c21ab1ca5c9",
"name": "Build Booking Reply",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
352,
192
]
},
{
"parameters": {
"documentId": {
"__rl": true,
"value": "YOUR_GOOGLE_SHEET_ID_HERE",
"mode": "list",
"cachedResultName": "Appointments_Template",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID_HERE/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": 506913772,
"mode": "list",
"cachedResultName": "Appointments",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID_HERE/edit#gid=506913772"
},
"filtersUI": {
"values": [
{
"lookupColumn": "phone",
"lookupValue": "={{$json.phone}}"
}
]
},
"options": {}
},
"id": "7f19ad8e-9b49-4530-a503-854161e47c1a",
"name": "Find Appointments By Phone",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
128,
368
],
"alwaysOutputData": true,
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const rows = $input.all().map(i => i.json).filter(r => r.Status !== 'Cancelled');\nconst toolCallId = $('Parse Tool Call').first().json.toolCallId;\n\nlet result;\nif (!rows.length) {\n result = 'No upcoming appointment found for that number.';\n} else {\n result = rows.map(r => `${r.Service} on ${r.Date} at ${r.Time} (Status: ${r.Status})`).join('; ');\n}\n\nreturn [{ json: { results: [{ toolCallId, result }] } }];"
},
"id": "cd00d015-a6d4-47fe-bcf6-e53b05f62c34",
"name": "Build Lookup Reply",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
352,
368
]
},
{
"parameters": {
"operation": "update",
"documentId": {
"__rl": true,
"value": "YOUR_GOOGLE_SHEET_ID_HERE",
"mode": "list",
"cachedResultName": "Appointments_Template",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID_HERE/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": 506913772,
"mode": "list",
"cachedResultName": "Appointments",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID_HERE/edit#gid=506913772"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"Status": "Cancelled",
"row_number": "={{$json.row_number}}"
},
"matchingColumns": [
"row_number"
],
"schema": [
{
"id": "toolCallId",
"displayName": "toolCallId",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "toolName",
"displayName": "toolName",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "name",
"displayName": "name",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "phone",
"displayName": "phone",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "service",
"displayName": "service",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "time",
"displayName": "time",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "date",
"displayName": "date",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "Status",
"displayName": "Status",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "row_number",
"displayName": "row_number",
"required": false,
"defaultMatch": false,
"display": true,
"type": "number",
"canBeUsedToMatch": true,
"readOnly": true,
"removed": false
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {}
},
"id": "8b42e7ba-d802-4ae8-a0ab-85aa7492aa61",
"name": "Mark Row Cancelled",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
352,
544
],
"alwaysOutputData": true,
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const t = $('Parse Tool Call').first().json;\nconst matched = $input.all().length > 0;\nreturn [{\n json: {\n results: [{\n toolCallId: t.toolCallId,\n result: matched\n ? `Your appointment on ${t.date} has been cancelled.`\n : `I couldn't find an appointment on ${t.date} for that number.`\n }]\n }\n}];"
},
"id": "3550a85c-4f8a-4f55-8e3e-f505c233541f",
"name": "Build Cancel Reply",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
576,
544
]
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{$json}}",
"options": {}
},
"id": "da87ef7a-a2d5-4363-a56d-95049a7f0c6e",
"name": "Respond to Vapi",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.1,
"position": [
800,
272
]
},
{
"parameters": {
"documentId": {
"__rl": true,
"value": "YOUR_GOOGLE_SHEET_ID_HERE",
"mode": "list",
"cachedResultName": "Appointments_Template",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID_HERE/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": 506913772,
"mode": "list",
"cachedResultName": "Appointments",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID_HERE/edit#gid=506913772"
},
"filtersUI": {
"values": [
{
"lookupColumn": "phone",
"lookupValue": "={{$json.phone}}"
},
{
"lookupColumn": "date",
"lookupValue": "={{$json.date}}"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.7,
"position": [
128,
544
],
"id": "480a0d9c-a946-4ed6-8284-7c84ad83af3d",
"name": "Find Row To Cancel",
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
}
],
"connections": {
"Webhook (Vapi Tool Call)": {
"main": [
[
{
"node": "Parse Tool Call",
"type": "main",
"index": 0
}
]
]
},
"Parse Tool Call": {
"main": [
[
{
"node": "Route by Tool Name",
"type": "main",
"index": 0
}
]
]
},
"Route by Tool Name": {
"main": [
[
{
"node": "Get Bookings For Date",
"type": "main",
"index": 0
}
],
[
{
"node": "Append Booking Row",
"type": "main",
"index": 0
}
],
[
{
"node": "Find Appointments By Phone",
"type": "main",
"index": 0
}
],
[
{
"node": "Find Row To Cancel",
"type": "main",
"index": 0
}
]
]
},
"Get Bookings For Date": {
"main": [
[
{
"node": "Build Availability Reply",
"type": "main",
"index": 0
}
]
]
},
"Build Availability Reply": {
"main": [
[
{
"node": "Respond to Vapi",
"type": "main",
"index": 0
}
]
]
},
"Append Booking Row": {
"main": [
[
{
"node": "Build Booking Reply",
"type": "main",
"index": 0
}
]
]
},
"Build Booking Reply": {
"main": [
[
{
"node": "Respond to Vapi",
"type": "main",
"index": 0
}
]
]
},
"Find Appointments By Phone": {
"main": [
[
{
"node": "Build Lookup Reply",
"type": "main",
"index": 0
}
]
]
},
"Build Lookup Reply": {
"main": [
[
{
"node": "Respond to Vapi",
"type": "main",
"index": 0
}
]
]
},
"Mark Row Cancelled": {
"main": [
[
{
"node": "Build Cancel Reply",
"type": "main",
"index": 0
}
]
]
},
"Build Cancel Reply": {
"main": [
[
{
"node": "Respond to Vapi",
"type": "main",
"index": 0
}
]
]
},
"Find Row To Cancel": {
"main": [
[
{
"node": "Mark Row Cancelled",
"type": "main",
"index": 0
}
]
]
}
},
"active": true,
"settings": {
"executionOrder": "v1",
"binaryMode": "separate",
"availableInMCP": false
},
"versionId": "6d686090-5027-49f5-a4d3-6dc6691ae1ae",
"meta": {
"templateCredsSetupCompleted": false
},
"nodeGroups": [],
"id": "ylnIeDHgtkqwVE0b",
"tags": []
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
googleSheetsOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
AI Receptionist - Vapi Webhook. Uses googleSheets. Webhook trigger; 13 nodes.
Source: https://github.com/aabdullahnadeem/Hercules-ai-receptionist/blob/main/AI_Receptionist_Vapi_Webhook.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Resume Screening & Behavioral Interviews with Gemini, Elevenlabs, & Notion ATS copy. Uses googleDrive, httpRequest, notion, formTrigger. Webhook trigger; 67 nodes.
[SANTOBET] FLUXO TODO - BACKUP. Uses googleSheets, httpRequest, googleSheetsTrigger. Webhook trigger; 57 nodes.
This workflow sends post-purchase review request emails for WooCommerce orders, stores expiring form links in Google Sheets, optionally shortens links with Dub.co and delays delivery, serves a hosted
FLUXO DISPARO DATA E HORA. Uses itemLists, googleSheets, httpRequest. Webhook trigger; 48 nodes.
This workflow allows you to accept online payments via YooKassa and log both orders and transactions in Google Sheets — all without writing a single line of code. It supports full payment flow: produc