# Zillow Scraper (`steadyscrape/zillow-scraper`) Actor

Zillow homes for sale, for rent and sold, by place, search link or property link: price, Zestimate, beds, baths, days on Zillow; optionally price and tax history, schools, every fact, agent, views and saves, and apartment buildings with each unit's rent. Whole cities.

- **URL**: https://apify.com/steadyscrape/zillow-scraper.md
- **Developed by:** [Steady Scrape](https://apify.com/steadyscrape) (community)
- **Categories:** Real estate, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 properties

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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 Scraper do?

**Zillow Scraper** extracts **every home for sale, for rent or recently sold in any US place** — a city, a ZIP code, a county, a neighborhood, or any Zillow search link with your filters — with price, Zestimate and Rent Zestimate, beds, baths, square feet, lot, home type, days on Zillow, price cuts, tax assessed value, broker and coordinates. Turn on **listing details** and each home also comes with its **price history, tax history, schools, every fact Zillow lists** (heating, cooling, parking, HOA, appliances, construction…), **listing agent and broker, page views and saves**, description and all photos. Apartment buildings come with **each floor plan and every available unit's rent and move-in date**.

**It reads whole cities.** Zillow shows at most 820 listings per search, which is why other scrapers stop there. This one splits the map into cells until each one fits and returns every listing in the area, once: **Austin for sale, 5,090 homes in 20 seconds**.

### Why use it?

- 🏘️ **Real estate investing** — every listing of a market with price, Zestimate, rent estimate and days on market, to find deals and estimate yields.
- 📉 **Market analysis** — inventory, price cuts and days on Zillow by ZIP code or neighborhood; recently sold homes with their sale price and date for comps.
- 🏢 **Rental research** — apartment buildings with every floor plan, each available unit's rent and move-in date, fees, pets and special offers.
- 🔔 **Monitoring** — schedule it on a search and see new listings, price changes and homes going pending.
- 🤖 **Feed dashboards, CRMs, sheets and AI agents** — JSON, CSV or Excel, or straight into Google Sheets, Make or Zapier through Apify integrations.

### Features

- ✅ **By place, search link or property link** — type `Austin, TX`, `78704` or `Brooklyn, NY`; paste a Zillow search link with any filters (price, beds, baths, home type, keywords, the map area you drew); or paste home and building links, or bare zpids.
- ✅ **For sale, for rent, recently sold** — pick the listing type for places; search links carry their own.
- ✅ **Full coverage** — past Zillow's 820-result limit, the whole area cell by cell, each property once.
- ✅ **Homes, buildings and new-construction communities** — each row says which (`kind`), with the fields that fit it.
- ✅ **Listing details** — price history, tax history, schools with ratings, ~190 facts, agent and broker with phones, MLS id, parcel id, HOA, property tax rate, page views and saves, description, all photos in full size.
- ✅ **Apartment buildings** — floor plans with beds, baths, square feet and price range, every available unit with its rent and move-in date, amenities, pets, special offers, walk/transit/bike scores, phone and manager.
- ✅ **Hard limits and fair billing** — the maximum per search is a hard stop, the spending limit is checked before any page is read, a property found twice is charged once, and links Zillow does not know are reported and **not charged**. No start fee.

### How to scrape Zillow

1. Click **Try for free**.
2. Type **locations** and pick **for sale, for rent or sold** — or paste **search links** or **property links**.
3. Optionally set a **maximum per search** and turn on **Include listing details**.
4. Click **Start** and download the properties as JSON, CSV or Excel. To monitor, add a [schedule](https://docs.apify.com/platform/schedules).

### Input example

```json
{
    "locations": ["Austin, TX", "78704"],
    "listingType": "forSale",
    "searchUrls": ["https://www.zillow.com/homes/for_rent/Austin,-TX_rb/"],
    "propertyUrls": ["https://www.zillow.com/homedetails/7560392_zpid/", "https://www.zillow.com/apartments/phoenix-az/seven-(az)/636CVJ/"],
    "includeDetails": true,
    "maxItemsPerSearch": 0,
    "fullCoverage": true
}
```

### Output example

A home, with listing details (lists shortened):

```json
{
    "kind": "home",
    "id": "7560392",
    "zpid": "7560392",
    "url": "https://www.zillow.com/homedetails/4048-E-Edgemont-Ave-Phoenix-AZ-85008/7560392_zpid/",
    "status": "FOR_SALE",
    "address": "4048 E EDGEMONT Avenue, Phoenix, AZ 85008",
    "street": "4048 E EDGEMONT Avenue", "city": "Phoenix", "state": "AZ", "zipcode": "85008",
    "latitude": 33.479282, "longitude": -111.9934,
    "price": 1600000,
    "currency": "USD",
    "homeType": "SINGLE_FAMILY",
    "bedrooms": 5, "bathrooms": 5, "livingArea": 3370, "lotArea": 10685, "lotAreaUnit": "sqft",
    "zestimate": null, "rentZestimate": null, "taxAssessedValue": 518600,
    "daysOnZillow": 167,
    "priceChange": -49000, "priceChangeDate": "2026-09-23",
    "listingSubType": ["newConstruction"],
    "brokerName": "HomeSmart",
    "details": {
        "yearBuilt": 2026,
        "propertyType": "Single Family",
        "lastSoldPrice": 522500, "dateSold": "2024-10-24",
        "propertyTaxRate": 0.41,
        "county": "Maricopa County", "parcelId": "12601083", "mlsId": "7007889",
        "pageViews": 2388, "saves": 246,
        "listingAgent": { "name": "Kristina Cat", "phone": "734-306-0569", "email": null, "licenseNumber": null },
        "broker": { "name": "HomeSmart", "phone": "602-230-7600" },
        "priceHistory": [{ "date": "2026-09-23", "event": "Price change", "price": 1600000, "pricePerSquareFoot": 475, "source": "ARMLS" }],
        "taxHistory": [{ "year": 2025, "taxPaid": 1819.7, "assessedValue": 51860 }],
        "schools": [{ "name": "Griffith Elementary School", "rating": 3, "distance": 0.9, "grades": "K-5", "level": null, "link": "https://www.greatschools.org/arizona/phoenix/754-Griffith-Elementary-School/" }],
        "facts": { "heating": ["ENERGY STAR Qualified Equipment", "Electric"], "cooling": ["Central Air", "Ceiling Fan(s)"], "parkingCapacity": 4, "hasGarage": true, "stories": 1 },
        "photos": ["https://photos.zillowstatic.com/fp/d74149e3a77bbdb4db14441e5bd9d0b8-uncropped_scaled_within_1536_1152.jpg"]
    },
    "building": null
}
```

An apartment building, with its page:

```json
{
    "kind": "building",
    "id": "1136159192",
    "url": "https://www.zillow.com/apartments/phoenix-az/seven-(az)/636CVJ/",
    "status": "FOR_RENT",
    "address": "19800 N 7th St, Phoenix, AZ 85024",
    "rentMin": 1357, "rentMax": 2052,
    "buildingName": "Seven (AZ)",
    "availableUnits": 13,
    "building": {
        "phone": "(928) 440-9094", "manager": "Greystar",
        "buildingFacts": ["216 units", "3 stories", "built in 2014"],
        "pets": ["Cats", "Large dogs", "Small dogs"],
        "specialOffers": ["Four Weeks Base Rent Free When You Move In by 11/1/2026*. Minimum Lease Terms Apply. Costs & Fees Excluded."],
        "walkScore": 26, "transitScore": 33, "bikeScore": 37,
        "floorPlans": [{ "name": "1X1", "beds": 1, "baths": 1, "sqft": 747, "minPrice": 1374, "maxPrice": 1473, "availableFrom": "2026-10-13", "units": [{ "unitNumber": "Unit 1081", "zpid": "2091638977", "price": 1454, "sqft": 747, "availableFrom": "2026-11-02" }] }]
    }
}
```

### Output fields

| field | meaning |
|---|---|
| `kind` | `home`, `building` (an apartment building or a multi-unit building) or `community` (new construction). |
| `id`, `zpid`, `url` | The zpid of a home; Zillow's lot or plan id of a building or community. |
| `status`, `statusText` | `FOR_SALE`, `FOR_RENT`, `SOLD`/`RECENTLY_SOLD`… and Zillow's label ("Active", "House for rent"). |
| `address`, `street`, `city`, `state`, `zipcode`, `unit`, `latitude`, `longitude` | Where it is. |
| `price`, `priceText` | Asking price, monthly rent or sold price, and the price as Zillow shows it. **A sold home's price is hidden in search results: turn on listing details to get it.** |
| `rentMin`, `rentMax`, `availableUnits`, `buildingName` | A building's base rent range (before required fees) and available units; a community's name and builder (`brokerName`). |
| `homeType`, `bedrooms`, `bathrooms`, `livingArea`, `lotArea`, `lotAreaUnit` | `livingArea` in square feet; `lotAreaUnit` is `sqft` or `acres`. |
| `zestimate`, `rentZestimate`, `taxAssessedValue` | Zillow's estimates (Zillow hides the Zestimate on many listed homes). |
| `daysOnZillow`, `priceChange`, `priceChangeDate`, `dateSold`, `listingSubType` | Market signals; `listingSubType` lists `forSaleByAgent`, `forSaleByOwner`, `newConstruction`, `foreclosure`, `bankOwned`, `auction`, `comingSoon`, `pending`, `openHouse`. |
| `details` | With **Include listing details**, for a home: see the example. `facts` is every fact Zillow lists, as Zillow names it. |
| `building` | With **Include listing details**, for an apartment building: see the example. |
| `searchLocation`, `resolvedLocation`, `scrapedAt` | The search or link the row came from, where Zillow resolved the place ("Austin TX"), and when (UTC). |

The run's **SUMMARY** record lists, per search, Zillow's own count, how many properties came out and how many requests it took, and any search or link that was refused, not found or not a place (those are not charged).

### Limits and tips

- **Zillow covers the United States.** A place it cannot find resolves to some city: check `resolvedLocation`. A place it takes for a single property is reported, not searched.
- **Full coverage** reads a city of ~5,000 listings with ~35 requests in about 20 seconds. Rentals are mostly buildings: a big city has tens of thousands of units in a few thousand buildings.
- **Listing details** cost one request per property: about 30 homes in 25 seconds. New-construction communities are returned from the search without a page.
- Prices are in US dollars; rents are monthly.

### Is it legal to scrape Zillow?

This Actor reads only data Zillow shows publicly to anyone, without logging in. Listing agents' and brokers' names and phone numbers are the business contacts Zillow publishes with each listing. Scraping public data is generally legal; still, make sure your use complies with Zillow's terms and the laws that apply to you, and use it responsibly. Read Apify's [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/) guide.

### Your feedback

Missing a field or a filter? Open an issue on the **Issues** tab: issues are answered, and the Actor is checked against the live site so it keeps working when Zillow changes.

# Actor input Schema

## `locations` (type: `array`):

Places as you would type them on Zillow: <code>Austin, TX</code>, <code>78704</code>, <code>Brooklyn, NY</code>, a county or a neighborhood. Zillow covers the United States.

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

What to search for in the locations above. Search links carry their own.

## `searchUrls` (type: `array`):

Zillow search links, with every filter they carry (price, beds, baths, home type, keywords) and the map area you drew or moved to. Set the filters on Zillow, then paste the address bar here.

## `propertyUrls` (type: `array`):

Homes (<code>https://www.zillow.com/homedetails/…\_zpid/</code> or just the zpid number) and apartment buildings (<code>https://www.zillow.com/apartments/…</code>). Each one is read from its own page, with all its details.

## `includeDetails` (type: `boolean`):

Read each property's own page too: description, price history, tax history, schools, every fact Zillow lists (heating, parking, HOA, appliances…), agent and broker, page views and saves, all photos; for an apartment building, its floor plans with each available unit's rent and move-in date. One extra request per property, and the price of a property with details.

## `maxItemsPerSearch` (type: `integer`):

0 = everything the search finds. A hard limit: nothing past it is read or charged.

## `fullCoverage` (type: `boolean`):

Zillow shows at most 820 listings per search and answers about 500 per map area. On, a search with more is read map cell by map cell until every listing is in. Off, only the first answer.

## Actor input object example

```json
{
  "locations": [
    "78704"
  ],
  "listingType": "forSale",
  "searchUrls": [],
  "propertyUrls": [],
  "includeDetails": false,
  "maxItemsPerSearch": 20,
  "fullCoverage": true
}
```

# Actor output Schema

## `properties` (type: `string`):

No description

## `summary` (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 = {
    "locations": [
        "78704"
    ],
    "searchUrls": [],
    "propertyUrls": [],
    "maxItemsPerSearch": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("steadyscrape/zillow-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 = {
    "locations": ["78704"],
    "searchUrls": [],
    "propertyUrls": [],
    "maxItemsPerSearch": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("steadyscrape/zillow-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 '{
  "locations": [
    "78704"
  ],
  "searchUrls": [],
  "propertyUrls": [],
  "maxItemsPerSearch": 20
}' |
apify call steadyscrape/zillow-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,steadyscrape/zillow-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/8AHKnyNBcGNIaeyq5/builds/vB7tQTNdCsUozvtKp/openapi.json
