This workflow corresponds to n8n.io template #6262 — we link there as the canonical source.
This workflow follows the Emailsend → HTTP Request recipe pattern — see all workflows that pair these two integrations.
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 →
{
"id": "zqOUjpxu04PO1idj",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Conversational Travel Booker: Automate Flight & Hotel Reservations with AI",
"tags": [],
"nodes": [
{
"id": "8b53e7e2-cedb-42a9-8918-3d7e8d0a23d1",
"name": "Webhook Trigger",
"type": "n8n-nodes-base.webhook",
"position": [
-660,
-80
],
"parameters": {
"path": "booking-request",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 1
},
{
"id": "16a396bd-3200-4be1-80d4-364d8a7a65e6",
"name": "AI Request Parser",
"type": "n8n-nodes-base.openAi",
"position": [
-440,
-80
],
"parameters": {
"model": "=gpt-3.5-turbo",
"prompt": "Hello",
"options": {
"temperature": 0.3
},
"requestOptions": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "d3d569ce-8e9b-4d88-ba84-e39f5cc41bf9",
"name": "Booking Type Router",
"type": "n8n-nodes-base.switch",
"position": [
-220,
-101
],
"parameters": {},
"typeVersion": 1
},
{
"id": "79041d5f-75e0-43e1-92be-486dcfb30847",
"name": "Flight Data Processor",
"type": "n8n-nodes-base.code",
"position": [
0,
-180
],
"parameters": {
"jsCode": "// Parse AI response and prepare flight search\nconst aiResponse = $input.first().json.choices[0].message.content;\nlet bookingData;\n\ntry {\n // Try to parse as JSON first\n bookingData = JSON.parse(aiResponse);\n} catch {\n // If not JSON, extract info from text\n bookingData = {\n type: 'flight',\n origin: extractValue(aiResponse, ['from', 'origin', 'departure']),\n destination: extractValue(aiResponse, ['to', 'destination', 'arrival']),\n departDate: extractValue(aiResponse, ['depart', 'departure date', 'leaving']),\n passengers: extractValue(aiResponse, ['passenger', 'traveler', 'people']) || 1\n };\n}\n\nfunction extractValue(text, keywords) {\n for (const keyword of keywords) {\n const regex = new RegExp(`${keyword}[:\\s]+([^\\n,]+)`, 'i');\n const match = text.match(regex);\n if (match) return match[1].trim();\n }\n return null;\n}\n\n// Prepare flight search parameters\nconst flightSearch = {\n origin: bookingData.origin || 'NYC',\n destination: bookingData.destination || 'LAX',\n departureDate: bookingData.departDate || new Date().toISOString().split('T')[0],\n passengers: parseInt(bookingData.passengers) || 1,\n class: bookingData.class || 'economy'\n};\n\nreturn { json: { bookingData, flightSearch, originalRequest: $input.first().json } };"
},
"typeVersion": 2
},
{
"id": "ac45ba1d-40a7-4f4e-98f6-ce3a17c94cbe",
"name": "Hotel Data Processor",
"type": "n8n-nodes-base.code",
"position": [
0,
20
],
"parameters": {
"jsCode": "// Parse AI response and prepare hotel search\nconst aiResponse = $input.first().json.choices[0].message.content;\nlet bookingData;\n\ntry {\n bookingData = JSON.parse(aiResponse);\n} catch {\n bookingData = {\n type: 'hotel',\n destination: extractValue(aiResponse, ['destination', 'city', 'location']),\n checkIn: extractValue(aiResponse, ['check in', 'arrival', 'checkin']),\n checkOut: extractValue(aiResponse, ['check out', 'departure', 'checkout']),\n guests: extractValue(aiResponse, ['guest', 'people', 'traveler']) || 2,\n rooms: extractValue(aiResponse, ['room']) || 1\n };\n}\n\nfunction extractValue(text, keywords) {\n for (const keyword of keywords) {\n const regex = new RegExp(`${keyword}[:\\s]+([^\\n,]+)`, 'i');\n const match = text.match(regex);\n if (match) return match[1].trim();\n }\n return null;\n}\n\n// Prepare hotel search parameters\nconst hotelSearch = {\n destination: bookingData.destination || 'New York',\n checkIn: bookingData.checkIn || new Date().toISOString().split('T')[0],\n checkOut: bookingData.checkOut || new Date(Date.now() + 86400000).toISOString().split('T')[0],\n guests: parseInt(bookingData.guests) || 2,\n rooms: parseInt(bookingData.rooms) || 1\n};\n\nreturn { json: { bookingData, hotelSearch, originalRequest: $input.first().json } };"
},
"typeVersion": 2
},
{
"id": "e9c34a77-e19b-4cf6-86ed-736b815c353f",
"name": "Flight Search API",
"type": "n8n-nodes-base.httpRequest",
"position": [
220,
-180
],
"parameters": {
"url": "https://api.aviationstack.com/v1/flights",
"options": {},
"sendQuery": true,
"authentication": "predefinedCredentialType",
"queryParameters": {
"parameters": [
{
"name": "dep_iata",
"value": "={{ $json.flightSearch.origin }}"
},
{
"name": "arr_iata",
"value": "={{ $json.flightSearch.destination }}"
},
{
"name": "limit",
"value": "5"
}
]
},
"nodeCredentialType": "aviationStackApi"
},
"typeVersion": 4.1
},
{
"id": "d49ce324-9a2b-4bb2-81db-a55f3977aa0d",
"name": "Hotel Search API",
"type": "n8n-nodes-base.httpRequest",
"position": [
220,
20
],
"parameters": {
"url": "https://api.booking.com/v1/hotels/search",
"options": {},
"sendQuery": true,
"authentication": "predefinedCredentialType",
"queryParameters": {
"parameters": [
{
"name": "dest_id",
"value": "={{ $json.hotelSearch.destination }}"
},
{
"name": "checkin_date",
"value": "={{ $json.hotelSearch.checkIn }}"
},
{
"name": "checkout_date",
"value": "={{ $json.hotelSearch.checkOut }}"
},
{
"name": "adults_number",
"value": "={{ $json.hotelSearch.guests }}"
},
{
"name": "room_number",
"value": "={{ $json.hotelSearch.rooms }}"
}
]
},
"nodeCredentialType": "bookingComApi"
},
"typeVersion": 4.1
},
{
"id": "0840d661-f296-4a66-94cc-4ee03dd30300",
"name": "Flight Booking Processor",
"type": "n8n-nodes-base.code",
"position": [
440,
-180
],
"parameters": {
"jsCode": "// Process flight search results and prepare booking\nconst searchResults = $input.first().json;\nconst bookingData = $input.first().json;\n\n// Mock flight results if API fails\nconst flights = searchResults.data || [\n {\n flight_number: 'AA123',\n airline: 'American Airlines',\n departure: { airport: bookingData.flightSearch?.origin || 'NYC', time: '09:00' },\n arrival: { airport: bookingData.flightSearch?.destination || 'LAX', time: '12:00' },\n price: 299,\n duration: '5h 30m'\n },\n {\n flight_number: 'DL456',\n airline: 'Delta Airlines', \n departure: { airport: bookingData.flightSearch?.origin || 'NYC', time: '14:00' },\n arrival: { airport: bookingData.flightSearch?.destination || 'LAX', time: '17:30' },\n price: 325,\n duration: '5h 30m'\n }\n];\n\n// Select best flight (lowest price)\nconst selectedFlight = flights.sort((a, b) => (a.price || 299) - (b.price || 325))[0];\n\n// Prepare booking confirmation\nconst booking = {\n type: 'flight',\n status: 'confirmed',\n confirmation: `FL${Date.now()}`,\n details: selectedFlight,\n passenger: {\n name: 'John Doe', // In real workflow, get from user data\n email: 'user@example.com'\n },\n total: selectedFlight.price || 299\n};\n\nreturn { json: { booking, searchResults: flights } };"
},
"typeVersion": 2
},
{
"id": "eb5d528a-6bd8-4546-8744-9ce2f0416ea4",
"name": "Hotel Booking Processor",
"type": "n8n-nodes-base.code",
"position": [
440,
20
],
"parameters": {
"jsCode": "// Process hotel search results and prepare booking\nconst searchResults = $input.first().json;\nconst bookingData = $input.first().json;\n\n// Mock hotel results if API fails\nconst hotels = searchResults.hotels || [\n {\n name: 'Grand Plaza Hotel',\n location: bookingData.hotelSearch?.destination || 'New York',\n rating: 4.5,\n price_per_night: 150,\n amenities: ['WiFi', 'Pool', 'Gym'],\n room_type: 'Deluxe Room'\n },\n {\n name: 'City Center Inn',\n location: bookingData.hotelSearch?.destination || 'New York',\n rating: 4.0,\n price_per_night: 120,\n amenities: ['WiFi', 'Breakfast'],\n room_type: 'Standard Room'\n }\n];\n\n// Select best hotel (highest rating)\nconst selectedHotel = hotels.sort((a, b) => (b.rating || 4) - (a.rating || 3.5))[0];\n\n// Calculate total nights\nconst checkIn = new Date(bookingData.hotelSearch?.checkIn || new Date());\nconst checkOut = new Date(bookingData.hotelSearch?.checkOut || new Date(Date.now() + 86400000));\nconst nights = Math.ceil((checkOut - checkIn) / (1000 * 60 * 60 * 24)) || 1;\n\n// Prepare booking confirmation\nconst booking = {\n type: 'hotel',\n status: 'confirmed',\n confirmation: `HT${Date.now()}`,\n details: selectedHotel,\n guest: {\n name: 'John Doe',\n email: 'user@example.com'\n },\n nights: nights,\n total: (selectedHotel.price_per_night || 120) * nights\n};\n\nreturn { json: { booking, searchResults: hotels } };"
},
"typeVersion": 2
},
{
"id": "ee741a63-77c7-4348-b62d-32150bdc4e4b",
"name": "Confirmation Message Generator",
"type": "n8n-nodes-base.openAi",
"position": [
660,
-80
],
"parameters": {
"model": "=gpt-3.5-turbo",
"prompt": "{{json.data}}",
"options": {
"temperature": 0.7
},
"requestOptions": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "45c5475b-31d2-4de8-b4b0-19acc57ef344",
"name": "Send Confirmation Email",
"type": "n8n-nodes-base.emailSend",
"position": [
880,
-80
],
"parameters": {
"text": "{{json.data}}",
"options": {
"allowUnauthorizedCerts": true
},
"subject": "\ud83c\udf89 Your Travel Booking is Confirmed!",
"toEmail": "user@example.com",
"fromEmail": "user@example.com"
},
"credentials": {
"smtp": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "1b362532-fb06-497b-9858-609d9ad6fa9b",
"name": "Send Response",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
1100,
-80
],
"parameters": {
"options": {},
"respondWith": "json",
"responseBody": {
"status": "success",
"booking": "{{ $('flight-booking-processor').item.json.booking || $('hotel-booking-processor').item.json.booking }}",
"message": "{{ $('confirmation-generator').item.json.choices[0].message.content }}",
"confirmation_code": "{{ $('flight-booking-processor').item.json.booking?.confirmation || $('hotel-booking-processor').item.json.booking?.confirmation }}"
}
},
"typeVersion": 1
},
{
"id": "6b6f2ebf-fda1-4a32-b8a3-5cb9525b4534",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-685,
-220
],
"parameters": {
"color": 5,
"width": 150,
"height": 300,
"content": "Accepts booking requests via HTTP POST"
},
"typeVersion": 1
},
{
"id": "3a6ac642-06a1-4c10-93ec-a8ef60ed7f1f",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
195,
-320
],
"parameters": {
"color": 4,
"width": 150,
"height": 520,
"content": " Searches for flights/hotels (with mock fallbacks)"
},
"typeVersion": 1
},
{
"id": "4c698f05-39a6-4369-88a4-8e92f43b1b18",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-25,
-320
],
"parameters": {
"color": 6,
"width": 150,
"height": 520,
"content": " Extracts and structures booking parameters"
},
"typeVersion": 1
},
{
"id": "8721b991-ce05-4244-84bf-237312498fbc",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-240,
-220
],
"parameters": {
"width": 150,
"height": 300,
"content": "Automatically determines if it's a flight or hotel booking"
},
"typeVersion": 1
},
{
"id": "b1d232d9-31f0-4f31-9a0b-9ea14ee31ab5",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-465,
-220
],
"parameters": {
"color": 3,
"width": 150,
"height": 300,
"content": " Uses OpenAI to understand natural language booking requests"
},
"typeVersion": 1
},
{
"id": "c001363a-c58c-406f-9cef-d7ad668fb071",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
855,
-220
],
"parameters": {
"color": 5,
"width": 150,
"height": 300,
"content": "Sends booking confirmations via email"
},
"typeVersion": 1
},
{
"id": "5d23d45e-23ab-45c8-8658-3a93ae8ec0c1",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
635,
-220
],
"parameters": {
"color": 2,
"width": 150,
"height": 300,
"content": "Creates personalized confirmation messages"
},
"typeVersion": 1
},
{
"id": "44b36b14-4353-45a1-894a-42596a2641fc",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
415,
-320
],
"parameters": {
"color": 3,
"width": 150,
"height": 520,
"content": "Processes and confirms bookings"
},
"typeVersion": 1
},
{
"id": "7588a845-8d92-4e8f-aa07-b454126f61f1",
"name": "Sticky Note11",
"type": "n8n-nodes-base.stickyNote",
"position": [
1075,
-220
],
"parameters": {
"color": 4,
"width": 150,
"height": 300,
"content": "Returns structured booking data"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "62307eb8-de4c-41a1-aa27-7efc27a9f954",
"connections": {
"Webhook Trigger": {
"main": [
[
{
"node": "AI Request Parser",
"type": "main",
"index": 0
}
]
]
},
"Hotel Search API": {
"main": [
[
{
"node": "Hotel Booking Processor",
"type": "main",
"index": 0
}
]
]
},
"AI Request Parser": {
"main": [
[
{
"node": "Booking Type Router",
"type": "main",
"index": 0
}
]
]
},
"Flight Search API": {
"main": [
[
{
"node": "Flight Booking Processor",
"type": "main",
"index": 0
}
]
]
},
"Booking Type Router": {
"main": [
[
{
"node": "Flight Data Processor",
"type": "main",
"index": 0
}
],
[
{
"node": "Hotel Data Processor",
"type": "main",
"index": 0
}
]
]
},
"Hotel Data Processor": {
"main": [
[
{
"node": "Hotel Search API",
"type": "main",
"index": 0
}
]
]
},
"Flight Data Processor": {
"main": [
[
{
"node": "Flight Search API",
"type": "main",
"index": 0
}
]
]
},
"Hotel Booking Processor": {
"main": [
[
{
"node": "Confirmation Message Generator",
"type": "main",
"index": 0
}
]
]
},
"Send Confirmation Email": {
"main": [
[
{
"node": "Send Response",
"type": "main",
"index": 0
}
]
]
},
"Flight Booking Processor": {
"main": [
[
{
"node": "Confirmation Message Generator",
"type": "main",
"index": 0
}
]
]
},
"Confirmation Message Generator": {
"main": [
[
{
"node": "Send Confirmation Email",
"type": "main",
"index": 0
}
]
]
}
}
}
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.
openAiApismtp
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This guide walks you through setting up an AI-driven workflow to automate flight and hotel reservation processes using a conversational travel booking system. The workflow accepts booking requests, processes them via APIs, and sends confirmations, enabling a seamless travel…
Source: https://n8n.io/workflows/6262/ — 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.
Watch on Youtube▶️
Automatically detects missed Zoom demos booked via Calendly and triggers AI-powered follow-up sequences.
Consulting firms in strategy, management, or IT who want to automate client onboarding and internal task assignment.
Send-Outreach. Uses postgres, openAi, httpRequest, emailSend. Webhook trigger; 15 nodes.
AI Resume Screening Workflow. Uses openAi, emailSend, httpRequest, postgres. Webhook trigger; 14 nodes.