# Zillow Search Scraper (`cirkit/zillow-search-scraper`) Actor

Scrape Zillow real-estate listings by location or search URL. Extracts zpid, address, price, beds/baths, photos, status, broker, lat/lon, and 40+ more fields from Zillow Search Results Pages.

- **URL**: https://apify.com/cirkit/zillow-search-scraper.md
- **Developed by:** [Crikit](https://apify.com/cirkit) (community)
- **Categories:** Real estate
- **Stats:** 8 total users, 2 monthly users, 98.1% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.60 / 1,000 results

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### What this Zillow Search Scraper does

This Zillow Search Scraper extracts real estate listing data from Zillow Search Results Pages at scale. Give it a Zillow search URL (or a location string like `austin-tx`, `90210`, `Seattle, WA`) and the actor walks every page in the search, parses Zillow's server-rendered JSON payload, and emits one structured record per listing. No login, no cookies, no API key. The actor works entirely from public search pages on `zillow.com`.

The Zillow Search Scraper is built for analytics, lead generation, and market intelligence use cases that need clean Zillow data without writing a scraper from scratch.

### What you get per listing

The actor extracts all 60+ fields Zillow embeds in each search result, including:

- **Identity**: `zpid`, `id`, `palsId`, `detailUrl` (link to the property's HDP page on Zillow)
- **Address**: `address`, `addressStreet`, `addressCity`, `addressState`, `addressZipcode`, `isUndisclosedAddress`
- **Pricing**: `price`, `unformattedPrice` (numeric), `countryCurrency`, `shouldShowZestimateAsPrice`, `shouldShowRequestOnPrice`
- **Physical**: `beds`, `baths`, `area` (sqft), `latLong` (latitude/longitude)
- **Status**: `statusType` (`FOR_SALE` / `RECENTLY_SOLD` / `FOR_RENT` / `COMING_SOON` / `PENDING`), `statusText`, `rawHomeStatusCd`, `marketingStatusSimplifiedCd`, `availabilityDate`
- **Media**: `imgSrc` (hero photo), `hasImage`, `has3DModel`, `hasVideo`, `carouselPhotosComposable` (responsive photo srcset)
- **Open house**: `hasOpenHouse`, `openHouseStartDate`, `openHouseEndDate`, `openHouseDescription`
- **Broker / attribution**: `brokerName`, `isFeaturedListing`, `isShowcaseListing`, `isZillowOwned`, `isPaidBuilderNewConstruction`
- **Provenance** (added by the actor): `foundOnSearchPage`, `foundFromSearchUrl`

Every field that Zillow returns flows through to your dataset, so when Zillow adds a new attribute, your dataset gets it on the next run with no schema changes.

### Why use this Zillow Scraper

- **30% cheaper than the leading competitor** on Apify Store ($0.0016 per listing on FREE tier vs the leader's $0.0023). Tier discounts apply automatically.
- **100% field match** with the leading competitor on the same input (820 / 820 listings on a full Austin scrape, validated against ground truth).
- **No cookies, no logins**. You never paste credentials. The scraper works from a clean Apify residential proxy session.
- **Crawlee + Cheerio + Apify residential proxy**, so it survives Zillow's PerimeterX anti-bot stack without spinning up a browser. Costs less than browser-based scrapers and runs about 5x faster.
- **Stable schema**. The output mirrors Zillow's own `listResults` shape; downstream pipelines that already parse Zillow data work without modification.

### Input

| Field | Type | Description |
|---|---|---|
| `searchUrls` | array of `{url}` | Zillow search URLs. Anything that resolves to a Search Results Page works (e.g. `https://www.zillow.com/austin-tx/`, `https://www.zillow.com/homes/for_sale/?searchQueryState=...`). |
| `locationQueries` | array of strings | Convenience input. Strings like `austin-tx`, `90210`, `Seattle, WA` are auto-converted to Zillow URL slugs. |
| `extractionMethod` | string | Currently only `PAGINATION` is supported (walks `_p/` pages, up to ~820 listings per search slice). MAP\_MARKERS and zoom-tiling modes are planned for v2. |
| `maxItems` | integer | Hard cap on listings returned. `0` = unlimited (still bounded by `maxPagesPerSearch` and Zillow's own 820 cap per slice). |
| `maxPagesPerSearch` | integer | Cap on pages walked per search URL. Zillow itself only paginates up to 20 pages (~820 listings) per region+filter combination. |
| `proxyConfiguration` | object | Apify proxy settings. **Residential US strongly recommended**; datacenter IPs get flagged within a handful of requests by PerimeterX. |

You must supply at least one of `searchUrls` or `locationQueries`.

### Sample input

```json
{
  "searchUrls": [
    { "url": "https://www.zillow.com/austin-tx/" },
    { "url": "https://www.zillow.com/seattle-wa/condos/" }
  ],
  "locationQueries": ["90210"],
  "extractionMethod": "PAGINATION",
  "maxItems": 200,
  "maxPagesPerSearch": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"],
    "apifyProxyCountry": "US"
  }
}
```

### Sample output

```json
{
  "zpid": "338246448",
  "id": "338246448",
  "palsId": "222004_40830219",
  "address": "2500 Longview St #518, Austin, TX 78705",
  "addressCity": "Austin",
  "addressState": "TX",
  "addressZipcode": "78705",
  "price": "$500,000",
  "unformattedPrice": 500000,
  "beds": 2,
  "baths": 2,
  "area": 1010,
  "latLong": { "latitude": 30.289932, "longitude": -97.75102 },
  "statusType": "FOR_SALE",
  "statusText": "For Sale",
  "imgSrc": "https://photos.zillowstatic.com/fp/example-cc_ft_960.jpg",
  "brokerName": "Compass RE Texas, LLC",
  "detailUrl": "https://www.zillow.com/homedetails/2500-Longview-St-518-Austin-TX-78705/338246448_zpid/",
  "foundOnSearchPage": 1,
  "foundFromSearchUrl": "https://www.zillow.com/austin-tx/"
}
```

### Measured coverage

Validated by running the same input as the leading competitor (Austin TX, full 820-result pull) and comparing:

| Metric | Value |
|---|---|
| Listings overlap with competitor | **820 / 820** (100.0%) |
| Field-name match | **61 / 61** fields |
| Critical fields (zpid, address, price, beds/baths, lat/lon, statusType, brokerName, imgSrc, detailUrl) | **97.6% to 100%** coverage, **100% value match** on overlapping records |

Fields that are present on a subset of listings (rentals only, land only, providerListing only) flow through automatically when Zillow includes them in the source data.

### Pricing

Pay-per-result, $0.0016 per listing on the FREE tier. Apify's tier discounts apply automatically (BRONZE/SILVER/GOLD/PLATINUM/DIAMOND).

Worked examples (FREE tier):

- 100 listings: $0.16
- 1,000 listings: $1.60
- 10,000 listings: $16.00
- One full Austin TX scrape (~820 listings): about $1.31

Compare to the leading Zillow search scraper on Apify Store at $0.0023 per listing on FREE tier (about 30% more).

### Limits and edge cases

- **820 listings per (region, filter) slice.** Zillow caps `/page_p/` pagination at 20 pages of 41 listings = 820. To exceed this for a region with more inventory, either (a) split your search by neighborhood / ZIP / price range and run the actor on each slice, or (b) wait for the v2 zoom-tiling mode.
- **Geo gating.** Run on a US Apify proxy. Zillow auto-redirects non-US IPs to localized pages (Canadian IPs get Canadian listings).
- **Restricted listings.** Some states (e.g. NY, parts of CA) hide certain listings from unauthenticated viewers. They appear in `restrictedListingCount` totals on Zillow but are not in the returned `listResults`. This affects approximately 1-3% of listings in affected markets.
- **PerimeterX retries.** Zillow runs PerimeterX bot detection. Expect 1-2 retries per 20-request batch; the actor handles this transparently with session rotation. If your concurrency is very high you may see your request count exceed your listing count by 10-15%.
- **Live data.** Zillow listings change continuously (new postings, price changes, sold transitions). Running the same input twice will return slightly different listings if the underlying market moved.

### Technical details

- **Stack**: Node.js 20 + Crawlee `CheerioCrawler` + `got-scraping` with Chrome `header generator`. No browser, no JavaScript execution.
- **Memory footprint**: 512 MB recommended.
- **Throughput**: about 50,000 listings per hour at default concurrency on Apify residential proxy.
- **TLS**: `got-scraping` uses Chrome's HTTP/2 SETTINGS frame and realistic headers to bypass Zillow's JA3 fingerprinting.

### FAQ

**Does this Zillow Search Scraper need an API key?** No. Zillow's web search is publicly accessible; the actor reads the same data anyone can see in a browser.

**Does it need my Zillow login or cookies?** No. This scraper never asks for user credentials.

**What's the difference between this and `maxcopell/zillow-detail-scraper`?** This actor extracts the search-page listing card (60+ fields). For deeper details on a single property (RESO facts, price history, tax history, schools, full photo set), use a detail page scraper that takes a `zpid` or detail URL as input.

**Can I run it via the Apify API or schedule it?** Yes, like any Apify actor. Use the standard Run actor API or attach a schedule in the Apify Console.

### Changelog

- **0.1** (2026-05-14): initial release. PAGINATION mode (up to 820 listings per search slice). 61-field output matches competitor schema 1:1.

# Actor input Schema

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

URLs of Zillow search queries. Each URL must point to a Zillow search results page; including `?searchQueryState=...` is supported and preserved during pagination. Example: https://www.zillow.com/austin-tx/ or https://www.zillow.com/homes/for\_sale/?searchQueryState=...

## `locationQueries` (type: `array`):

Convenience input: provide locations as strings (`austin-tx`, `90210`, `Seattle, WA`). Each will be converted to a Zillow URL slug.

## `extractionMethod` (type: `string`):

How to enumerate listings. PAGINATION walks the `/page_p/` URLs (up to ~820 listings per search slice). This is currently the only supported mode; MAP\_MARKERS and PAGINATION\_WITH\_ZOOM\_IN are planned.

## `maxItems` (type: `integer`):

Hard cap on the number of listings to return. 0 means unlimited (subject to maxPagesPerSearch and Zillow's ~820 cap per search URL).

## `maxPagesPerSearch` (type: `integer`):

Cap on pages walked per search URL. Zillow itself caps at 20 pages (~820 listings) per region/filter combination.

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

Proxy settings. Residential proxies in the US are strongly recommended; Zillow runs PerimeterX bot detection on the origin and datacenter IPs are flagged within a few requests.

## Actor input object example

```json
{
  "searchUrls": [
    {
      "url": "https://www.zillow.com/austin-tx/"
    }
  ],
  "locationQueries": [],
  "extractionMethod": "PAGINATION",
  "maxItems": 50,
  "maxPagesPerSearch": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

## `datasetItems` (type: `string`):

All listings collected by this run, one record per property.

## `datasetItemsCsv` (type: `string`):

All listings in CSV format.

## `datasetItemsXlsx` (type: `string`):

All listings in Excel format.

## `consoleRun` (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 = {
    "searchUrls": [
        {
            "url": "https://www.zillow.com/austin-tx/"
        }
    ],
    "locationQueries": [],
    "extractionMethod": "PAGINATION",
    "maxItems": 50,
    "maxPagesPerSearch": 5,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("cirkit/zillow-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 = {
    "searchUrls": [{ "url": "https://www.zillow.com/austin-tx/" }],
    "locationQueries": [],
    "extractionMethod": "PAGINATION",
    "maxItems": 50,
    "maxPagesPerSearch": 5,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("cirkit/zillow-search-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "searchUrls": [
    {
      "url": "https://www.zillow.com/austin-tx/"
    }
  ],
  "locationQueries": [],
  "extractionMethod": "PAGINATION",
  "maxItems": 50,
  "maxPagesPerSearch": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call cirkit/zillow-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=cirkit/zillow-search-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/std1byLrPg7xj4cjs/builds/GbVJuJmf7lN7Zk0nO/openapi.json
