AutomationFlowsMarketing & Ads › Qualify Real Estate Leads and Send Instant Replies with Openai, Gmail, and…

Qualify Real Estate Leads and Send Instant Replies with Openai, Gmail, and…

Original n8n title: Qualify Real Estate Leads and Send Instant Replies with Openai, Gmail, and Google Sheets

BySoumyajit @soumya-dev on n8n.io

This workflow captures real estate leads via a webhook, uses an OpenAI-compatible Chat Completions API call to qualify and draft a reply, then sends emails through Gmail and logs the lead to Google Sheets. Receives a new lead submission via a POST webhook from a web form.…

Webhook trigger★★★★☆ complexity13 nodesHTTP RequestGmailGoogle Sheets
Marketing & Ads Trigger: Webhook Nodes: 13 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #16092 — we link there as the canonical source.

This workflow follows the Gmail → Google Sheets 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 →

Download .json
{
  "id": "0PCfE3TBU4QHOLJW",
  "name": "Real Estate Lead Capture & Instant AI Follow-Up",
  "tags": [],
  "nodes": [
    {
      "id": "578394e5-c49a-4298-8c7c-3841baf2826b",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        80,
        -48
      ],
      "parameters": {
        "width": 480,
        "height": 832,
        "content": "## Real Estate Lead Capture & Instant AI Follow-Up\n\n### How it works\n\nThis workflow captures a new real estate lead from a web form, enriches it with configured business and agent details, and standardizes the lead data. It then sends the lead context to an OpenAI-compatible AI service to generate an instant follow-up response and supporting agent summary. Finally, it emails the lead, notifies the agent, and logs the interaction to a Google Sheets-based CRM.\n\n### Setup steps\n\n- Configure the webhook endpoint and connect it to the lead capture form on the website.\n- Update the Settings node with the correct businessName, agentName, agentEmail, and bookingLink values.\n- Configure the AI request details, including the OpenAI-compatible endpoint URL, model, API key, and any required headers.\n- Connect Gmail credentials for both the lead reply and agent notification nodes.\n- Connect Google Sheets credentials and select the target spreadsheet and sheet for CRM logging.\n\n### Customization\n\nAdjust the normalization and AI prompt code to match the fields collected by the web form, the desired follow-up tone, qualification criteria, and CRM columns."
      },
      "typeVersion": 1
    },
    {
      "id": "7a4f0cc3-13df-49df-b98c-3a0cb8f0c6d5",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        640,
        224
      ],
      "parameters": {
        "color": 7,
        "width": 592,
        "height": 320,
        "content": "## Capture and prepare lead\n\nReceives a new real estate lead from the web form, applies business and agent settings, and normalizes the submitted lead details for downstream processing."
      },
      "typeVersion": 1
    },
    {
      "id": "94f940fc-ace5-40bd-8f90-437373086c3b",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1280,
        224
      ],
      "parameters": {
        "color": 7,
        "width": 592,
        "height": 320,
        "content": "## Generate AI follow-up\n\nBuilds the OpenAI-compatible request, sends the lead context to the AI endpoint, and parses the AI response into usable follow-up content and lead insights."
      },
      "typeVersion": 1
    },
    {
      "id": "a77f019a-900d-4280-a0c7-26e7d57aa9c5",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1920,
        -48
      ],
      "parameters": {
        "color": 7,
        "height": 768,
        "content": "## Send and record outcomes\n\nUses the parsed AI output to immediately email the lead, notify the agent, and log the lead plus follow-up details to a Google Sheets CRM."
      },
      "typeVersion": 1
    },
    {
      "id": "15110a04-2170-4a68-8d50-d2c27159bf19",
      "name": "When Lead Form Submitted",
      "type": "n8n-nodes-base.webhook",
      "position": [
        688,
        384
      ],
      "parameters": {
        "path": "realestate-lead",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2.1
    },
    {
      "id": "efea880d-241b-4035-93dc-e80ce7d109ad",
      "name": "Set Agent Details",
      "type": "n8n-nodes-base.set",
      "position": [
        896,
        384
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "13b764d7-c26c-438e-9c0c-e28b1fc4cd99",
              "name": "businessName",
              "type": "string",
              "value": "Sunrise Realty"
            },
            {
              "id": "c46aace0-7411-4cca-b1c8-9a89dee5dfcd",
              "name": "agentName",
              "type": "string",
              "value": "Alex"
            },
            {
              "id": "7c16bd8c-a130-433e-be2d-f660a95f9f53",
              "name": "agentEmail",
              "type": "string",
              "value": "user@example.com"
            },
            {
              "id": "bcaaf05e-6c36-4484-a5f4-168cbe4c2971",
              "name": "bookingLink",
              "type": "string",
              "value": "https://cal.com/your-link"
            },
            {
              "id": "cc87d037-8d8c-4980-8684-81ca70ed4fce",
              "name": "aiUrl",
              "type": "string",
              "value": "https://api.openai.com/v1/chat/completions"
            },
            {
              "id": "daef2bc1-ad46-44e0-932c-154c3a747d75",
              "name": "aiModel",
              "type": "string",
              "value": "gpt-4o-mini"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "733a944b-7536-41ca-8716-234d15a28553",
      "name": "Normalize Lead Data",
      "type": "n8n-nodes-base.code",
      "position": [
        1088,
        384
      ],
      "parameters": {
        "jsCode": "const j = $('When Lead Form Submitted').first().json;\nconst p = j.body || j;\nconst s = $('Set Agent Details').first().json;\nreturn [{ json: {\n  name: p.name || p.full_name || 'there',\n  email: p.email || '',\n  phone: p.phone || p.phone_number || '',\n  budget: p.budget || p.budget_range || '',\n  interest: p.interest || p.property_type || p.message || '',\n  timeline: p.timeline || '',\n  message: p.message || p.notes || '',\n  businessName: s.businessName, agentName: s.agentName, agentEmail: s.agentEmail,\n  bookingLink: s.bookingLink, aiUrl: s.aiUrl, aiModel: s.aiModel\n}}];"
      },
      "typeVersion": 2
    },
    {
      "id": "def0f3f2-63b2-47d2-be53-076844052aaf",
      "name": "Build AI Request Data",
      "type": "n8n-nodes-base.code",
      "position": [
        1328,
        384
      ],
      "parameters": {
        "jsCode": "const out = [];\nfor (const it of $input.all()) {\n  const j = it.json;\n  const prompt = 'You are the assistant for ' + j.businessName + ', a real estate agency. A new lead just came in. ' +\n    'First qualify them as HOT, WARM, or COLD from budget, timeline and intent. ' +\n    'Then write a warm, professional reply (4-6 sentences) from ' + (j.agentName || 'our team') + ' that thanks them, references their interest, answers helpfully, and invites them to book a viewing at this link: ' + j.bookingLink + '. ' +\n    'Return ONLY JSON with keys: score (HOT|WARM|COLD), reason (one line), replySubject, replyBody. ' +\n    'Lead -> name: ' + j.name + ', email: ' + j.email + ', phone: ' + j.phone + ', budget: ' + j.budget + ', interest: ' + j.interest + ', timeline: ' + j.timeline + ', message: ' + j.message;\n  const aiBody = JSON.stringify({ model: j.aiModel, messages: [{ role: 'user', content: prompt }], temperature: 0.5, stream: false, response_format: { type: 'json_object' } });\n  out.push({ json: { ...j, aiBody } });\n}\nreturn out;"
      },
      "typeVersion": 2
    },
    {
      "id": "d56682f9-0558-403f-890d-e280cf5a7573",
      "name": "Post to AI Endpoint",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "position": [
        1520,
        384
      ],
      "parameters": {
        "url": "={{ $json.aiUrl }}",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ $json.aiBody }}",
        "sendBody": true,
        "specifyBody": "json"
      },
      "typeVersion": 4.2
    },
    {
      "id": "c2a485ba-2f46-4535-a9be-3f10f44a5f7b",
      "name": "Parse AI Response",
      "type": "n8n-nodes-base.code",
      "position": [
        1728,
        384
      ],
      "parameters": {
        "jsCode": "const prep = $('Build AI Request Data').all();\nconst res = $input.all();\nconst out = [];\nfor (let i = 0; i < res.length; i++) {\n  let txt = '';\n  try { txt = res[i].json.choices[0].message.content; } catch (e) {}\n  let p = { score: 'WARM', reason: '', replySubject: 'Thanks for reaching out', replyBody: '' };\n  try { p = JSON.parse(txt); } catch (e) {}\n  const j = (prep[i] && prep[i].json) ? prep[i].json : {};\n  out.push({ json: { ...j, score: String(p.score || 'WARM').toUpperCase(), reason: p.reason || '', replySubject: p.replySubject || 'Thanks for reaching out', replyBody: p.replyBody || ('Hi ' + j.name + ', thanks for your interest! Book a viewing here: ' + j.bookingLink) } });\n}\nreturn out;"
      },
      "typeVersion": 2
    },
    {
      "id": "63ed2db7-c33b-45ec-8890-ed7bc87978c9",
      "name": "Send Email to Lead",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1968,
        208
      ],
      "parameters": {
        "sendTo": "={{ $json.email }}",
        "message": "={{ $json.replyBody }}",
        "options": {},
        "subject": "={{ $json.replySubject }}",
        "emailType": "text"
      },
      "typeVersion": 2.2
    },
    {
      "id": "e547ddca-4625-4602-b636-1c009611daaa",
      "name": "Notify Agent via Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1968,
        384
      ],
      "parameters": {
        "sendTo": "={{ $json.agentEmail }}",
        "message": "=A new lead just came in:\n\nName: {{ $json.name }}\nEmail: {{ $json.email }}\nPhone: {{ $json.phone }}\nBudget: {{ $json.budget }}\nInterest: {{ $json.interest }}\nTimeline: {{ $json.timeline }}\n\nAI verdict: {{ $json.score }} - {{ $json.reason }}",
        "options": {},
        "subject": "=\ud83c\udfe1 New {{ $json.score }} lead: {{ $json.name }}",
        "emailType": "text"
      },
      "typeVersion": 2.2
    },
    {
      "id": "1931e138-1733-40d9-8ddd-acb4a01bdad1",
      "name": "Log Details in CRM Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "onError": "continueRegularOutput",
      "position": [
        1968,
        560
      ],
      "parameters": {
        "columns": {
          "value": {
            "name": "={{ $json.name }}",
            "email": "={{ $json.email }}",
            "phone": "={{ $json.phone }}",
            "score": "={{ $json.score }}",
            "budget": "={{ $json.budget }}",
            "reason": "={{ $json.reason }}",
            "interest": "={{ $json.interest }}",
            "timeline": "={{ $json.timeline }}"
          },
          "schema": [
            {
              "id": "name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "name",
              "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": "budget",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "budget",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "interest",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "interest",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "timeline",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "timeline",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "score",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "score",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "reason",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "reason",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": []
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Leads"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "PASTE_YOUR_GOOGLE_SHEET_URL"
        }
      },
      "typeVersion": 4.7
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "060f9db3-2c31-46e4-80e0-12431109964f",
  "connections": {
    "Parse AI Response": {
      "main": [
        [
          {
            "node": "Send Email to Lead",
            "type": "main",
            "index": 0
          },
          {
            "node": "Notify Agent via Email",
            "type": "main",
            "index": 0
          },
          {
            "node": "Log Details in CRM Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Agent Details": {
      "main": [
        [
          {
            "node": "Normalize Lead Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Lead Data": {
      "main": [
        [
          {
            "node": "Build AI Request Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post to AI Endpoint": {
      "main": [
        [
          {
            "node": "Parse AI Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build AI Request Data": {
      "main": [
        [
          {
            "node": "Post to AI Endpoint",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When Lead Form Submitted": {
      "main": [
        [
          {
            "node": "Set Agent Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow captures real estate leads via a webhook, uses an OpenAI-compatible Chat Completions API call to qualify and draft a reply, then sends emails through Gmail and logs the lead to Google Sheets. Receives a new lead submission via a POST webhook from a web form.…

Source: https://n8n.io/workflows/16092/ — original creator credit. Request a take-down →

More Marketing & Ads workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Marketing & Ads

Ad agencies needing automated lead capture. Sales teams fighting fraud and scoring leads. B2B SaaS companies nurturing prospects. Marketing pros boosting sales pipelines. Captures leads via Webhook fr

HTTP Request, Google Sheets, Slack +2
Marketing & Ads

This workflow captures shoe-shopping leads via a Tally form webhook, matches products from Google Sheets, uses a local Llama model (Ollama HTTP API) to score the lead and draft recommendations, then e

Google Sheets, HTTP Request, Gmail +1
Marketing & Ads

This workflow captures real estate property inquiries via a webhook, validates and normalizes lead details, upserts the lead into Google Sheets, sends an auto-reply through Gmail, and notifies your te

Google Sheets, Gmail, Slack +1
Marketing & Ads

This workflow captures real estate property inquiries via a webhook, saves the lead to Google Sheets, sends an auto-reply email through Gmail, and posts a notification to a Slack channel before return

Google Sheets, Gmail, Slack +1
Marketing & Ads

Lead Capture & CRM Automation. Uses slack, googleSheets, gmail. Webhook trigger; 14 nodes.

Slack, Google Sheets, Gmail