This workflow corresponds to n8n.io template #16274 — we link there as the canonical source.
This workflow follows the Form → Form Trigger 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 →
{
"meta": {
"templateCredsSetupCompleted": false
},
"name": "AI Real Estate Buyer and Seller Lead Router with Claude",
"tags": [],
"nodes": [
{
"id": "d3e4f5a6-0010-4000-8000-000000000001",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-368,
48
],
"parameters": {
"width": 480,
"height": 896,
"content": "## AI Real Estate Buyer and Seller Lead Router with Claude\n\n### How it works\n\nThis workflow serves a hosted lead-capture form, normalizes the inquiry, and sends it to Claude to classify whether the person is a buyer, seller, renter, or investor, judge their timeline and readiness, score the lead, and flag financing status. Ready leads trigger an alert to the assigned agent and a row in an active-leads Google Sheet, while early-stage leads are logged to a separate nurture tab. Every submitter receives a friendly confirmation page.\n\n### Setup steps\n\n- Open the Receive Lead Submission node and adjust the form title, description, and fields to match your market.\n- Configure an HTTP Header Auth credential for Anthropic with header name x-api-key and value sk-ant-... and attach it to the Analyze Lead node.\n- Connect Gmail credentials and set the agent recipient on the Dispatch Agent Alert node.\n- Connect Google Sheets credentials and create a spreadsheet with two tabs, then replace the placeholder sheet ID in both append nodes.\n- Review the scoring, timeline, and financing rules in the Analyze Lead prompt and tune them to your team.\n- Activate the workflow and share the production form URL on your site and listing pages.\n\n### Customization\n\nEdit the form fields and the Claude rubric to fit buyers only, sellers only, or both. Change the ready-lead threshold, route buyers and sellers to different agent inboxes, swap Gmail for Slack or SMS, or push hot leads into a CRM in parallel with the Google Sheets log."
},
"typeVersion": 1
},
{
"id": "d3e4f5a6-0010-4000-8000-000000000002",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
192,
144
],
"parameters": {
"color": 7,
"width": 416,
"height": 336,
"content": "## Receive and normalize lead\n\nServes a hosted lead-capture form and standardizes the inquiry: name, contact, intent, budget, timeline, area, and notes for downstream processing."
},
"typeVersion": 1
},
{
"id": "d3e4f5a6-0010-4000-8000-000000000003",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
640,
160
],
"parameters": {
"color": 7,
"width": 416,
"height": 320,
"content": "## Classify and parse lead\n\nSends the normalized lead to Claude to determine buyer or seller intent, timeline, financing readiness, and a score, then parses the JSON response and merges it back into the lead data."
},
"typeVersion": 1
},
{
"id": "d3e4f5a6-0010-4000-8000-000000000004",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1104,
48
],
"parameters": {
"color": 7,
"width": 640,
"height": 576,
"content": "## Route ready leads\n\nEvaluates whether the lead is ready to transact, then routes the result: alerting the assigned agent and logging active leads, or logging early-stage leads to a separate nurture tab."
},
"typeVersion": 1
},
{
"id": "d3e4f5a6-0010-4000-8000-000000000005",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1776,
144
],
"parameters": {
"color": 7,
"width": 240,
"height": 336,
"content": "## Confirm to submitter\n\nReturns a friendly confirmation page to the lead after the routed handling path completes."
},
"typeVersion": 1
},
{
"id": "d3e4f5a6-0010-4000-8000-000000000006",
"name": "Receive Lead Submission",
"type": "n8n-nodes-base.formTrigger",
"position": [
240,
320
],
"parameters": {
"options": {},
"formTitle": "Find Your Next Move",
"formFields": {
"values": [
{
"fieldType": "text",
"fieldLabel": "Full Name",
"requiredField": true
},
{
"fieldType": "email",
"fieldLabel": "Email",
"requiredField": true
},
{
"fieldType": "text",
"fieldLabel": "Phone"
},
{
"fieldType": "dropdown",
"fieldLabel": "I Am Looking To",
"fieldOptions": {
"values": [
{
"option": "Buy a home"
},
{
"option": "Sell my home"
},
{
"option": "Both buy and sell"
},
{
"option": "Rent"
},
{
"option": "Invest"
}
]
},
"requiredField": true
},
{
"fieldType": "text",
"fieldLabel": "Area or Neighborhood"
},
{
"fieldType": "text",
"fieldLabel": "Budget or Target Price"
},
{
"fieldType": "dropdown",
"fieldLabel": "Ideal Timeline",
"fieldOptions": {
"values": [
{
"option": "ASAP"
},
{
"option": "1 to 3 months"
},
{
"option": "3 to 6 months"
},
{
"option": "6 to 12 months"
},
{
"option": "Just exploring"
}
]
}
},
{
"fieldType": "dropdown",
"fieldLabel": "Financing Status",
"fieldOptions": {
"values": [
{
"option": "Pre-approved"
},
{
"option": "Need a lender"
},
{
"option": "Paying cash"
},
{
"option": "Not sure"
},
{
"option": "Not applicable"
}
]
}
},
{
"fieldType": "textarea",
"fieldLabel": "Anything Else We Should Know"
}
]
},
"responseMode": "responseNode",
"formDescription": "Tell us what you are looking for and a local agent will reach out. No obligation."
},
"typeVersion": 2.2
},
{
"id": "d3e4f5a6-0010-4000-8000-000000000007",
"name": "Set Lead Fields",
"type": "n8n-nodes-base.set",
"position": [
460,
320
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "l1-name",
"name": "fullName",
"type": "string",
"value": "={{ ($json['Full Name'] || '').toString().trim() }}"
},
{
"id": "l2-email",
"name": "email",
"type": "string",
"value": "={{ ($json['Email'] || '').toString().trim().toLowerCase() }}"
},
{
"id": "l3-phone",
"name": "phone",
"type": "string",
"value": "={{ ($json['Phone'] || '').toString().trim() }}"
},
{
"id": "l4-intent",
"name": "intentRaw",
"type": "string",
"value": "={{ ($json['I Am Looking To'] || '').toString().trim() }}"
},
{
"id": "l5-area",
"name": "area",
"type": "string",
"value": "={{ ($json['Area or Neighborhood'] || '').toString().trim() }}"
},
{
"id": "l6-budget",
"name": "budget",
"type": "string",
"value": "={{ ($json['Budget or Target Price'] || '').toString().trim() }}"
},
{
"id": "l7-timeline",
"name": "timeline",
"type": "string",
"value": "={{ ($json['Ideal Timeline'] || '').toString().trim() }}"
},
{
"id": "l8-financing",
"name": "financing",
"type": "string",
"value": "={{ ($json['Financing Status'] || '').toString().trim() }}"
},
{
"id": "l9-notes",
"name": "notes",
"type": "string",
"value": "={{ ($json['Anything Else We Should Know'] || '').toString().trim() }}"
},
{
"id": "l10-timestamp",
"name": "timestamp",
"type": "string",
"value": "={{ $now.toISO() }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "d3e4f5a6-0010-4000-8000-000000000008",
"name": "Analyze Lead with Claude",
"type": "n8n-nodes-base.httpRequest",
"position": [
680,
320
],
"parameters": {
"url": "https://api.anthropic.com/v1/messages",
"method": "POST",
"options": {},
"jsonBody": "={\n \"model\": \"claude-sonnet-4-6\",\n \"max_tokens\": 1024,\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"You are an intake coordinator at a residential real estate team. Analyze the lead and reply with valid JSON only, no markdown fences, no commentary. Use this exact schema:\\n\\n{\\n \\\"lead_type\\\": \\\"buyer|seller|buyer_seller|renter|investor|unknown\\\",\\n \\\"summary\\\": \\\"<one sentence summary of what they want>\\\",\\n \\\"score\\\": <integer 1-10>,\\n \\\"is_ready\\\": <true or false>,\\n \\\"timeline_band\\\": \\\"immediate|near_term|long_term|exploring\\\",\\n \\\"financing_ready\\\": <true or false>,\\n \\\"recommended_agent_role\\\": \\\"<buyer agent, listing agent, rental specialist, or investor specialist>\\\",\\n \\\"suggested_next_step\\\": \\\"<one concrete first action for the agent>\\\",\\n \\\"missing_info\\\": [\\\"<key fact still needed>\\\"]\\n}\\n\\nScoring rules:\\n- 8-10: clear intent, near-term timeline, financing in place or cash, specific area or price.\\n- 5-7: real interest but a longer timeline or missing financing detail.\\n- 1-4: vague, just exploring, spam, or out of area.\\nis_ready is true when score is 7 or higher. financing_ready is true when the lead is pre-approved or paying cash, or financing is not applicable to a seller. Treat sellers as financing_ready true.\\n\\nLEAD:\\nLooking to: \" + {{ JSON.stringify($json.intentRaw) }} + \"\\nArea: \" + {{ JSON.stringify($json.area) }} + \"\\nBudget or target price: \" + {{ JSON.stringify($json.budget) }} + \"\\nTimeline: \" + {{ JSON.stringify($json.timeline) }} + \"\\nFinancing: \" + {{ JSON.stringify($json.financing) }} + \"\\nName: \" + {{ JSON.stringify($json.fullName) }} + \"\\nNotes: \" + {{ JSON.stringify($json.notes) }}\n }\n ]\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"headerParameters": {
"parameters": [
{
"name": "anthropic-version",
"value": "2023-06-01"
},
{
"name": "content-type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "d3e4f5a6-0010-4000-8000-000000000009",
"name": "Parse Lead Classification",
"type": "n8n-nodes-base.code",
"position": [
900,
320
],
"parameters": {
"jsCode": "// Parse the Claude response and merge it with the original lead fields\nconst lead = $('Set Lead Fields').item.json;\nconst raw = $json.content?.[0]?.text || '{}';\n\nlet parsed = {\n lead_type: 'unknown',\n summary: 'Failed to parse AI response',\n score: 0,\n is_ready: false,\n timeline_band: 'exploring',\n financing_ready: false,\n recommended_agent_role: 'Intake review',\n suggested_next_step: 'Review manually',\n missing_info: []\n};\n\ntry {\n const cleaned = raw.replace(/^```(?:json)?\\s*/i, '').replace(/\\s*```\\s*$/i, '').trim();\n parsed = JSON.parse(cleaned);\n parsed.score = Math.max(1, Math.min(10, parseInt(parsed.score, 10) || 0));\n} catch (e) {\n parsed.summary = 'AI returned malformed JSON: ' + raw.slice(0, 200);\n}\n\nconst isReady = parsed.is_ready === true || parsed.score >= 7;\nconst missingInfo = Array.isArray(parsed.missing_info) ? parsed.missing_info.join(' | ') : '';\n\nreturn [{\n json: {\n ...lead,\n lead_type: parsed.lead_type || 'unknown',\n summary: parsed.summary || '',\n score: parsed.score,\n is_ready: isReady,\n isReady,\n timeline_band: parsed.timeline_band || 'exploring',\n financing_ready: parsed.financing_ready === true,\n recommended_agent_role: parsed.recommended_agent_role || 'Intake review',\n suggested_next_step: parsed.suggested_next_step || '',\n missing_info: missingInfo\n }\n}];"
},
"typeVersion": 2
},
{
"id": "d3e4f5a6-0010-4000-8000-000000000010",
"name": "Evaluate Lead Readiness",
"type": "n8n-nodes-base.if",
"position": [
1152,
320
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "cond-ready",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.isReady }}",
"rightValue": true
}
]
}
},
"typeVersion": 2.2
},
{
"id": "d3e4f5a6-0010-4000-8000-000000000011",
"name": "Dispatch Agent Alert",
"type": "n8n-nodes-base.gmail",
"position": [
1376,
208
],
"parameters": {
"sendTo": "you@example.com",
"message": "=<h2>New ready lead - {{ $json.lead_type }}</h2>\n<p><b>Score:</b> {{ $json.score }}/10 · <b>Timeline:</b> {{ $json.timeline_band }}<br>\n<b>Route to:</b> {{ $json.recommended_agent_role }}<br>\n<b>Financing ready:</b> {{ $json.financing_ready ? 'yes' : 'no' }}</p>\n<p><b>{{ $json.fullName }}</b><br>\n{{ $json.email }}{{ $json.phone ? ' · ' + $json.phone : '' }}</p>\n<p><b>Area:</b> {{ $json.area || '(not provided)' }}<br>\n<b>Budget / price:</b> {{ $json.budget || '(not provided)' }}<br>\n<b>Stated financing:</b> {{ $json.financing || '(not provided)' }}</p>\n<p><b>Summary:</b> {{ $json.summary }}</p>\n<p><b>Suggested next step:</b> {{ $json.suggested_next_step }}</p>\n{{ $json.notes ? '<p><b>Their notes:</b><br><blockquote>' + $json.notes + '</blockquote></p>' : '' }}\n{{ $json.missing_info ? '<p><b>Still needed:</b> ' + $json.missing_info + '</p>' : '' }}",
"options": {},
"subject": "=New {{ $json.lead_type }} lead ({{ $json.score }}/10) - {{ $json.fullName }}",
"emailType": "html"
},
"typeVersion": 2.1
},
{
"id": "d3e4f5a6-0010-4000-8000-000000000012",
"name": "Append to Active Leads",
"type": "n8n-nodes-base.googleSheets",
"position": [
1600,
208
],
"parameters": {
"columns": {
"value": {
"area": "={{ $json.area }}",
"email": "={{ $json.email }}",
"notes": "={{ $json.notes }}",
"phone": "={{ $json.phone }}",
"score": "={{ $json.score }}",
"budget": "={{ $json.budget }}",
"summary": "={{ $json.summary }}",
"fullName": "={{ $json.fullName }}",
"lead_type": "={{ $json.lead_type }}",
"timestamp": "={{ $json.timestamp }}",
"missing_info": "={{ $json.missing_info }}",
"timeline_band": "={{ $json.timeline_band }}",
"financing_ready": "={{ $json.financing_ready ? 'yes' : 'no' }}",
"suggested_next_step": "={{ $json.suggested_next_step }}",
"recommended_agent_role": "={{ $json.recommended_agent_role }}"
},
"schema": [
{
"id": "timestamp",
"type": "string",
"display": true,
"required": false,
"displayName": "timestamp",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "fullName",
"type": "string",
"display": true,
"required": false,
"displayName": "fullName",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "email",
"type": "string",
"display": true,
"required": false,
"displayName": "email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "phone",
"type": "string",
"display": true,
"required": false,
"displayName": "phone",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "lead_type",
"type": "string",
"display": true,
"required": false,
"displayName": "lead_type",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "score",
"type": "number",
"display": true,
"required": false,
"displayName": "score",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "timeline_band",
"type": "string",
"display": true,
"required": false,
"displayName": "timeline_band",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "financing_ready",
"type": "string",
"display": true,
"required": false,
"displayName": "financing_ready",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "recommended_agent_role",
"type": "string",
"display": true,
"required": false,
"displayName": "recommended_agent_role",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "area",
"type": "string",
"display": true,
"required": false,
"displayName": "area",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "budget",
"type": "string",
"display": true,
"required": false,
"displayName": "budget",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "summary",
"type": "string",
"display": true,
"required": false,
"displayName": "summary",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "suggested_next_step",
"type": "string",
"display": true,
"required": false,
"displayName": "suggested_next_step",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "missing_info",
"type": "string",
"display": true,
"required": false,
"displayName": "missing_info",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "notes",
"type": "string",
"display": true,
"required": false,
"displayName": "notes",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": []
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "Active Leads"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "REPLACE_WITH_YOUR_SHEET_ID"
}
},
"typeVersion": 4.5
},
{
"id": "d3e4f5a6-0010-4000-8000-000000000013",
"name": "Append to Nurture Leads",
"type": "n8n-nodes-base.googleSheets",
"position": [
1376,
464
],
"parameters": {
"columns": {
"value": {
"area": "={{ $json.area }}",
"email": "={{ $json.email }}",
"notes": "={{ $json.notes }}",
"phone": "={{ $json.phone }}",
"score": "={{ $json.score }}",
"budget": "={{ $json.budget }}",
"summary": "={{ $json.summary }}",
"fullName": "={{ $json.fullName }}",
"lead_type": "={{ $json.lead_type }}",
"timestamp": "={{ $json.timestamp }}",
"timeline_band": "={{ $json.timeline_band }}"
},
"schema": [
{
"id": "timestamp",
"type": "string",
"display": true,
"required": false,
"displayName": "timestamp",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "fullName",
"type": "string",
"display": true,
"required": false,
"displayName": "fullName",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "email",
"type": "string",
"display": true,
"required": false,
"displayName": "email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "phone",
"type": "string",
"display": true,
"required": false,
"displayName": "phone",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "lead_type",
"type": "string",
"display": true,
"required": false,
"displayName": "lead_type",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "score",
"type": "number",
"display": true,
"required": false,
"displayName": "score",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "timeline_band",
"type": "string",
"display": true,
"required": false,
"displayName": "timeline_band",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "area",
"type": "string",
"display": true,
"required": false,
"displayName": "area",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "budget",
"type": "string",
"display": true,
"required": false,
"displayName": "budget",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "summary",
"type": "string",
"display": true,
"required": false,
"displayName": "summary",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "notes",
"type": "string",
"display": true,
"required": false,
"displayName": "notes",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": []
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "Nurture Leads"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "REPLACE_WITH_YOUR_SHEET_ID"
}
},
"typeVersion": 4.5
},
{
"id": "d3e4f5a6-0010-4000-8000-000000000014",
"name": "Respond to Submitter",
"type": "n8n-nodes-base.form",
"position": [
1824,
320
],
"parameters": {
"options": {},
"operation": "completion",
"respondWith": "showText",
"completionTitle": "Thanks, we got your details",
"completionMessage": "A local agent will review what you are looking for and reach out shortly. Keep an eye on your inbox and phone."
},
"typeVersion": 1
}
],
"settings": {
"executionOrder": "v1"
},
"connections": {
"Set Lead Fields": {
"main": [
[
{
"node": "Analyze Lead with Claude",
"type": "main",
"index": 0
}
]
]
},
"Dispatch Agent Alert": {
"main": [
[
{
"node": "Respond to Submitter",
"type": "main",
"index": 0
}
]
]
},
"Append to Nurture Leads": {
"main": [
[
{
"node": "Respond to Submitter",
"type": "main",
"index": 0
}
]
]
},
"Evaluate Lead Readiness": {
"main": [
[
{
"node": "Dispatch Agent Alert",
"type": "main",
"index": 0
},
{
"node": "Append to Active Leads",
"type": "main",
"index": 0
}
],
[
{
"node": "Append to Nurture Leads",
"type": "main",
"index": 0
}
]
]
},
"Receive Lead Submission": {
"main": [
[
{
"node": "Set Lead Fields",
"type": "main",
"index": 0
}
]
]
},
"Analyze Lead with Claude": {
"main": [
[
{
"node": "Parse Lead Classification",
"type": "main",
"index": 0
}
]
]
},
"Parse Lead Classification": {
"main": [
[
{
"node": "Evaluate Lead Readiness",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow hosts an n8n lead-capture form, uses Anthropic Claude to score and classify real estate inquiries, then routes ready leads to Gmail and Google Sheets while logging early-stage leads to a separate Google Sheets tab. Receives a new submission from an n8n Form trigger…
Source: https://n8n.io/workflows/16274/ — 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 repository contains an SLA-based lead routing workflow built in n8n, designed to ensure fast lead response, fair sales distribution, and controlled escalation without relying on a full CRM system
Find companies similar to your best clients using PredictLeads, enrich each with news, hiring, and tech signals, then score them 0–100 for outreach priority.
This workflow collects business leads from Google Maps by geocoding a user-provided city, searching across a small coordinate grid with Places Nearby Search pagination, and writing enriched business d
This workflow runs a FindMyClient search for a keyword, polls for completion, and extracts any returned email addresses. If emails are found, it splits them into individual items for optional saving t
How it works A form trigger accepts an Industry + Location query (e.g. Accountants London). Text Search Page 1 calls Google Places Text Search to return results and a nextpagetoken. Conditional checks