This workflow follows the HTTP Request → Itemlists 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 →
{
"name": "Lodge Lead Engine",
"nodes": [
{
"parameters": {},
"id": "trigger",
"name": "Manual Trigger",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
200,
300
]
},
{
"parameters": {
"values": {
"number": [
{
"name": "page",
"value": 1
},
{
"name": "per_page",
"value": 25
}
],
"string": [
{
"name": "keywords",
"value": "fishing lodge"
}
]
},
"options": {}
},
"id": "config",
"name": "Config",
"type": "n8n-nodes-base.set",
"typeVersion": 3,
"position": [
420,
300
]
},
{
"parameters": {
"method": "POST",
"url": "https://api.apollo.io/api/v1/mixed_people/search",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "Cache-Control",
"value": "no-cache"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"q_keywords\": \"{{$json.keywords}}\",\n \"person_titles\": [\"owner\", \"general manager\", \"president\", \"founder\", \"proprietor\"],\n \"person_locations\": [\"United States\"],\n \"organization_num_employees_ranges\": [\"1,10\", \"11,20\", \"21,50\"],\n \"page\": {{$json.page}},\n \"per_page\": {{$json.per_page}}\n}",
"options": {}
},
"id": "apollo",
"name": "Apollo: Search Lodges",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
640,
300
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"fieldToSplitOut": "people",
"options": {}
},
"id": "split",
"name": "Split People",
"type": "n8n-nodes-base.itemLists",
"typeVersion": 3,
"position": [
860,
300
]
},
{
"parameters": {
"jsCode": "// Normalize one Apollo person into a lead shape and fetch their site\nconst p = $json;\nconst org = p.organization || {};\nconst website = org.website_url || (org.primary_domain ? `https://${org.primary_domain}` : null);\n\nif (!website || !p.email) {\n return { json: { skip: true, reason: 'no website or email', person: p } };\n}\n\nlet html = '';\nlet detected = [];\nlet fetchError = null;\ntry {\n const res = await this.helpers.httpRequest({\n method: 'GET',\n url: website,\n timeout: 15000,\n returnFullResponse: false,\n headers: { 'User-Agent': 'Mozilla/5.0 (compatible; LodgeQualifier/1.0)' }\n });\n html = (typeof res === 'string' ? res : JSON.stringify(res)).toLowerCase();\n} catch (e) {\n fetchError = e.message;\n}\n\nconst signatures = {\n checkfront: ['checkfront.com', 'cfwidget'],\n resnexus: ['resnexus.com'],\n fareharbor: ['fareharbor.com', 'fh-button'],\n bookeo: ['bookeo.com'],\n cloudbeds: ['cloudbeds.com', 'mybookings.cloudbeds'],\n lodgify: ['lodgify.com'],\n thinkres: ['thinkreservations.com'],\n innroad: ['innroad.com'],\n rezdy: ['rezdy.com'],\n peek: ['peekpro.com', 'bookwithpeek'],\n webrez: ['webrezpro.com'],\n resharmonics:['resharmonics.com'],\n};\nfor (const [name, needles] of Object.entries(signatures)) {\n if (needles.some(n => html.includes(n))) detected.push(name);\n}\n\nconst booking_widget_detected = detected.length > 0;\n\nreturn {\n json: {\n skip: false,\n business_name: org.name || p.name || 'Unknown',\n contact_name: p.name || null,\n email: p.email,\n phone: org.phone || null,\n city: p.city || org.city || null,\n state: p.state || org.state || null,\n website,\n booking_widget_detected,\n detected_widgets: detected,\n fetch_error: fetchError,\n html_snippet: html.slice(0, 3000),\n title: p.title || null,\n source: 'apollo+n8n'\n }\n};"
},
"id": "qualify",
"name": "Fetch Site + Detect Widgets",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1080,
300
]
},
{
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{$json.skip}}",
"value2": false
},
{
"value1": "={{$json.booking_widget_detected}}",
"value2": false
}
]
}
},
"id": "filter",
"name": "Qualified (No Widget)",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
1300,
300
]
},
{
"parameters": {
"resource": "message",
"modelId": {
"mode": "list",
"value": "claude-sonnet-4-6"
},
"messages": {
"values": [
{
"role": "user",
"content": "=You are writing ONE opening sentence for a cold email to a fishing lodge owner.\n\nBusiness: {{$json.business_name}}\nLocation: {{$json.city}}, {{$json.state}}\nWebsite text snippet: {{$json.html_snippet}}\n\nWrite a single sentence (under 25 words) that feels personal and specific to their lodge. Reference something real from the snippet \u2014 a species, a lake, a guide, an experience. Do NOT mention websites, booking, software, or sales. Just a warm opener. Output only the sentence, no quotes, no prefix."
}
]
},
"options": {
"maxTokens": 100
}
},
"id": "personalize",
"name": "Claude: Personalize",
"type": "@n8n/n8n-nodes-langchain.anthropic",
"typeVersion": 1,
"position": [
1520,
240
],
"credentials": {
"anthropicApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// Attach personalization line back onto the lead and strip the html_snippet\nconst lead = $('Qualified (No Widget)').item.json;\nconst line = ($json.content?.[0]?.text || $json.text || '').trim();\nreturn {\n json: {\n business_name: lead.business_name,\n contact_name: lead.contact_name,\n email: lead.email,\n phone: lead.phone,\n city: lead.city,\n state: lead.state,\n website: lead.website,\n booking_widget_detected: lead.booking_widget_detected,\n detected_widgets: lead.detected_widgets,\n personalization_line: line,\n source: lead.source\n }\n};"
},
"id": "shape",
"name": "Shape Lead",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1740,
240
]
},
{
"parameters": {
"aggregate": "aggregateAllItemData",
"destinationFieldName": "leads",
"options": {}
},
"id": "aggregate",
"name": "Aggregate to Batch",
"type": "n8n-nodes-base.itemLists",
"typeVersion": 3,
"position": [
1960,
240
]
},
{
"parameters": {
"method": "POST",
"url": "https://crm.twenty1-media.com/api/leads/ingest",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ leads: $json.leads }) }}",
"options": {}
},
"id": "ingest",
"name": "POST to CRM /api/leads/ingest",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2180,
240
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
}
],
"connections": {
"Manual Trigger": {
"main": [
[
{
"node": "Config",
"type": "main",
"index": 0
}
]
]
},
"Config": {
"main": [
[
{
"node": "Apollo: Search Lodges",
"type": "main",
"index": 0
}
]
]
},
"Apollo: Search Lodges": {
"main": [
[
{
"node": "Split People",
"type": "main",
"index": 0
}
]
]
},
"Split People": {
"main": [
[
{
"node": "Fetch Site + Detect Widgets",
"type": "main",
"index": 0
}
]
]
},
"Fetch Site + Detect Widgets": {
"main": [
[
{
"node": "Qualified (No Widget)",
"type": "main",
"index": 0
}
]
]
},
"Qualified (No Widget)": {
"main": [
[
{
"node": "Claude: Personalize",
"type": "main",
"index": 0
}
],
[]
]
},
"Claude: Personalize": {
"main": [
[
{
"node": "Shape Lead",
"type": "main",
"index": 0
}
]
]
},
"Shape Lead": {
"main": [
[
{
"node": "Aggregate to Batch",
"type": "main",
"index": 0
}
]
]
},
"Aggregate to Batch": {
"main": [
[
{
"node": "POST to CRM /api/leads/ingest",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
}
}
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.
anthropicApihttpHeaderAuth
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Lodge Lead Engine. Uses httpRequest, itemLists, anthropic. Event-driven trigger; 10 nodes.
Source: https://github.com/Isaac-Walden21/twenty1-crm/blob/9c78ed02caabd53b48df0e8f250ca9f60adeb254/n8n/lodge-lead-engine.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.
Goal: This workflow demonstrates the full fluidX THE EYE integration — starting a live session, inviting both the customer (via SMS) and the service agent (via email), and then accessing the media (ph
This n8n workflow automatically generates a comprehensive dataset of 50 AI search prompts tailored to a specific company.
Triggered by a GitLab MR webhook, this workflow automatically assists your team in writing customer-facing release notes by combining Linear issue data with Claude AI.
The competitive edge, delivered. This Customer Intelligence Engine simultaneously analyzes the web, Reddit, and X/Twitter to generate a professional, actionable executive briefing.
Your Cold Email is Now Researched. This pipeline finds specific bottlenecks on prospect websites and instantly crafts an irresistible pitch