# 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:** 13 total users, 4 monthly users, 100.0% runs succeeded, 3 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $1.00 / 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/actors/running/actors-in-store.md#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

## Zillow Search Scraper

**Scrape Zillow real-estate listings** by location name or search URL. This **Zillow scraper** pulls every home off a Zillow Search Results Page with zpid, full address, price, bedrooms, bathrooms, photos, listing status, broker, coordinates, and 40+ further fields.

No Zillow API key, no login, and no headless browser. Results land in a structured dataset you can export to JSON, CSV, Excel, or XML, or pull straight from the Apify API.

### What is Zillow Search Scraper?

Zillow Search Scraper is an [Apify Actor](https://apify.com/actors) that extracts real-estate search results from [Zillow](https://www.zillow.com) and returns them as clean, structured records. Point it at a city, a ZIP code, or a Zillow URL you have already filtered in the browser, and every filter in that URL is honoured. `slimOutput` trims the payload when you only need the core columns.

### What data can this Zillow scraper extract?

Every run writes one row per property. The full schema carries **73 fields**; the most-used ones are below.

| Field | Type | Description |
| --- | --- | --- |
| `zpid` | string | Zillow property identifier. |
| `id` | string | Zillow internal listing id (often equal to zpid for active listings). |
| `palsId` | string | Provider-and-listing-source identifier. |
| `imgSrc` | string | Hero image for the listing. |
| `hasImage` | boolean | True if Zillow has at least one photo for this listing. |
| `carouselPhotosComposable` | array | Carousel photo data (responsive sources for srcset). Shape varies: array of source objects, or a single object... |
| `detailUrl` | string | Absolute URL of the property's HDP page on Zillow. |
| `statusType` | string | Machine status code (FOR\_SALE | RECENTLY\_SOLD | FOR\_RENT | COMING\_SOON | PENDING). |
| `statusText` | string | Human-readable status label. |
| `rawHomeStatusCd` | string | Zillow's internal raw status code. |
| `marketingStatusSimplifiedCd` | string | Simplified marketing-status code (for\_sale, sold, for\_rent, etc.). |
| `countryCurrency` | string | Currency code (USD, CAD). |
| `price` | string | Listing price as displayed (e.g. "$500,000"). Populated for for-sale and coming-soon listings; rental listings use... |
| `unformattedPrice` | number | Listing price as a number in the listing's currency. See `price` for status-specific alternatives. |
| `soldPrice` | number | Final sold price. Populated only on RECENTLY\_SOLD listings. |
| `baseRent` | number | Monthly base rent. Populated only on FOR\_RENT listings. |
| `minBaseRent` | number | Minimum monthly rent across units. Populated on apartment-building FOR\_RENT listings. |
| `maxBaseRent` | number | Maximum monthly rent across units. Populated on apartment-building FOR\_RENT listings. |
| `units` | array | Per-unit roster on apartment-building listings (each entry has bedrooms, bathrooms, area, price). |
| `isBuilding` | boolean | True when this listing is an apartment community / multi-unit building rather than a single property. Building... |
| `buildingName` | string | Building name |
| `builderName` | string | Builder name |

See the **Output** tab in Apify Console for all 73 fields.

### How to scrape Zillow search results

1. Open [Zillow Search Scraper](https://apify.com/cirkit/zillow-search-scraper) and click **Try for free**.
2. Paste a Zillow search URL into `searchUrls`, or type a place into `locationQueries`.
3. Set `maxItems` and `maxPagesPerSearch` to bound the run.
4. Turn on `slimOutput` if you want a compact row rather than all 70+ fields.
5. Adjust `maxConcurrency` for large multi-region pulls.
6. Click **Start** and watch rows appear live in the **Output** tab.
7. Export the dataset as JSON, CSV, Excel, or XML — or fetch it from the [Apify API](https://docs.apify.com/api/v2) once the run finishes.

### Zillow Search Scraper input options

| Input | Type | What it does | Default |
| --- | --- | --- | --- |
| `searchUrls` | array | URLs of Zillow search queries. Each URL must point to a Zillow search results page; including... | `see schema` |
| `locationQueries` | array | Convenience input: provide locations as strings (`austin-tx`, `90210`, `Seattle, WA`). Each will be converted to a... |  |
| `extractionMethod` | string | How to enumerate listings. **PAGINATION** walks the `/page_p/` URLs and returns up to ~820 listings per search URL —... | `"PAGINATION"` |
| `maxConcurrency` | integer | Parallel requests in flight. 16 is a good balance of speed and proxy pressure; raise it for very large multi-city... | `16` |
| `slimOutput` | boolean | Drop the bulky `carouselPhotosComposable` photo-srcset blob (and a few other rarely-queried fields) from each... | `false` |
| `maxItems` | integer | Hard cap on the number of listings to return. Enforced exactly — the run stops on the item that reaches the cap, so... | `50` |
| `maxPagesPerSearch` | integer | Cap on pages walked per search URL. Zillow itself caps at 20 pages (~820 listings) per region/filter combination. | `5` |

Proxy is configured through the standard `proxyConfiguration` object; the defaults shipped with this Actor are already tuned for the target site.

### Example output

```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"
  }
}
```

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

This Actor runs on **pay per result** pricing: **$0.001 per listing** ($1 per 1,000). A one-time start fee of $0.005 applies per run.

| Results | Approximate cost |
| --- | --- |
| 1,000 | $1.00 |
| 10,000 | $10.01 |
| 100,000 | $100.00 |

You pay for rows you actually receive, so a search that returns nothing costs nothing beyond the start fee. Every Apify account includes free monthly usage credit, so you can trial Zillow Search Scraper at no cost.

### What can you build with Zillow data?

#### Build a market inventory feed

Pull every active listing in a metro daily and diff it to detect new listings, price cuts, and pendings the morning they happen rather than a week later.

#### Generate seller and investor lead lists

Filter to listings with long days-on-market or repeated price reductions — the clearest public signal of a motivated seller.

#### Feed an automated valuation model

zpid, coordinates, beds, baths, square footage, and price across a whole market is the training frame most AVMs start from.

#### Monitor rental supply and asking rents

Rental rows carry base rent ranges and unit counts, so you can track how much rental inventory a submarket is absorbing month over month.

#### Power a real-estate search product

Photos, status, address, and price come back structured enough to render a listings UI directly off the dataset.

### Zillow scraping tips and limits

- Zillow's own search caps how deep it paginates. For full coverage of a large metro, split by ZIP code or draw several smaller map regions rather than one broad query.
- Use a filtered Zillow URL from your browser — price, beds, home type, and sold-status filters all carry through.
- Pair with [Zillow Detail Scraper](https://apify.com/cirkit/zillow-detail-scraper) using the `zpid` field to enrich only the homes worth the extra cost.
- Sold and off-market rows behave differently from active ones. Check `statusType` before treating every row as for-sale inventory.

### Integrations and automation

Run Zillow Search Scraper on a [schedule](https://docs.apify.com/platform/schedules) to keep a Zillow dataset fresh, or trigger it from your own stack through the [Apify API](https://docs.apify.com/api/v2) and the official [JavaScript](https://docs.apify.com/sdk/js) and [Python](https://docs.apify.com/sdk/python) clients. Native [integrations](https://docs.apify.com/platform/integrations) push results into Google Sheets, Slack, Airtable, Zapier, Make, GitHub, or any webhook endpoint. The Actor also works as an [MCP](https://docs.apify.com/platform/integrations/mcp) tool, so an AI agent can call it directly.

### Related scrapers

| Actor | What it does |
| --- | --- |
| [Zillow Detail Scraper](https://apify.com/cirkit/zillow-detail-scraper) | 99+ fields per home: price history, tax history, schools, broker. |
| [Redfin Property Scraper - Homes for Sale, Rent, and Sold Data](https://apify.com/cirkit/redfin-property-scraper) | The same market on Redfin, including sold and coming-soon homes. |
| [Realtor.com Property Scraper (Search + Detail)](https://apify.com/cirkit/realtor-property-scraper) | Realtor.com listings with MLS data and price history. |
| [Apartments.com Listings Scraper](https://apify.com/cirkit/apartments-listings-scraper) | Rental inventory from Apartments.com. |

### Frequently asked questions

#### Can I scrape Zillow without getting blocked?

This Actor handles the request shaping and proxy rotation for you, and the default proxy configuration is already tuned for Zillow. Very aggressive concurrency is the usual cause of trouble, so raise `maxConcurrency` gradually.

#### How do I get full property details, not just search rows?

Take the `zpid` from any search row and feed it to [Zillow Detail Scraper](https://apify.com/cirkit/zillow-detail-scraper), which returns 99 to 141 fields per home including price history, tax history, and schools.

#### Do I need a Zillow API key?

No. Zillow Search Scraper reads publicly available Zillow pages and endpoints directly, so there is no key to obtain, no OAuth app to register, and no account to connect.

#### Can I export Zillow data to CSV, Excel, or Google Sheets?

Yes. Every run stores results in an Apify dataset that exports to JSON, JSONL, CSV, Excel, XML, or HTML with one click, and the Google Sheets integration writes rows straight into a spreadsheet.

#### Can I run Zillow Search Scraper on a schedule?

Yes. Apify schedules run the Actor hourly, daily, weekly, or on any cron expression, and webhooks can notify your systems the moment a run finishes.

#### Is it legal to scrape Zillow?

Scraping publicly available data is broadly lawful in the US and EU, but the answer depends on what you collect and how you use it. This Actor is built to gather public property listing information Zillow publishes publicly, including agent and broker names. Personal data carries extra obligations under GDPR and CCPA. Read Apify's guide on [whether web scraping is legal](https://blog.apify.com/is-web-scraping-legal/) and take your own legal advice for your use case.

### Support and feedback

Found a bug, a missing field, or a Zillow page shape this Actor does not handle yet? Open an issue from the **Issues** tab on the Actor page. Feature requests and custom-scraper enquiries are welcome there too.

# 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 and returns up to ~820 listings per search URL — that is Zillow's own hard cap per region+filter combination. **FULL\_REGION** breaks through that cap: when a search has more than 820 results, the actor recursively splits it into price bands (each band is a separate filter, so each gets its own fresh 820-result window) and paginates every band, then de-duplicates by `zpid`. Use FULL\_REGION when you need every listing in a large metro; it costs proportionally more requests.

## `maxConcurrency` (type: `integer`):

Parallel requests in flight. 16 is a good balance of speed and proxy pressure; raise it for very large multi-city runs, lower it if you are on a small residential proxy pool.

## `slimOutput` (type: `boolean`):

Drop the bulky `carouselPhotosComposable` photo-srcset blob (and a few other rarely-queried fields) from each record. Roughly halves dataset size and transfer cost. `imgSrc` (the hero photo) is always kept.

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

Hard cap on the number of listings to return. Enforced exactly — the run stops on the item that reaches the cap, so you are never charged for overshoot. 0 means unlimited (subject to maxPagesPerSearch and, in PAGINATION mode, 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",
  "maxConcurrency": 16,
  "slimOutput": false,
  "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",
    "maxConcurrency": 16,
    "slimOutput": false,
    "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",
    "maxConcurrency": 16,
    "slimOutput": False,
    "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(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 '{
  "searchUrls": [
    {
      "url": "https://www.zillow.com/austin-tx/"
    }
  ],
  "locationQueries": [],
  "extractionMethod": "PAGINATION",
  "maxConcurrency": 16,
  "slimOutput": false,
  "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": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cirkit/zillow-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/std1byLrPg7xj4cjs/builds/AiNadzhEAHOy00E1S/openapi.json
