AutomationFlowsSlack & Telegram › Automated Real Estate Market Scanner

Automated Real Estate Market Scanner

Original n8n title: Real Estate Market Scanning

Real Estate Market Scanning. Uses scheduleTrigger, httpRequest, splitOut, emailSend. Scheduled trigger; 15 nodes.

Cron / scheduled trigger★★★★☆ complexity15 nodesHTTP RequestEmail SendSlack
Slack & Telegram Trigger: Cron / scheduled Nodes: 15 Complexity: ★★★★☆ Added:

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": "WUFuYk56jNNpjfZm",
  "name": "Real Estate Market Scanning",
  "tags": [],
  "nodes": [
    {
      "id": "db8f34be-8475-4be6-b070-79a8185fad69",
      "name": "Schedule Market Scan",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1580,
        260
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours"
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "36f4babd-3441-4da7-b485-3f9f561cb929",
      "name": "BatchData API Configuration",
      "type": "n8n-nodes-base.set",
      "position": [
        -1380,
        260
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "f44f6a90-6de5-4c02-909d-73cfce0c0c9a",
              "name": "apiKey",
              "type": "string",
              "value": "YOUR_BATCHDATA_API_KEY"
            },
            {
              "id": "9356ff74-9783-40cf-a8af-94e45f1ac83e",
              "name": "searchParameters",
              "type": "object",
              "value": "={\n  \"city\": \"Austin\",\n  \"state\": \"TX\",\n  \"minimumMarketValue\": 250000,\n  \"maximumMarketValue\": 600000,\n  \"minimumEquity\": 30,\n  \"propertyType\": [\"SFR\"],\n  \"limit\": 100\n}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "e34c4c84-4b31-451f-ad16-11db76f67dce",
      "name": "Query BatchData Properties",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1180,
        260
      ],
      "parameters": {
        "url": "https://api.batchdata.com/api/v1/properties/search",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "city",
              "value": "={{ $json.searchParameters.city }}"
            },
            {
              "name": "state",
              "value": "={{ $json.searchParameters.state }}"
            },
            {
              "name": "minimumMarketValue",
              "value": "={{ $json.searchParameters.minimumMarketValue }}"
            },
            {
              "name": "maximumMarketValue",
              "value": "={{ $json.searchParameters.maximumMarketValue }}"
            },
            {
              "name": "minimumEquity",
              "value": "={{ $json.searchParameters.minimumEquity }}"
            },
            {
              "name": "propertyType",
              "value": "={{ $json.searchParameters.propertyType }}"
            },
            {
              "name": "limit",
              "value": "={{ $json.searchParameters.limit }}"
            }
          ]
        },
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.1
    },
    {
      "id": "c6d4c4ee-51d4-41f5-a975-e979785e9166",
      "name": "Get Previous Results",
      "type": "n8n-nodes-base.code",
      "position": [
        -980,
        260
      ],
      "parameters": {
        "jsCode": "// Get the stored data from previous runs\nconst workflowStaticData = getWorkflowStaticData('global');\n\n// If no previous data exists, initialize it\nif (!workflowStaticData.hasOwnProperty('previousProperties')) {\n  workflowStaticData.previousProperties = [];\n}\n\n// Add the previous properties data to the current item\nreturn [\n  {\n    json: {\n      ...items[0].json,\n      previousProperties: workflowStaticData.previousProperties,\n      currentProperties: items[0].json.data.properties || [],\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "a77dfe55-8a01-4b83-9395-ab533e1b7b24",
      "name": "Compare Results",
      "type": "n8n-nodes-base.code",
      "position": [
        -780,
        260
      ],
      "parameters": {
        "jsCode": "// Get the current and previous property lists\nconst currentProperties = items[0].json.currentProperties;\nconst previousProperties = items[0].json.previousProperties;\n\n// Create a map of previous properties by their ID for easier comparison\nconst previousPropertiesMap = {};\nfor (const property of previousProperties) {\n  previousPropertiesMap[property.id] = property;\n}\n\n// Find new properties (those in current but not in previous)\nconst newProperties = currentProperties.filter(property => \n  !previousPropertiesMap[property.id]\n);\n\n// Find changed properties (those in both but with different values)\nconst changedProperties = currentProperties.filter(property => {\n  const previousProperty = previousPropertiesMap[property.id];\n  if (!previousProperty) return false;\n  \n  // Check if important values changed (price, status, etc.)\n  return (\n    property.marketValue !== previousProperty.marketValue ||\n    property.status !== previousProperty.status ||\n    property.ownerStatus !== previousProperty.ownerStatus ||\n    property.lastSaleDate !== previousProperty.lastSaleDate\n  );\n});\n\n// Update the static data for the next run\nconst workflowStaticData = getWorkflowStaticData('global');\nworkflowStaticData.previousProperties = currentProperties;\n\n// Return the combined results\nreturn [\n  {\n    json: {\n      ...items[0].json,\n      newProperties,\n      changedProperties,\n      allChanges: [...newProperties, ...changedProperties]\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "c8c01396-58e8-4782-b1aa-0cc3059ef80f",
      "name": "Split Properties",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -560,
        260
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "allChanges"
      },
      "typeVersion": 1
    },
    {
      "id": "7971a981-d2e8-4d96-b3ef-ad6e532d95fe",
      "name": "Filter High Potential",
      "type": "n8n-nodes-base.filter",
      "position": [
        -380,
        260
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "83c15f54-20d9-460c-a3f5-82f6c98d3d63",
              "operator": {
                "type": "number",
                "operation": "larger"
              },
              "leftValue": "={{ $json.equityPercentage || 0 }}",
              "rightValue": 40
            },
            {
              "id": "53bf77b8-4c78-4f87-a518-0e9a56c77a70",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.ownerStatus || '' }}",
              "rightValue": "absentee"
            }
          ]
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "f5c20b50-d514-4d26-a3e7-874f228578e9",
      "name": "Get Property Details",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -180,
        260
      ],
      "parameters": {
        "url": "=https://api.batchdata.com/api/v1/properties/{{ $json.id }}",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.1
    },
    {
      "id": "f83e4ccb-4457-4e00-97b7-ad411decba80",
      "name": "Format Email Content",
      "type": "n8n-nodes-base.set",
      "position": [
        20,
        260
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "ad37cef8-0359-4fb8-8c54-e5a5a0aa1082",
              "name": "emailSubject",
              "type": "string",
              "value": "=New Property Opportunity: {{ $json.address.street }}, {{ $json.address.city }}, {{ $json.address.state }}"
            },
            {
              "id": "9c1b6e34-b31e-4e46-a6b3-ea7c34b4456a",
              "name": "emailContent",
              "type": "string",
              "value": "=<h2>High Potential Property Opportunity</h2>\n\n<p><strong>Address:</strong> {{ $json.address.street }}, {{ $json.address.city }}, {{ $json.address.state }} {{ $json.address.zip }}</p>\n\n<p><strong>Property Details:</strong></p>\n<ul>\n  <li>Market Value: ${{ $json.marketValue }}</li>\n  <li>Equity: {{ $json.equityPercentage }}%</li>\n  <li>Owner Status: {{ $json.ownerStatus }}</li>\n  <li>Square Feet: {{ $json.squareFeet }}</li>\n  <li>Bedrooms: {{ $json.bedrooms }}</li>\n  <li>Bathrooms: {{ $json.bathrooms }}</li>\n  <li>Year Built: {{ $json.yearBuilt }}</li>\n  <li>Last Sale Date: {{ $json.lastSaleDate }}</li>\n  <li>Last Sale Price: ${{ $json.lastSalePrice }}</li>\n</ul>\n\n<p><strong>Owner Information:</strong></p>\n<ul>\n  <li>Owner Name: {{ $json.owner.name }}</li>\n  <li>Mailing Address: {{ $json.owner.mailingAddress }}</li>\n  <li>Phone Numbers: {{ $json.owner.phoneNumbers ? $json.owner.phoneNumbers.join(', ') : 'N/A' }}</li>\n  <li>Email: {{ $json.owner.email || 'N/A' }}</li>\n</ul>\n\n<p>This property appears to be a high-potential opportunity based on:</p>\n<ul>\n  <li>High equity percentage</li>\n  <li>Absentee owner</li>\n</ul>\n\n<p><a href=\"https://maps.google.com/?q={{ $json.address.street }}, {{ $json.address.city }}, {{ $json.address.state }} {{ $json.address.zip }}\">View on Google Maps</a></p>"
            },
            {
              "id": "eac4a51e-edfe-457a-9b38-a6c6f9e17ffd",
              "name": "slackMessage",
              "type": "string",
              "value": "=*New High Potential Property Lead*\n\n*Address:* {{ $json.address.street }}, {{ $json.address.city }}, {{ $json.address.state }} {{ $json.address.zip }}\n*Market Value:* ${{ $json.marketValue }}\n*Equity:* {{ $json.equityPercentage }}%\n*Owner Status:* {{ $json.ownerStatus }}\n\n<https://maps.google.com/?q={{ $json.address.street }}, {{ $json.address.city }}, {{ $json.address.state }} {{ $json.address.zip }}|View on Google Maps>"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "3f69ccd0-24c8-490f-a1ec-305f14819d39",
      "name": "Send Email Alert",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        400,
        180
      ],
      "parameters": {
        "options": {},
        "subject": "={{ $json.emailSubject }}",
        "toEmail": "salesteam@yourcompany.com",
        "fromEmail": "alerts@yourcompany.com"
      },
      "typeVersion": 2
    },
    {
      "id": "416661ac-8068-44fd-b95f-6b978834eed9",
      "name": "Post to Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        280,
        320
      ],
      "parameters": {
        "text": "={{ $json.slackMessage }}",
        "otherOptions": {}
      },
      "typeVersion": 2
    },
    {
      "id": "f6b33048-3224-4b2d-a3e3-fd21dc1f42aa",
      "name": "Sticky Note Main Flow",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1660,
        120
      ],
      "parameters": {
        "width": 1040,
        "height": 340,
        "content": "## Main Workflow Flow\nThis part of the workflow handles the regular scanning and processing of property data. It runs on a schedule to detect new properties or changes to existing ones, then passes the filtered results along for detailed analysis."
      },
      "typeVersion": 1
    },
    {
      "id": "82472e40-7132-40ac-9c9b-4635f604d92a",
      "name": "Sticky Note Filter & Analyze",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -600,
        120
      ],
      "parameters": {
        "width": 760,
        "height": 340,
        "content": "## Property Filtering & Analysis\nHere we filter the properties based on criteria for high-potential leads (high equity %, absentee owners, etc.) and fetch detailed information about each property to prepare comprehensive reports for the sales team."
      },
      "typeVersion": 1
    },
    {
      "id": "4538e728-f86c-4cf3-a69e-ce42ca5bb83e",
      "name": "Sticky Note Notifications",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        180,
        -40
      ],
      "parameters": {
        "width": 440,
        "height": 500,
        "content": "## Notifications\nThis section delivers the property leads to the sales team through multiple channels:\n\n1. Email alerts with detailed property and owner information\n2. Slack notifications for quick updates\n\nBoth include Google Maps links to quickly view the property location."
      },
      "typeVersion": 1
    },
    {
      "id": "4e09ea20-a6a3-4e6c-a67c-95cbd79f9151",
      "name": "Sticky Note Instructions",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1660,
        -220
      ],
      "parameters": {
        "width": 1040,
        "height": 300,
        "content": "## Setup Instructions\n\n1. **API Keys & Credentials**:\n   - Add your BatchData API Key to the BatchData API Configuration node\n   - Set up SMTP credentials for email delivery\n   - Configure Slack API credentials for team notifications\n\n2. **Customize Search Parameters**:\n   - Adjust property search criteria in the BatchData API Configuration node\n   - Modify the filtering conditions in the Filter High Potential node\n\n3. **Notification Recipients**:\n   - Update email recipients in the Send Email Alert node\n   - Set appropriate Slack channel in the Post to Slack node"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "21dfe7cd-d858-4954-a4da-b0dd11d17aff",
  "connections": {
    "Compare Results": {
      "main": [
        [
          {
            "node": "Split Properties",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Properties": {
      "main": [
        [
          {
            "node": "Filter High Potential",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Email Content": {
      "main": [
        [
          {
            "node": "Send Email Alert",
            "type": "main",
            "index": 0
          },
          {
            "node": "Post to Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Previous Results": {
      "main": [
        [
          {
            "node": "Compare Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Property Details": {
      "main": [
        [
          {
            "node": "Format Email Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Market Scan": {
      "main": [
        [
          {
            "node": "BatchData API Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter High Potential": {
      "main": [
        [
          {
            "node": "Get Property Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Query BatchData Properties": {
      "main": [
        [
          {
            "node": "Get Previous Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "BatchData API Configuration": {
      "main": [
        [
          {
            "node": "Query BatchData Properties",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

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

How this works

Stay ahead in the competitive real estate market by automatically scanning for new property listings and price changes, saving hours of manual research and enabling quicker investment decisions. This workflow suits real estate agents, investors, or analysts who need regular market insights without constant monitoring. It begins with a scheduled trigger that queries the BatchData API for fresh property data, then compares it against previous results to highlight high-potential opportunities before emailing a concise summary.

Use this workflow for daily or weekly scans in specific regions where timely alerts on undervalued properties or market shifts can drive deals. Avoid it for one-off queries or markets without API access like BatchData, as it relies on recurring automation. Common variations include swapping email notifications for Slack messages to team channels or adding filters for commercial versus residential properties.

About this workflow

Real Estate Market Scanning. Uses scheduleTrigger, httpRequest, splitOut, emailSend. Scheduled trigger; 15 nodes.

Source: https://github.com/Zie619/n8n-workflows — original creator credit. Request a take-down →

More Slack & Telegram workflows → · Browse all categories →

Related workflows

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

Slack & Telegram

debug. Uses httpRequest, slack, redis, mailgun. Scheduled trigger; 60 nodes.

HTTP Request, Slack, Redis +2
Slack & Telegram

This workflow contains community nodes that are only compatible with the self-hosted version of n8n.

N8N Nodes Scrapegraphai, HTTP Request, Google Sheets +2
Slack & Telegram

Simplify financial oversight with this automated n8n workflow. Triggered daily, it fetches cash flow and expense data from a Google Sheet, analyzes inflows and outflows, validates records, and generat

HTTP Request, Google Sheets, Email Send +3
Slack & Telegram

This workflow automatically monitors competitor affiliate programs twice daily using Bright Data's web scraping API to extract commission rates, cookie durations, average order values, and payout term

HTTP Request, Google Sheets, Slack +1
Slack & Telegram

Automate your payroll process with this efficient workflow. Triggered monthly on the 28th, it fetches employee data from a Google Sheet, uses AI to calculate net salaries with tax and deductions, stru

Google Sheets, HTTP Request, Email Send +1