{
  "name": "Daily Zumper rental alerts with Apify",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "days",
              "triggerAtHour": 8
            }
          ]
        }
      },
      "id": "rentals-schedule",
      "name": "Daily schedule",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        -620,
        0
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.apify.com/v2/actors/benthepythondev~zumper-rental-scraper/run-sync-get-dataset-items",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "{\"mode\":\"search\",\"location\":\"austin-tx\",\"propertyType\":\"apartments-for-rent\",\"maxPrice\":3000,\"minBeds\":1,\"maxListings\":25,\"includePhotos\":false,\"useApifyProxy\":true}",
        "options": {
          "timeout": 300000
        }
      },
      "id": "rentals-apify",
      "name": "Run Zumper Actor",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -360,
        0
      ]
    },
    {
      "parameters": {
        "jsCode": "const input = $input.all().map(item => item.json);\nconst rows = input.length === 1 && Array.isArray(input[0]) ? input[0] : input;\nconst rentals = rows.filter(row => {\n  const price = Number(row.price_min ?? row.price ?? 0);\n  const score = Number(row.lead_score ?? 0);\n  return row && row.url && (!price || price <= 3000) && score >= 60;\n}).sort((a, b) => Number(b.lead_score || 0) - Number(a.lead_score || 0));\nconst lines = rentals.slice(0, 25).map((row, index) => {\n  const price = row.price_min ? `$${row.price_min}/mo` : 'Price unavailable';\n  const beds = row.beds_min ?? row.bedrooms ?? '?';\n  const address = row.address || [row.street, row.city, row.state].filter(Boolean).join(', ');\n  return `${index + 1}. ${price} | ${beds} bed | score ${row.lead_score || 0}\\n${address || 'Address unavailable'}\\n${row.url}`;\n});\nreturn [{ json: { count: rentals.length, subject: `Zumper alert: ${rentals.length} high-score rentals`, digest: lines.join('\\n\\n') || 'No rentals matched the configured price and score thresholds today.' } }];"
      },
      "id": "rentals-digest",
      "name": "Filter and build rental digest",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -100,
        0
      ]
    },
    {
      "parameters": {
        "fromEmail": "alerts@example.com",
        "toEmail": "you@example.com",
        "subject": "={{ $json.subject }}",
        "emailFormat": "text",
        "text": "={{ $json.digest }}",
        "options": {}
      },
      "id": "rentals-email",
      "name": "Email rental alert",
      "type": "n8n-nodes-base.emailSend",
      "typeVersion": 2.1,
      "position": [
        160,
        0
      ]
    }
  ],
  "connections": {
    "Daily schedule": {
      "main": [
        [
          {
            "node": "Run Zumper Actor",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run Zumper Actor": {
      "main": [
        [
          {
            "node": "Filter and build rental digest",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter and build rental digest": {
      "main": [
        [
          {
            "node": "Email rental alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "zumper-alerts-v1",
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "tags": []
}