AutomationFlowsCRM & Sales › Automated Property Lead Generation with Batchdata and CRM Integration

Automated Property Lead Generation with Batchdata and CRM Integration

ByPreston Zeller @zellerhaus on n8n.io

How It Works This N8N workflow creates an automated system for discovering high-potential real estate investment opportunities. The workflow runs on a customizable schedule to scan the market for properties that match your specific criteria, then alerts your team about the most…

Event trigger★★★★☆ complexity17 nodesHTTP RequestSpreadsheet FileHubSpotEmail Send
CRM & Sales Trigger: Event Nodes: 17 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #3665 — 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 →

Download .json
{
  "id": "RGVS0tHJV7Wh6aX4",
  "name": "Property Lead Contact Enrichment from CRM",
  "tags": [],
  "nodes": [
    {
      "id": "518b14de-23b9-4821-930c-8fa55eb4cfb4",
      "name": "When clicking \"Execute Workflow\"",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -340,
        280
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "939df2a3-f6dd-40c9-a01a-460923a332a6",
      "name": "Daily Schedule",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -340,
        100
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "3228372f-ac40-4898-8bf5-09a4f37fde85",
      "name": "Search Properties API",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        320,
        260
      ],
      "parameters": {
        "url": "https://api.batchdata.com/api/v1/property/search",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"searchCriteria\": {\n    \"query\": \"{{ $json.city }}, {{ $json.state }}\",\n    \"quickList\": \"{{ $json.quicklist }}\",\n    \"valuation\": {\n      \"estimatedValue\":{\"min\": {{ $json.minValue }}, \"max\": {{ $json.maxValue }}},\n      \"equityPercent\":{\"min\": {{ $json.equityMin }}} \n    },\n    \"general\": {\n      \"propertyTypeDetail\": {\"equals\": \"{{ $json.propertyType }}\"}\n    }\n  },\n  \"options\": {\n    \"skip\": 0,\n    \"take\": {{ $json.propertiesToTake }}\n    }\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer {{ $json.APIkey }}"
            }
          ]
        }
      },
      "typeVersion": 4.1
    },
    {
      "id": "0aa1fb95-66c8-4b61-81f5-04b37e5c1185",
      "name": "Configure Search Parameters",
      "type": "n8n-nodes-base.set",
      "position": [
        40,
        240
      ],
      "parameters": {
        "values": {
          "string": [
            {
              "name": "city",
              "value": "=Austin"
            },
            {
              "name": "state",
              "value": "Texas"
            },
            {
              "name": "propertyType",
              "value": "Single Family"
            },
            {
              "name": "minValue",
              "value": "200000"
            },
            {
              "name": "maxValue",
              "value": "500000"
            },
            {
              "name": "quicklist",
              "value": "out-of-state-owner"
            },
            {
              "name": "equityMin",
              "value": "30"
            },
            {
              "name": "propertiesToTake",
              "value": "2"
            },
            {
              "name": "APIkey",
              "value": "YOUR_AWS_SECRET_KEY_HERE"
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 2
    },
    {
      "id": "2c183cc1-06a1-4528-82c3-df2585df58eb",
      "name": "Get Owner Contact Info",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        800,
        220
      ],
      "parameters": {
        "url": "https://api.batchdata.com/api/v1/property/skip-trace",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"requests\": [\n    {\n      \"propertyAddress\": {\n        \"street\": \"{{ $json.address.street }}\",\n        \"city\": \"{{ $json.address.city }}\",\n        \"state\": \"{{ $json.address.state }}\"\n      }\n    }\n  ]\n} ",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer {{ $('Configure Search Parameters').item.json.APIkey }}"
            }
          ]
        }
      },
      "typeVersion": 4.1
    },
    {
      "id": "2fe0aef9-30d2-4c30-9029-571f3b4c8ca9",
      "name": "Format Lead Data",
      "type": "n8n-nodes-base.code",
      "position": [
        980,
        300
      ],
      "parameters": {
        "jsCode": "const output = [];\n\n$input.all().forEach(item => {\n  const persons = ((item.json.results || {}).persons) || [];\n  persons.forEach(person => {\n    // Owner info\n    const owner_name = `${person.name.first || \"\"} ${person.name.middle || \"\"} ${person.name.last || \"\"}`.trim();\n    const property = person.property || {};\n    const propAddress = person.propertyAddress || {};\n    const mailing = person.mailingAddress || {};\n\n    // Property meta\n    const property_id = property.id || \"\";\n    const address = propAddress.street || \"\";\n    const city = propAddress.city || \"\";\n    const state = propAddress.state || \"\";\n    const zip = propAddress.zip || \"\";\n\n    // Property info\n    const absentee_owner = (property.absenteeOwner === true) ? \"Yes\" : \"No\";\n    const equity = property.equity || \"\";\n    const equity_percent = property.equityPercent || \"\";\n    const owner_mailing_address = mailing.street || \"\";\n    const owner_mailing_city = mailing.city || \"\";\n    const owner_mailing_state = mailing.state || \"\";\n    const owner_mailing_zip = mailing.zip || \"\";\n\n    // Create row object with basic info\n    const row = {\n      owner_name,\n      property_id,\n      address,\n      city,\n      state,\n      zip,\n      absentee_owner,\n      equity,\n      equity_percent,\n      owner_mailing_address,\n      owner_mailing_city,\n      owner_mailing_state,\n      owner_mailing_zip,\n      lead_source: 'BatchData Property Search',\n      date_added: new Date().toISOString().split('T')[0]\n    };\n\n    // Add phones as phone_1, phone_2, etc.\n    (person.phoneNumbers || []).forEach((phone, idx) => {\n      const n = idx + 1;\n      row[`phone_${n}`] = phone.number;\n      row[`phone_${n}_type`] = phone.type;\n      row[`phone_${n}_carrier`] = phone.carrier;\n      row[`phone_${n}_tested`] = phone.tested ? \"Yes\" : \"No\";\n      row[`phone_${n}_reachable`] = phone.reachable ? \"Yes\" : \"No\";\n      row[`phone_${n}_dnc`] = phone.dnc ? \"Yes\" : \"No\";\n      row[`phone_${n}_last_reported`] = phone.lastReportedDate;\n      row[`phone_${n}_score`] = phone.score;\n    });\n\n    // Add emails as email_1, email_2, etc.\n    (person.emails || []).forEach((email, idx) => {\n      const n = idx + 1;\n      row[`email_${n}`] = email.address || email;\n    });\n\n    output.push(row);\n  });\n});\n\nreturn output.map(row => ({ json: row }));\n"
      },
      "typeVersion": 2
    },
    {
      "id": "013469c2-1e83-44e0-b078-c0b3d052a2c5",
      "name": "Create Excel Spreadsheet",
      "type": "n8n-nodes-base.spreadsheetFile",
      "position": [
        1320,
        160
      ],
      "parameters": {
        "options": {
          "fileName": "=Property_Leads_BatchData_{{ $now.format('LL/dd/yyyy') }}.xlsx",
          "headerRow": true
        },
        "operation": "toFile",
        "fileFormat": "xlsx"
      },
      "typeVersion": 2
    },
    {
      "id": "954c492a-7da2-4902-99ab-318d4ea6e333",
      "name": "Push to CRM",
      "type": "n8n-nodes-base.hubspot",
      "position": [
        1320,
        540
      ],
      "parameters": {
        "email": "=$json[\"email\"]",
        "options": {},
        "additionalFields": {}
      },
      "typeVersion": 2
    },
    {
      "id": "61bfd72b-8971-4298-8d2a-09baea403956",
      "name": "Email Notification",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        1560,
        360
      ],
      "parameters": {
        "options": {},
        "subject": "Property Lead Report - {{ $now.format('YYYY-MM-DD') }}",
        "toEmail": "user@example.com",
        "fromEmail": "user@example.com"
      },
      "typeVersion": 2.1
    },
    {
      "id": "a79a0618-ac63-4aaf-8337-b9ccc5940eef",
      "name": "Summarize Results",
      "type": "n8n-nodes-base.code",
      "position": [
        1320,
        360
      ],
      "parameters": {
        "jsCode": "// Summarize the results of the property lead search\nconst leads = $input.all();\nconst totalLeads = leads.length;\n\n// Calculate the highest lead score\nlet highestScore = 0;\nif (totalLeads > 0) {\n  highestScore = Math.max(...leads.map(item => item.json.lead_score || 0));\n}\n\n// Return a summary object\nreturn {\n  json: {\n    total_leads: totalLeads,\n    highest_score: highestScore,\n    execution_date: new Date().toISOString(),\n    success: true\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "cf6bbc2b-4892-4612-aee9-7f255f627a67",
      "name": "Sticky Note - Workflow Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -420,
        -520
      ],
      "parameters": {
        "width": 800,
        "height": 280,
        "content": "# Property Lead Automation Workflow\n\nThis workflow automatically searches for potential real estate leads based on configured criteria, obtains owner contact information through skip tracing, and pushes the leads to your CRM. It can be run manually or scheduled to run daily.\n\n## Steps: Property Search \u2192 Filter Results \u2192 Skip Trace \u2192 Format Data \u2192 Export (Excel & CRM)"
      },
      "typeVersion": 1
    },
    {
      "id": "ff155460-3f4e-44e8-aac7-4b84dff2dceb",
      "name": "Sticky Note - Triggers",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -420,
        -160
      ],
      "parameters": {
        "color": 2,
        "width": 320,
        "height": 620,
        "content": "## Workflow Triggers\n\nThis workflow can be triggered in two ways:\n\n1. **Scheduled Trigger** - Runs automatically every day at the specified time\n\n2. **Manual Trigger** - Run the workflow on-demand by clicking Execute"
      },
      "typeVersion": 1
    },
    {
      "id": "8c127497-0dc4-428d-a946-14c10b9572cb",
      "name": "Sticky Note - Property Search",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -80,
        -180
      ],
      "parameters": {
        "color": 4,
        "width": 320,
        "height": 650,
        "content": "## Search Configuration\n\nConfigure your property search criteria including:\n\n- Location (city, state, zip)\n- Property type\n- Value range\n- Equity percentage\n- Owner status\n- And more\n\nEdit the 'search_parameters' in the Set node to customize your search criteria."
      },
      "typeVersion": 1
    },
    {
      "id": "20ad7c5e-5d73-4b43-b5b0-6c9eaae18400",
      "name": "Sticky Note - Data Processing",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        260,
        -180
      ],
      "parameters": {
        "color": 5,
        "width": 880,
        "height": 660,
        "content": "## Property Data Processing\n\n1. **Search Properties API** - Connect to BatchData to search for properties\n\n2. **Filter Property Results** - Apply additional filtering logic and calculate lead scores based on factors like:\n   - Equity percentage\n   - Years of ownership\n   - Owner occupancy status\n   - Tax delinquency\n   - Recent sales activity\n\n3. **Get Owner Contact Info** - Skip trace each property to find owner contact details\n\n4. **Format Lead Data** - Structure the data for CRM and reporting"
      },
      "typeVersion": 1
    },
    {
      "id": "a0254233-a0af-43b2-8258-0820d8fdd49d",
      "name": "Sticky Note - Output",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1180,
        -180
      ],
      "parameters": {
        "color": 6,
        "width": 560,
        "height": 920,
        "content": "## Lead Output Options\n\n1. **Create Excel Spreadsheet** - Generates an Excel file with all property leads and details\n\n2. **Push to CRM** - Adds leads to your CRM system (HubSpot in this example, but can be changed to Salesforce, Zoho, etc.)\n\n3. **Email Notification** - Sends a summary email with the Excel file attached\n\n4. **Summarize Results** - Provides a summary of the execution results"
      },
      "typeVersion": 1
    },
    {
      "id": "cd34cafe-5a92-4ac3-b585-77c07862db22",
      "name": "Filter",
      "type": "n8n-nodes-base.filter",
      "position": [
        480,
        200
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cee6d210-4a90-4ad6-bbda-77153c21d3b4",
              "operator": {
                "type": "dateTime",
                "operation": "before"
              },
              "leftValue": "={{ $json.results.properties[0].deedHistory[0].recordingDate }}",
              "rightValue": "2024-06-02T00:00:00"
            },
            {
              "id": "99089667-9c68-48d7-ad09-24a5ce301a70",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.results.properties[0].mls.status }}",
              "rightValue": "Off Market"
            },
            {
              "id": "261c72c7-7208-462c-860d-148f19d3922d",
              "operator": {
                "type": "number",
                "operation": "lt"
              },
              "leftValue": "={{ $json.results.properties[0].openLien.mortgages[0].ltv }}",
              "rightValue": 70
            },
            {
              "id": "0a18f08e-86ea-4859-85db-2137c2186d11",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.results.properties[0].quickLists.highEquity }}",
              "rightValue": "true"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "d30c51d7-9f2d-4804-9fec-036b41ebf5a8",
      "name": "Split Out",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        640,
        300
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "results.properties"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "be71140e-2f5c-452a-9cde-ac00b14c7a6a",
  "connections": {
    "Filter": {
      "main": [
        [
          {
            "node": "Split Out",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out": {
      "main": [
        [
          {
            "node": "Get Owner Contact Info",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Daily Schedule": {
      "main": [
        [
          {
            "node": "Configure Search Parameters",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Lead Data": {
      "main": [
        [
          {
            "node": "Create Excel Spreadsheet",
            "type": "main",
            "index": 0
          },
          {
            "node": "Push to CRM",
            "type": "main",
            "index": 0
          },
          {
            "node": "Summarize Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Summarize Results": {
      "main": [
        [
          {
            "node": "Email Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search Properties API": {
      "main": [
        [
          {
            "node": "Filter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Owner Contact Info": {
      "main": [
        [
          {
            "node": "Format Lead Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Excel Spreadsheet": {
      "main": [
        [
          {
            "node": "Email Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Configure Search Parameters": {
      "main": [
        [
          {
            "node": "Search Properties API",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \"Execute Workflow\"": {
      "main": [
        [
          {
            "node": "Configure Search Parameters",
            "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

How It Works This N8N workflow creates an automated system for discovering high-potential real estate investment opportunities. The workflow runs on a customizable schedule to scan the market for properties that match your specific criteria, then alerts your team about the most…

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

More CRM & Sales workflows → · Browse all categories →

Related workflows

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

CRM & Sales

How It Works This workflow automates the entire property lead generation process in a few simple steps: Property Search: Connects to BatchData's Property Search API with customizable parameters (locat

HTTP Request, Spreadsheet File, HubSpot +1
CRM & Sales

Property Lead Contact Enrichment from CRM. Uses httpRequest, spreadsheetFile, hubspot, emailSend. Event-driven trigger; 16 nodes.

HTTP Request, Spreadsheet File, HubSpot +1
CRM & Sales

This workflow automates the entire lead qualification process from form submission to personalized follow-up. When a prospect fills out your JotForm, the workflow instantly captures their information,

Jot Form Trigger, HubSpot, Google Sheets +2
CRM & Sales

This template is perfect for: Marketing Teams looking to automatically qualify inbound leads from campaigns Sales Teams wanting to prioritize high-value prospects instantly Agencies offering lead qual

Form Trigger, Slack, OpenAI +5
CRM & Sales

This n8n workflow automates end-to-end lead generation, from scraping local businesses to qualifying and sending high-quality prospects directly into your CRM.

HTTP Request, Google Sheets, HubSpot +2