# Zillow Scraper: ZIP Search & New Listing Monitor (`integrative_cafe_8pc/zillow-zip-monitor`) Actor

Use this Actor when you need Zillow listings by ZIP code (for sale, for rent or sold) with price, beds, baths, Zestimate and photos, or alerts on new listings and price cuts. Monitor mode returns only what changed, with optional webhook alerts. No agent personal data.

- **URL**: https://apify.com/integrative_cafe_8pc/zillow-zip-monitor.md
- **Developed by:** [Bluefield Data](https://apify.com/integrative_cafe_8pc) (community)
- **Categories:** Real estate, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.75 / 1,000 listing returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Zillow ZIP Code Search & New Listing Monitor

Use this Actor when you need Zillow listings for one or more US ZIP codes (for sale, for rent or recently sold) as clean JSON, or a scheduled feed of only the new listings and price cuts.

**Schedule it every few hours and get only new listings and price cuts.** Search Zillow by ZIP code for homes **for sale**, **for rent** or **recently sold**, with price, bedroom, bathroom and days-on-Zillow filters. Turn on monitor mode and each run returns only what changed since the last run, with an optional alert to Discord, Slack or any webhook.

### Why this one

- **Runs finish.** When Zillow blocks a request, the actor opens a fresh US residential session and retries with growing waits. In our launch test, 5 out of 5 ZIP codes (Austin, Miami Beach, New York, Chicago, San Francisco) came back for sale, for rent and sold: 2,478 listings, 0 errors.
- **Monitor mode built in.** It remembers every listing it has seen and returns only `NEW` listings and `PRICE_CUT` listings (with the previous price). No spreadsheet diffing on your side.
- **Past the 820-result limit.** Zillow shows at most 20 pages per search. Big ZIP codes are split by price automatically and merged without duplicates.
- **Clean, privacy-safe data.** Only the brokerage company name is returned. Agent names, phone numbers and emails are never collected.
- **Failures are free.** A ZIP that still fails comes back in the dataset with the reason and is not charged.

### How to use it as a monitor

1. Fill in your ZIP codes and filters, and tick **Monitor mode**.
2. Optional: paste a Discord or Slack webhook URL in **Webhook URL**.
3. Run it once. The first run saves the baseline (and returns the current listings, unless you turn off **Return listings on the first monitor run**).
4. In Apify Console, open **Schedules**, create a schedule (for example every 3 hours, `0 */3 * * *`) and pick this actor with the same input.

From then on every run returns only new listings and price cuts, and each one is posted to your webhook. Use a different **Monitor name** for each separate search you monitor.

### Input

| Field | What it does |
|---|---|
| `zipCodes` | US 5-digit ZIP codes, one per line |
| `listingTypes` | `for_sale`, `for_rent`, `sold` (one or more) |
| `priceMin`, `priceMax` | Price range in USD (monthly rent for rentals) |
| `bedsMin`, `bedsMax`, `bathsMin` | Bedroom and bathroom filters |
| `daysOnZillow` | Only listings added in the last 1, 7, 14, 30 or 90 days |
| `maxItemsPerZip` | Cap per ZIP and listing type (default 200) |
| `monitorMode` | Return only new listings and price cuts since the last run |
| `monitorName` | Name of the memory used by the monitor |
| `emitOnFirstRun` | Return the baseline on the first monitor run (default on) |
| `webhookUrl` | Optional POST target for each change (Discord, Slack, or any URL that takes JSON) |

### Output

```json
{
  "zpid": "29459441",
  "searchZip": "78704",
  "listingType": "for_rent",
  "status": "FOR_RENT",
  "address": "1317 Kenwood Ave, Austin, TX 78704",
  "city": "Austin", "state": "TX", "zipcode": "78704",
  "latitude": 30.246357, "longitude": -97.73815,
  "price": 4999, "priceText": "$4,999/mo",
  "beds": 4, "baths": 4, "sqft": 2780,
  "homeType": "SINGLE_FAMILY",
  "daysOnZillow": 15,
  "priceChange": -1000, "priceChangeDate": "2026-10-16", "priceReductionText": "$1,000 (Oct 16)",
  "zestimate": 1493300, "rentZestimate": 7729, "taxAssessedValue": 1062172,
  "brokerName": "Example Realty LLC",
  "photos": ["https://photos.zillowstatic.com/fp/...-p_e.jpg"],
  "url": "https://www.zillow.com/homedetails/1317-Kenwood-Ave-Austin-TX-78704/29459441_zpid/",
  "changeType": "PRICE_CUT", "previousPrice": 5999
}
```

`changeType` and `previousPrice` appear only in monitor mode. Fields Zillow does not show for a listing (for example the Zestimate or the sold price in non-disclosure states) are left out. Apartment buildings come as one row with `buildingName` and `units` (price from, beds).

### Pricing

Pay per event: **$0.0015 per listing returned** plus **$0.005 per ZIP search** (one ZIP and one listing type). 200 listings from one ZIP cost about $0.31. In monitor mode you pay the search fee plus only the changes returned, so a scheduled check with nothing new costs half a cent. Failures are free.

### Notes

Data comes from Zillow's public search results, the same data anyone sees on the map page without logging in. Results are capped by Zillow at what the public search shows.

# Actor input Schema

## `zipCodes` (type: `array`):

US 5-digit ZIP codes, one per line. Each ZIP is searched on its own.

## `listingTypes` (type: `array`):

Which Zillow searches to run for each ZIP. Pick one or more.

## `priceMin` (type: `integer`):

Minimum price. For rentals this is the monthly rent.

## `priceMax` (type: `integer`):

Maximum price. For rentals this is the monthly rent.

## `bedsMin` (type: `integer`):

Only listings with at least this many bedrooms.

## `bedsMax` (type: `integer`):

Only listings with at most this many bedrooms.

## `bathsMin` (type: `integer`):

Only listings with at least this many bathrooms.

## `daysOnZillow` (type: `string`):

Only listings added in this period (for sold: sold in this period).

## `maxItemsPerZip` (type: `integer`):

Stop after this many listings for each ZIP and listing type. Large ZIPs are split by price automatically to go past Zillow's 820-result page limit.

## `monitorMode` (type: `boolean`):

Remember what was seen in earlier runs and return only NEW listings and PRICE_CUT listings. Schedule the actor and you get only changes. The first run saves the baseline.

## `monitorName` (type: `string`):

Name of the key-value store that keeps the monitor memory. Use a different name for each separate monitor.

## `emitOnFirstRun` (type: `boolean`):

If on, the first monitor run returns every current listing as NEW (the baseline). If off, the first run only saves the baseline and returns nothing.

## `webhookUrl` (type: `string`):

Optional. In monitor mode each new listing or price cut is POSTed here. Discord and Slack webhooks get a readable message; any other URL gets the listing JSON. Not sent on the first (baseline) run.

## `proxy` (type: `object`):

US residential proxy is required; Zillow blocks datacenter IPs.

## Actor input object example

```json
{
  "zipCodes": [
    "78704",
    "33139"
  ],
  "listingTypes": [
    "for_sale"
  ],
  "daysOnZillow": "any",
  "maxItemsPerZip": 200,
  "monitorMode": false,
  "monitorName": "zillow-zip-monitor",
  "emitOnFirstRun": true,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "zipCodes": [
        "78704",
        "33139"
    ],
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("integrative_cafe_8pc/zillow-zip-monitor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "zipCodes": [
        "78704",
        "33139",
    ],
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("integrative_cafe_8pc/zillow-zip-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "zipCodes": [
    "78704",
    "33139"
  ],
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call integrative_cafe_8pc/zillow-zip-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,integrative_cafe_8pc/zillow-zip-monitor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/36NY31ejHH75hcj4s/builds/Vp315uph1bj5ULuHy/openapi.json
