# Zillow Scraper: Homes for Sale, Rent & Sold by City or ZIP (`datadesk-io/zillow-listings-scraper`) Actor

Scrape Zillow listings by US city, ZIP or search URL: homes for sale, rentals and recently sold. Address, price, beds, baths, sqft, home type, days on Zillow, Zestimate, coordinates. No login. $3 per 1,000.

- **URL**: https://apify.com/datadesk-io/zillow-listings-scraper.md
- **Developed by:** [DataDesk](https://apify.com/datadesk-io) (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 $2.40 / 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

## Zillow Scraper: Homes for Sale, Rent & Sold by City or ZIP

Get **Zillow listings by city, ZIP code or search URL** as clean JSON/CSV/Excel: **homes for sale, rentals and recently sold**, with address, price, beds, baths, square feet, home type, days on Zillow, Zestimate, coordinates, broker and the listing URL. No login, no browser, no paid proxy.

🇪🇸 **Español:** extrae listados de Zillow (venta, alquiler y vendidos) por ciudad, código postal (ZIP) o URL de búsqueda de EE. UU. Precio, habitaciones, baños, m², tipo de propiedad, días en Zillow, Zestimate y coordenadas. Sin cuenta ni proxy de pago.
🇧🇷 **Português:** extrai anúncios do Zillow (venda, aluguel e vendidos) por cidade, CEP (ZIP) ou URL de busca dos EUA: preço, quartos, banheiros, área, tipo de imóvel, dias no Zillow, Zestimate e coordenadas. Sem login nem proxy pago.

### What you get

- 🏠 **For sale / For rent / Recently sold** in one Actor (`listingType`).
- 📍 **Any US city** (`Austin, TX`), **ZIP** (`78704`) or **a zillow.com search URL** (neighborhoods, map areas, your own filters).
- 🎯 Filters: min/max price (or monthly rent), min bedrooms, min bathrooms.
- 📊 Up to **820 listings per search** (Zillow serves 20 pages of 41). Run several searches in one run; results are deduplicated.
- 💸 **$3 per 1,000 listings**, plus $0.005 per run. Runs with no results cost nothing.

### Pricing

Pay-per-event: **$0.003 per listing** (Store discounts for Silver/Gold/Platinum/Diamond plans) + $0.005 once per run, charged only if at least one listing is found. Searches that return nothing, and duplicates, are free. A spending limit is respected: the run stops cleanly at it.

### Input (all optional)

```json
{
  "searches": ["Austin, TX", "78704", "https://www.zillow.com/homes/for_sale/Denver,-CO_rb/"],
  "listingType": "for_sale",
  "maxListingsPerSearch": 100,
  "minPrice": 300000,
  "maxPrice": 900000,
  "minBeds": 3
}
```

Empty input runs two cities (Austin, TX and Denver, CO) with 50 listings each, in a few seconds.

- Filters apply to cities and ZIPs. When you paste a URL, the URL's own filters are used and the input filters are ignored.
- **Rentals:** Zillow lists many rentals as whole apartment buildings. Those rows have `isBuilding: true` and a `units` list (price and beds per unit) with `minUnitRent`; single homes/apartments carry `price`. Use `includeApartmentBuildings: false` to keep only single listings. `minBeds` for rentals is applied to the unit list.
- **Recently sold:** the search page shows no sold price. You get `dateSold`, the `zestimate` and the home facts, not the sale price.

### Output example (real run, 2026-10-24, shortened)

```json
{
  "zpid": "13420501",
  "listingType": "for_sale",
  "url": "https://www.zillow.com/homedetails/3413-S-Akron-St-Denver-CO-80231/13420501_zpid/",
  "status": "House for sale",
  "address": "3413 S Akron Street, Denver, CO 80231",
  "city": "Denver", "state": "CO", "zipcode": "80231",
  "price": 749000, "priceText": "$749,000",
  "beds": 5, "baths": 3, "livingAreaSqft": 3202,
  "homeType": "SINGLE_FAMILY", "daysOnZillow": 6,
  "taxAssessedValue": 564600,
  "latitude": 39.654552, "longitude": -104.88319,
  "brokerName": "West and Main Homes Inc",
  "openHouse": "Sat. 11am-2pm",
  "search": "Denver, CO", "scrapedAt": "2026-10-24T18:44:08Z"
}
```

`zestimate` / `rentZestimate` appear only when Zillow shows them on the search page.

### Honest limits (read this)

- **Zillow can block scrapers, and this Actor uses no paid proxy.** In our tests (Oct 24, 2026) runs on Apify completed without blocks, including a 20-page / 820-listing run. We have not tested at large scale, and Zillow may start answering 403/429 when you run many searches.
- **If Zillow blocks a request,** the Actor retries with backoff, then falls back to the **Apify datacenter proxy that is included in your plan** (the fallback is capped at 40 requests per run). If it is still blocked, the search stops and **the listings already collected are kept** (and charged); the run status message tells you how many searches were blocked.
- **US only.** Non-US places are not supported.
- **Search pages only:** this Actor reads what Zillow shows in search results. It does not open each listing's detail page, so there is no description, photo gallery, price history or agent contact.
- **Max ~820 listings per search** (Zillow's own limit). To cover a big city, split it by ZIP code.
- Listing data is public, but check Zillow's terms and the laws that apply to your use (copyright, privacy, fair housing, marketing rules) before you reuse it.

### Use cases

Real-estate market analysis · investor deal flow and price monitoring · rental comps · lead lists of active listings by area · feeding AI agents and dashboards with local housing data.

### Scheduling and integrations

Run on a schedule with Apify Schedules and send new data through webhooks, Make, Zapier, n8n or the API. Plain REST: `POST https://api.apify.com/v2/acts/datadesk-io~zillow-listings-scraper/run-sync-get-dataset-items?token=...`.

### Use with AI agents (MCP)

This Actor works as a tool for AI agents through the [Apify MCP server](https://mcp.apify.com). Add it to Claude, ChatGPT, Cursor, VS Code or any MCP client:

`https://mcp.apify.com/?tools=datadesk-io/zillow-listings-scraper`

Sign in with OAuth or `Authorization: Bearer <APIFY_TOKEN>`. Local stdio config:

```json
{"mcpServers": {"zillow": {"command": "npx", "args": ["-y", "@apify/actors-mcp-server", "--tools", "datadesk-io/zillow-listings-scraper"], "env": {"APIFY_TOKEN": "<token>"}}}}
```

**What goes in → what comes out:** Input: US cities, ZIP codes or Zillow search URLs, listing type and optional price/bed/bath filters. Output: one JSON row per listing with address, price, beds, baths, square feet, home type, days on Zillow, Zestimate, coordinates, broker and URL. Every input is optional and every output field is documented.

**Example prompt:** "List the 30 cheapest 3-bedroom homes for sale in Austin, TX and Denver, CO with price per square foot." Use `maxListingsPerSearch` or `maxResults` to cap the cost of one call.

### FAQ

**Does it need cookies or a Zillow account?** No.
**Why are some rental rows empty of price?** They are apartment buildings; use `units` and `minUnitRent`.
**Issues?** Report them on the Issues tab. We usually reply within 48 h.

# Actor input Schema

## `searches` (type: `array`):

US places as "City, ST" (Austin, TX), a 5-digit ZIP (78704) or a full zillow.com search URL (use a URL for neighborhoods or a map area). Non-US places are not supported.

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

For sale, For rent (many rows are apartment buildings with a units list) or Recently sold (the search page shows no sold price; you get dateSold and Zestimate).

## `maxListingsPerSearch` (type: `integer`):

Cap per city/ZIP/URL. Zillow serves at most 20 pages of 41 results (about 820) per search.

## `maxResults` (type: `integer`):

Hard cap on listings for the whole run. Never exceeded.

## `minPrice` (type: `integer`):

Minimum sale price, or minimum monthly rent for rentals. Ignored when you paste a URL.

## `maxPrice` (type: `integer`):

Maximum sale price, or maximum monthly rent for rentals. Ignored when you paste a URL.

## `minBeds` (type: `integer`):

Keep listings with at least this many bedrooms. Ignored when you paste a URL.

## `minBaths` (type: `integer`):

Keep listings with at least this many bathrooms (for sale and sold only). Ignored when you paste a URL.

## `includeApartmentBuildings` (type: `boolean`):

For rentals, Zillow lists whole apartment buildings with several units. Turn off to keep only single listings.

## Actor input object example

```json
{
  "searches": [
    "Austin, TX",
    "Denver, CO"
  ],
  "listingType": "for_sale",
  "maxListingsPerSearch": 50,
  "includeApartmentBuildings": true
}
```

# Actor output Schema

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

One row per listing (see dataset schema for field descriptions).

# 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 = {
    "searches": [
        "Austin, TX",
        "Denver, CO"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("datadesk-io/zillow-listings-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 = { "searches": [
        "Austin, TX",
        "Denver, CO",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("datadesk-io/zillow-listings-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 '{
  "searches": [
    "Austin, TX",
    "Denver, CO"
  ]
}' |
apify call datadesk-io/zillow-listings-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datadesk-io/zillow-listings-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/plAV2H0G15qhXbPwh/builds/LVZIeVyte4yVljWvZ/openapi.json
