{
  "name": "Zillow ZIP New-Listing Watcher → Slack (APIllow)",
  "meta": {
    "templateCredsSetupCompleted": false,
    "description": "Every morning, pull active for-sale listings in a ZIP via the APIllow API, diff against the ZPIDs seen yesterday (kept in an n8n Data Table / static data), and post anything new to Slack. Store your APIllow key as a Header Auth credential named x-api-key. Free key at https://apillow.co"
  },
  "nodes": [
    {
      "parameters": {
        "rule": { "interval": [{ "field": "cronExpression", "expression": "0 8 * * *" }] }
      },
      "id": "c2b2d001-0001-4001-8001-000000000001",
      "name": "Every day at 8am",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [240, 300]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.apillow.co/v1/properties",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"zipcodes\": [44124],\n  \"type\": \"sale\",\n  \"max_items\": 100\n}",
        "options": {}
      },
      "id": "c2b2d001-0002-4001-8001-000000000002",
      "name": "APIllow: submit ZIP search",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [460, 300],
      "credentials": {
        "httpHeaderAuth": { "id": "REPLACE_WITH_YOUR_CREDENTIAL_ID", "name": "APIllow" }
      }
    },
    {
      "parameters": { "amount": 8, "unit": "seconds" },
      "id": "c2b2d001-0003-4001-8001-000000000003",
      "name": "Wait for job",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [680, 300]
    },
    {
      "parameters": {
        "url": "=https://api.apillow.co/v1/results/{{ $('APIllow: submit ZIP search').item.json.job_id }}",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {}
      },
      "id": "c2b2d001-0004-4001-8001-000000000004",
      "name": "APIllow: get results",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [900, 300],
      "credentials": {
        "httpHeaderAuth": { "id": "REPLACE_WITH_YOUR_CREDENTIAL_ID", "name": "APIllow" }
      }
    },
    {
      "parameters": {
        "jsCode": "// Diff today's ZPIDs against what we saw yesterday (kept in workflow static data).\nconst results = $input.first().json.results || [];\nconst store = $getWorkflowStaticData('global');\nconst seen = new Set(store.seenZpids || []);\n\nconst fresh = results.filter(r => r.property && !seen.has(r.property.zpid));\n\n// Remember everything we saw today for tomorrow's diff.\nstore.seenZpids = results.map(r => r.property && r.property.zpid).filter(Boolean);\n\nreturn fresh.map(r => ({ json: r.property }));"
      },
      "id": "c2b2d001-0005-4001-8001-000000000005",
      "name": "Only new listings",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [1120, 300]
    },
    {
      "parameters": {
        "select": "channel",
        "channelId": { "__rl": true, "mode": "list", "value": "YOUR_SLACK_CHANNEL" },
        "text": "=:house: New listing in 44124 — {{ $json.address }} — ${{ $json.price }} ({{ $json.bedrooms }}bd/{{ $json.bathrooms }}ba)\\nhttps://www.zillow.com/homedetails/{{ $json.zpid }}_zpid/",
        "otherOptions": {}
      },
      "id": "c2b2d001-0006-4001-8001-000000000006",
      "name": "Post to Slack",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.2,
      "position": [1340, 300],
      "credentials": {}
    }
  ],
  "connections": {
    "Every day at 8am": { "main": [[{ "node": "APIllow: submit ZIP search", "type": "main", "index": 0 }]] },
    "APIllow: submit ZIP search": { "main": [[{ "node": "Wait for job", "type": "main", "index": 0 }]] },
    "Wait for job": { "main": [[{ "node": "APIllow: get results", "type": "main", "index": 0 }]] },
    "APIllow: get results": { "main": [[{ "node": "Only new listings", "type": "main", "index": 0 }]] },
    "Only new listings": { "main": [[{ "node": "Post to Slack", "type": "main", "index": 0 }]] }
  },
  "settings": { "executionOrder": "v1" },
  "pinData": {}
}
