# Zillow ZIP Search Scraper - Listings & Prices (`dataio/zillow-zip-search-scraper`) Actor

Scrape Zillow listings for any US ZIP code: homes for sale, for rent or recently sold, with price, Zestimate, Rent Zestimate, beds, baths, area, days on Zillow, price cuts and coordinates. Rental buildings priced from their units. Follows every page, no browser.

- **URL**: https://apify.com/dataio/zillow-zip-search-scraper.md
- **Developed by:** [Tom Awake](https://apify.com/dataio) (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 $1.00 / 1,000 listings

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

### What does Zillow ZIP Search Scraper do?

Zillow ZIP Search Scraper extracts every Zillow listing for the US ZIP codes
you give it: **homes for sale, for rent, or recently sold**. You get the price,
the **Zestimate and Rent Zestimate**, beds, baths, living area, lot size, home
type, days on Zillow, **price cuts**, open houses, broker, coordinates and the
listing URL. It works like a **Zillow API** for ZIP-code searches.

- **Follows every results page.** Zillow shows about 41 listings per page, and
  the actor pages through until it reaches your limit. Measured: 264 listings
  over 7 pages for 90210.
- **Rental buildings, priced.** On Zillow, apartment buildings have no price of
  their own, only per-unit rents. In a sample of 123 rentals, 73 were
  buildings. The actor reads their starting rent, rent range, bedroom range and
  available units. Measured: rental price coverage rose from 42 % to 98 %.
- **Filters that keep paging.** A minimum price, bedrooms or a home type is
  applied during collection. Ask for 100 condos and you get 100 condos, not the
  condos found among the first 100 listings.
- **No browser.** The actor reads Zillow's own page data, which is fast and
  light.

### What data can you extract from Zillow?

| Data | Fields |
|---|---|
| Price | `price`, `priceText`, `zestimate`, `rentZestimate`, `priceChange`, `priceReduction` |
| Home | `beds`, `baths`, `livingAreaSqft`, `lotAreaValue`, `lotAreaUnit`, `homeType`, `homeStatus` |
| Market | `daysOnZillow`, `openHouse`, `brokerName`, `listingType` |
| Location | `address`, `street`, `city`, `state`, `zipcode`, `latitude`, `longitude` |
| Rental buildings | `isBuilding`, `buildingName`, `availableUnits`, `minRent`, `maxRent`, `bedsRange`, `units` |
| Links | `zpid`, `detailUrl`, `imageUrl` |

Coverage measured on 3 ZIP codes (90210, 10001, 60614), 123 listings per
type:

| Field | For sale | For rent | Sold |
|---|---|---|---|
| `price` | 100 % | 98 % | 100 % |
| `zestimate` | 57 % | 15 % | 92 % |
| `rentZestimate` | 22 % | 28 % | 57 % |
| `baths` | 100 % | 41 % | 97 % |
| `livingAreaSqft` | 84 % | 30 % | 72 % |
| `daysOnZillow` | 98 % | 40 % | 100 % |
| `priceChange` | 18 % | 15 % | — |
| `latitude`, `longitude` | 100 % | 98 % | 90 % |

Rental buildings carry per-unit data (`units`, `bedsRange`, rent range) instead
of a single home's baths and area, which is why those columns are thinner for
rentals.

### How to scrape Zillow by ZIP code

1. Enter one or more **ZIP codes**.
2. Choose **for sale**, **for rent** or **recently sold**.
3. Optionally set filters: price range, minimum bedrooms, home types.
4. Click **Start**, then download JSON, CSV or Excel, or read the results
   through the API.

### How much does it cost to scrape Zillow?

You pay per listing returned: **$0.0015 each**, that is $1.50 per 1,000.
Subscription plans pay less, down to $0.0007 per listing. There is no start
fee.

| Job | Listings | Cost |
|---|---|---|
| One ZIP code, first page | ~41 | about $0.06 |
| One ZIP code, 200 listings | 200 | about $0.30 |
| 20 ZIP codes, 200 each | 4,000 | about $6 |

If a run reaches the spending limit you set, the output stops at that limit and
never goes past it.

### Input example

```json
{
  "zipCodes": ["90210", "10001", "60614"],
  "listingType": "forSale",
  "priceMin": 500000,
  "minBedrooms": 2,
  "homeTypes": ["CONDO", "TOWNHOUSE"],
  "maxItemsPerZip": 200
}
```

### Output example

```json
{
  "zpid": "20534770",
  "address": "624 Cole Pl, Beverly Hills, CA 90210",
  "listingType": "forSale",
  "price": 25000000,
  "zestimate": null,
  "beds": 6,
  "baths": 6,
  "livingAreaSqft": 6586,
  "homeType": "SINGLE_FAMILY",
  "daysOnZillow": 1,
  "priceChange": -2998000,
  "priceReduction": "$2,998,000 (Sep 17)",
  "openHouse": "Sun. 1-4pm",
  "latitude": 34.10872,
  "longitude": -118.3981,
  "detailUrl": "https://www.zillow.com/homedetails/624-Cole-Pl-Beverly-Hills-CA-90210/20534770_zpid/"
}
```

### Use the Zillow API in Python

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("DataIO/zillow-zip-search-scraper").call(run_input={
    "zipCodes": ["90210"], "listingType": "forSale", "maxItemsPerZip": 100,
})
for home in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(home["address"], home["price"], home["zestimate"])
```

It also works from JavaScript, Make, Zapier, n8n, and from AI agents through
the Apify MCP server.

### Other actors you might like

- [Google Hotels Scraper](https://apify.com/DataIO/google-hotels-scraper): hotel prices and ratings for any city and dates.
- [OpenStreetMap Scraper](https://apify.com/DataIO/openstreetmap-overpass-poi-scraper): local businesses and places by city and category.
- [USAspending Scraper](https://apify.com/DataIO/usaspending-federal-awards): federal contract awards by state and agency.

### FAQ

#### Is it legal to scrape Zillow?

The actor reads listings that Zillow shows publicly, without logging in. Zillow's
terms of use restrict automated access. You decide whether and how to use the
data, and it is your responsibility to respect those terms and the laws that
apply to you.

#### Why do I need residential proxies?

Zillow blocks datacenter addresses. Measured: HTTP 403 on every attempt from
datacenter proxies, and 123 listings with no refusal from US residential
proxies. The default setting already uses US residential proxies.

#### Why is the Zestimate sometimes empty?

Zillow does not publish a Zestimate for every home in search results: in the
sample, 57 % of homes for sale and 92 % of recently sold homes had one.

#### Can I track a ZIP code every day?

Yes. Schedule the actor and compare `price`, `priceChange` and `daysOnZillow`
from one run to the next to catch new listings and price cuts.

### Source

Public Zillow search pages. This actor is not affiliated with or endorsed by
Zillow.

# Actor input Schema

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

Five-digit US ZIP codes, one per line. Up to 100.

## `listingType` (type: `string`):

Homes for sale, for rent, or recently sold.

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

Listing price (monthly rent for rentals). Applied during collection: the actor keeps paging until it has enough listings that pass.

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

Listing price (monthly rent for rentals).

## `minBedrooms` (type: `integer`):

Keeps listings with at least this many bedrooms.

## `homeTypes` (type: `array`):

Zillow's home types, e.g. SINGLE\_FAMILY, CONDO, TOWNHOUSE, MULTI\_FAMILY, APARTMENT, LOT, MANUFACTURED. Empty = all.

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

Zillow shows about 41 listings per page; the actor follows the pages up to this number.

## `proxyConfiguration` (type: `object`):

Zillow blocks datacenter addresses (measured: HTTP 403 on every attempt). US residential proxies work (measured: 123 listings, no refusal).

## Actor input object example

```json
{
  "zipCodes": [
    "90210"
  ],
  "listingType": "forSale",
  "maxItemsPerZip": 40,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

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

Every row produced by the run, in JSON.

# 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": [
        "90210"
    ],
    "maxItemsPerZip": 40,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("dataio/zillow-zip-search-scraper").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": ["90210"],
    "maxItemsPerZip": 40,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("dataio/zillow-zip-search-scraper").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": [
    "90210"
  ],
  "maxItemsPerZip": 40,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call dataio/zillow-zip-search-scraper --silent --output-dataset

```

## MCP server setup

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

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/Htsdu1cQpcjUB32uv/builds/nW3mkfFF5CyPBM91j/openapi.json
