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": "Book Appointment",
"nodes": [
{
"parameters": {
"path": "book_appointment",
"httpMethod": "POST",
"responseMode": "responseNode",
"options": {}
},
"id": "webhook-1",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [
250,
300
]
},
{
"parameters": {
"jsCode": "// n8n webhook may put POST body in $json.body or at root level\nconst data = $json.body || $json;\n\n// Get integration from _integrations object (keyed by integration type)\nconst integrations = data._integrations || {};\nconst integration = integrations.booking_api;\n\nif (!data.date || !data.time) {\n return {\n _error: true,\n success: false,\n message: 'Date and time are required for booking. Please provide when you would like to make a reservation.'\n };\n}\n\nif (!integration || !integration.apiUrl) {\n return {\n _error: true,\n success: false,\n message: 'No API integration configured for this client. Please set up a booking_api integration in the admin panel.',\n debug: { hasIntegrations: !!data._integrations, keys: Object.keys(integrations) }\n };\n}\n\n// Use full URL from integration (no path appending needed)\nlet apiUrl = integration.apiUrl;\n\n// Prepare API call config\nreturn {\n date: data.date,\n time: data.time,\n serviceType: data.serviceType || 'Table Reservation',\n customerName: data.customerName || 'Guest',\n customerEmail: data.customerEmail || '',\n customerPhone: data.customerPhone || '',\n partySize: data.partySize || 2,\n notes: data.notes || '',\n _apiConfig: {\n url: apiUrl,\n key: integration.apiKey,\n method: integration.method || 'POST',\n authMethod: integration.authMethod || 'bearer'\n }\n};"
},
"id": "prepare-request",
"name": "Prepare API Request",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
450,
300
]
},
{
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{ $json._error }}",
"value2": true
}
]
}
},
"id": "if-error",
"name": "Has Error?",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
650,
300
]
},
{
"parameters": {
"method": "={{ $json._apiConfig.method }}",
"url": "={{ $json._apiConfig.url }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "=Bearer {{ $json._apiConfig.key }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"date\": \"{{ $json.date }}\",\n \"time\": \"{{ $json.time }}\",\n \"serviceType\": \"{{ $json.serviceType }}\",\n \"customerName\": \"{{ $json.customerName }}\",\n \"customerEmail\": \"{{ $json.customerEmail }}\",\n \"customerPhone\": \"{{ $json.customerPhone }}\",\n \"partySize\": {{ $json.partySize }},\n \"notes\": \"{{ $json.notes }}\"\n}",
"options": {
"response": {
"response": {
"responseFormat": "json",
"fullResponse": true,
"neverError": true
}
},
"timeout": 10000
}
},
"id": "http-api-call",
"name": "Call Client API",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
900,
400
]
},
{
"parameters": {
"jsCode": "// Extract response from HTTP Request node\n// n8n HTTP Request with fullResponse: true returns { statusCode, body, headers, ... }\n// With neverError: true, we get the response even for error status codes\nconst response = $json.body || $json;\nconst statusCode = $json.statusCode || $json.status || 200;\n\n// Check if this is an error response (4xx or 5xx)\nif (statusCode >= 400) {\n // For error responses, return the error message from the API\n // The API should return { success: false, error: '...', message: '...' }\n return {\n success: false,\n error: response.error || response.message || `API returned status ${statusCode}`,\n message: response.message || response.error || `Request failed with status ${statusCode}`,\n statusCode: statusCode,\n ...(response.availableTimes && { availableTimes: response.availableTimes }),\n ...(response.data && { data: response.data })\n };\n}\n\n// For successful responses (2xx), return the response as-is\nreturn response;"
},
"id": "handle-response",
"name": "Handle Response",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1000,
400
]
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ JSON.stringify($json) }}"
},
"id": "respond-error",
"name": "Return Error",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
900,
200
]
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ JSON.stringify($json) }}"
},
"id": "respond-success",
"name": "Return Result",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
1100,
400
]
}
],
"connections": {
"Webhook": {
"main": [
[
{
"node": "Prepare API Request",
"type": "main",
"index": 0
}
]
]
},
"Prepare API Request": {
"main": [
[
{
"node": "Has Error?",
"type": "main",
"index": 0
}
]
]
},
"Has Error?": {
"main": [
[
{
"node": "Return Error",
"type": "main",
"index": 0
}
],
[
{
"node": "Call Client API",
"type": "main",
"index": 0
}
]
]
},
"Call Client API": {
"main": [
[
{
"node": "Handle Response",
"type": "main",
"index": 0
}
]
]
},
"Handle Response": {
"main": [
[
{
"node": "Return Result",
"type": "main",
"index": 0
}
]
]
}
},
"active": true,
"settings": {},
"versionId": "4",
"id": "book_appointment"
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Book Appointment. Uses httpRequest. Webhook trigger; 7 nodes.
Source: https://github.com/TropoEU/CSAIProj/blob/45562ba7faf947f8be6511dba03245871bc8d5e1/n8n-workflows/book_appointment.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.
This n8n template provides enterprise-level version control for your workflows using GitHub integration. Stop losing hours to broken workflows and manual exports – get proper commit history, visual di
This flow creates dummy files for every item added in your *Arrs (Radarr/Sonarr) with the tag .
eek-Go v2 (Batch-Then-Review). Uses httpRequest. Webhook trigger; 75 nodes.
This workflow receives webhook requests from a content calendar and uses the X API v2 to publish text posts, threads, image/video posts, and polls, as well as delete existing posts and run a credentia
This workflow acts as a central API gateway for all technical indicator agents in the Binance Spot Market Quant AI system. It listens for incoming webhook requests and dynamically routes them to the c