# Zillow scraper (`lukass/zillow-scraper`) Actor

- **URL**: https://apify.com/lukass/zillow-scraper.md
- **Developed by:** [Lukáš Širhal](https://apify.com/lukass) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.70 / 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.
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?

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 Scraper — For Sale, For Rent & Sold

**Scrape Zillow listings by location, search URL or ZPID — no Zillow API key, no browser, no captured credentials.**

Type a place name (`Los Angeles`, `Melrose, Bronx`, `90210`), paste a Zillow search URL, or hand it a list of ZPIDs, and get every for-sale, for-rent or recently-sold listing: price, address, coordinates, beds and baths, living area, lot size, year built, Zestimate, tax assessment, open houses, broker, 3D tour and every listing photo.

Filter exactly as you would in the Zillow app — price, beds, baths, home type, square feet, lot size, year built, days on market, HOA, keywords, views, basement, pool, waterfront, pets, laundry — and sort the results the same way.

### ✨ Why this Zillow scraper

| | This scraper | Typical Zillow scraper |
|---|---|---|
| Input | Place name, Zillow URL, or ZPIDs | Usually a hand-crafted `?searchQueryState=…` URL only |
| Engine | Direct API calls | Headless browser + HTML parsing |
| Detail request per listing | Not needed — the search response is already complete | Often a second, billed request per property |
| Result ceiling per area | Unlimited via automatic map splitting | Often ~500 or ~820 per URL |
| Credentials | None | Sometimes an API key or a login |

Zillow caps any single search at **1,000 results**. This Actor works around that cap by splitting the map into quadrants and searching each one, so a dense metro is scraped completely rather than truncated at the first page.

### 🚪 What it can do

- **🔎 Search by free text** — city, borough, county, neighborhood, ZIP, subdivision or state.
- **🔗 Or paste Zillow URLs** — a search URL's map area *and* its filters are read straight out of `searchQueryState`; a property URL is fetched by its ZPID.
- **🆔 Or give it ZPIDs** — fetch specific properties directly, no search involved.
- **🏷️ For sale, for rent, or recently sold** — one switch.
- **🎛️ The Zillow app's own filters** — price, beds, baths, home type, square feet, lot size, year built, days on market (or *sold within* for sold listings), keywords, HOA, basement, view, pool, air conditioning, waterfront, parking, open houses, 3D tours, price cuts, foreclosures — plus pets, laundry, parking and availability date for rentals.
- **↕️ Sorting** — price, newest, beds, baths, square feet, lot size or year built, ascending or descending.
- **📦 Full listing data in a single request** — no second request per property.
- **🗺️ Automatic map splitting** — beats Zillow's 1,000-per-search cap.
- **♻️ Resumable** — results are deduplicated by `zpid` and counters survive a migration, so a restarted run does not re-push what it already scraped.
- **⬇️ Export anywhere** — JSON, CSV, Excel, XML or HTML, via the Apify API, integrations or webhooks.

### 🎯 What can you do with Zillow data?

- **Market research** — track median prices, days on market and inventory across neighborhoods over time.
- **Comparable sales** — pull recently sold listings with `lastSoldDate` and price per square foot to value a property.
- **Deal finding** — scrape for-sale listings with `zestimate` and `priceChange`, and filter for homes priced under their Zestimate or recently reduced.
- **Rental analysis** — collect rents by bedroom count and compare against `rentZestimate` for yield estimates.
- **Lead generation** — collect listings with broker and agent names in a target area.
- **New-listing alerts** — schedule a run with `daysOnZillowMax: 1` and a webhook to be notified of everything listed today.

### 📚 How do I scrape Zillow?

1. Create a free Apify account.
2. Open this Actor and tell it what to scrape — put a location in the **Search** field (e.g. `Los Angeles`), paste Zillow URLs into **Zillow URLs**, or list **ZPIDs**. One of the three is enough.
3. Pick a **Listing type** — for sale, for rent, or recently sold.
4. Optionally set filters and a sort order. They work the same way as the filter sheet in the Zillow app.
5. Set **Limit the number of items** (or leave it empty to scrape everything).
6. Click **Start**, then download the results as JSON, CSV, Excel, XML or HTML.

### ⬇️ Input

Give it **one** of `search`, `startUrls` or `zpids`. Everything else is optional.

| Field | Type | Default | Description |
|-----------------|---------|---------|-------------|
| `search` | String | — | Location to search, e.g. `Los Angeles`, `Melrose, Bronx`, `90210` |
| `startUrls` | Array | — | Zillow search URLs (must include `?searchQueryState=…`) or property URLs |
| `zpids` | Array | — | Zillow property IDs, e.g. `89070667` |
| `type` | String | `sale` | `sale`, `rent`, or `sold` |
| `maxItems` | Integer | `200` | Maximum properties to return; empty means no limit |
| `maxSplitLevel` | Integer | `3` | How deep a map area may be split — see [Map splitting](#-map-splitting) |
| `proxy` | Object | Apify Proxy | Proxy configuration — US residential recommended |
| `debugLog` | Boolean | `false` | Verbose logging |

#### Filters

All optional. Leave one empty to not apply it.

| Field | Type | Description |
|---|---|---|
| `priceMin`, `priceMax` | Integer | Price range. For `rent`, the monthly rent |
| `bedsMin`, `bedsMax` | Integer | Bedrooms |
| `bathsMin` | Integer | Bathrooms (half baths count, so `2` also matches 2.5) |
| `homeTypes` | Array | `singleFamily`, `condo`, `townhome`, `multiFamily`, `apartment`, `manufactured`, `land` |
| `sqftMin`, `sqftMax` | Integer | Living area in square feet |
| `lotSizeMin`, `lotSizeMax` | Integer | Lot size in square feet (1 acre = 43,560) |
| `yearBuiltMin`, `yearBuiltMax` | Integer | Year built |
| `daysOnZillowMax` | Integer | Listed within N days — for `sold`, **sold** within N days |
| `keywords` | String | Free text over the listing description, e.g. `pool` |
| `showOnly` | Array | `priceReduction`, `openHouses`, `approvedVirtualTour`, `singleStory`, `garage` |
| `amenities` | Array | `havePool`, `haveAirConditioning`, `onWaterfront` |
| `parkingSpotsMin` | Integer | Minimum parking spots |
| `basementStatuses` | Array | `finished`, `partial`, `unfinished` |
| `viewTypes` | Array | `city`, `mountain`, `water`, `park` |
| `hoaMaxPerMonth` | Integer | Maximum monthly HOA fee |
| `includeHomesWithNoHoaData` | Boolean | Keep listings with unknown HOA (default `true`) |
| `includePending` | Boolean | Keep pending / under-contract listings (hidden by default) |
| `includeForeclosed`, `includePreforeclosure` | Boolean | Add (pre-)foreclosures |
| `pets` | Array | *Rentals* — `largeDogs`, `smallDogs` |
| `rentalAmenities` | Array | *Rentals* — `laundryAvailable`, `parkingAvailable` |
| `availableFrom` | String | *Rentals* — available on or after `YYYY-MM-DD` |
| `excludeSeniorCommunity` | Boolean | *Rentals* — drop 55+ communities |
| `sortOrder` | String | `relevance`, `price`, `beds`, `baths`, `daysOn`, `recentlyChanged`, `livingArea`, `lotArea`, `yearBuilt` |
| `sortAscending` | Boolean | Low to high instead of high to low |

### 🧪 Example inputs

**Family homes in a city, under $1.5M:**

```json
{
  "search": "Austin, TX",
  "type": "sale",
  "priceMax": 1500000,
  "bedsMin": 3,
  "bathsMin": 2,
  "homeTypes": ["singleFamily"],
  "sortOrder": "price",
  "sortAscending": true,
  "maxItems": 500
}
```

**Everything listed today, for a daily alert:**

```json
{
  "search": "90210",
  "type": "sale",
  "daysOnZillowMax": 1
}
```

**Pet-friendly rentals with in-unit laundry, available next month:**

```json
{
  "search": "Brooklyn, NY",
  "type": "rent",
  "priceMin": 2000,
  "priceMax": 4000,
  "pets": ["largeDogs", "smallDogs"],
  "rentalAmenities": ["laundryAvailable"],
  "availableFrom": "2026-10-01"
}
```

**Comparable sales from the last 6 months:**

```json
{
  "search": "Melrose, Bronx",
  "type": "sold",
  "daysOnZillowMax": 182,
  "homeTypes": ["singleFamily", "condo"]
}
```

**From a Zillow search URL, filters and all:**

```json
{
  "startUrls": [
    { "url": "https://www.zillow.com/bronx-new-york-ny/?searchQueryState=%7B%22mapBounds%22%3A%7B...%7D%7D" }
  ]
}
```

**Specific properties by ZPID:**

```json
{ "zpids": ["89070667", "448148857"] }
```

### 🌳 What data can I extract?

<table>
<tr><td>🏠 Full address</td><td>💰 Price and price per sqft</td></tr>
<tr><td>🛏️ Bedrooms and bathrooms</td><td>📍 Latitude and longitude</td></tr>
<tr><td>📅 Listing date</td><td>⏳ Days on Zillow</td></tr>
<tr><td>📷 All listing photos</td><td>📏 Living area and lot size</td></tr>
<tr><td>💼 Broker and agent name</td><td>🚪 Open house times</td></tr>
<tr><td>🏠 Home type and status</td><td>🏗️ Year built</td></tr>
<tr><td>🔗 Listing URL</td><td>🏢 ZPID</td></tr>
<tr><td>💸 Rent Zestimate</td><td>💵 Zestimate</td></tr>
<tr><td>🧾 Tax assessed value</td><td>📉 Price change</td></tr>
<tr><td>🎥 Video and 3D tour</td><td>📐 Floor plan availability</td></tr>
</table>

### ⬆️ Output

One dataset item per property. All three examples below are real, unedited items.

#### For sale

```jsonc
{
  "zpid": 89070667,
  "url": "https://www.zillow.com/homedetails/89070667_zpid/",
  "homeStatus": "forSale",
  "marketingStatus": "active",
  "homeType": "condo",
  "price": 299999,
  "currency": "usd",
  "pricePerSquareFoot": 452,
  "zestimate": null,
  "rentZestimate": null,
  "taxAssessedValue": 73950,
  "taxAssessmentYear": 2025,
  "address": {
    "streetAddress": "837 Washington Avenue #3B",
    "city": "Bronx",
    "state": "NY",
    "zipcode": "10451"
  },
  "latitude": 40.822433,
  "longitude": -73.91177,
  "bedrooms": 1,
  "bathrooms": 1,
  "fullBathrooms": 1,
  "halfBathrooms": 0,
  "livingArea": 664,
  "lotSize": 0.5089072543617998,
  "lotSizeUnit": "acres",
  "yearBuilt": 2008,
  "daysOnZillow": 1,
  "listingDate": "2026-08-24T17:43:05.566Z",
  "isZillowOwned": false,
  "isShowcaseListing": false,
  "brokerName": "Listing by: Century 21 Milestone Team Rlty",
  "openHouse": [{ "startTime": "2026-08-29T16:00:00.000Z", "endTime": "2026-08-29T17:00:00.000Z" }],
  "hasFloorPlan": true,
  "virtualTour": "https://www.zillow.com/view-3d-home/8644b1a0-852b-40d0-8f9f-db458d6bce55",
  "photos": ["https://photos.zillowstatic.com/fp/e53c22aded73ef47a29c8f666405d1d4-p_f.jpg"]
}
```

#### For rent

Rentals are grouped **buildings** rather than single homes, so instead of one `price` they carry a `title`, a `minPrice`/`maxPrice` band, the available `unitsGroup`, and `matchingHomeCount` — how many units in that building match your filters.

```jsonc
{
  "zpid": 463355670,
  "url": "https://www.zillow.com/homedetails/463355670_zpid/",
  "homeStatus": "forRent",
  "title": "Inkwell",
  "price": 3664,
  "minPrice": 3664,
  "maxPrice": 3980,
  "currency": "usd",
  "address": {
    "streetAddress": "586 Gerard Ave",
    "city": "Bronx",
    "state": "NY",
    "zipcode": "10451"
  },
  "latitude": 40.82056,
  "longitude": -73.9285,
  "listingDate": "2026-08-21T20:50:20.785Z",
  "unitsGroup": [{ "bedrooms": 2, "minPrice": 3664, "isRoomForRent": false }],
  "matchingHomeCount": 8,
  "photos": ["https://photos.zillowstatic.com/fp/b60cc73bb73341791703c4b83eff7127-p_f.jpg"]
}
```

#### Recently sold

Sold listings add `lastSoldDate`, and `price` is the sale price — compare it against `zestimate` for a valuation gap.

```jsonc
{
  "zpid": 29816126,
  "url": "https://www.zillow.com/homedetails/29816126_zpid/",
  "homeStatus": "recentlySold",
  "marketingStatus": "closed",
  "homeType": "singleFamily",
  "price": 650000,
  "pricePerSquareFoot": 464,
  "zestimate": 749900,
  "rentZestimate": 4131,
  "taxAssessedValue": 732000,
  "address": {
    "streetAddress": "1819 Willow Lane",
    "city": "Bronx",
    "state": "NY",
    "zipcode": "10461"
  },
  "bedrooms": 3,
  "bathrooms": 3,
  "livingArea": 1400,
  "lotSize": 2500,
  "lotSizeUnit": "squareFeet",
  "yearBuilt": 1925,
  "lastSoldDate": "2023-09-04T04:00:00.000Z",
  "brokerName": "Keller Williams Realty NYC Grp",
  "photos": ["https://photos.zillowstatic.com/fp/af0b6605ea49bb6446d4b724bc1801a9-p_f.jpg"]
}
```

*Zillow decides which fields it returns per listing, so individual fields can be `null` — `zestimate` in particular is absent for many for-sale listings.*

### 🗺️ Map splitting

Zillow's search rejects `pageNumber * pageSize > 1000`, so at most 1,000 listings are reachable per map area (2 pages of 500). When an area holds more, the scraper splits it into four quadrants and searches each one separately, recursively, until every listing is reachable.

The root area is the region's own bounding box, so the very first split already divides the results — scraping all 2,666 Bronx listings takes 12 requests this way, against 53 from a US-wide root.

`maxSplitLevel` limits the depth. Only splits that actually divide the results count towards it, so a raised limit costs nothing on areas that don't need it. Raise it for a large metro or a whole state; lower it to cap the run.

### 💰 What does it cost?

**$3.00 per 1,000 results** on the free plan, dropping with your Apify plan:

| Plan | Per 1,000 results |
|---|---|
| Free | $3.00 |
| Starter | $2.60 |
| Scale | $2.20 |
| Business | $1.70 |

You pay per result, plus $0.00005 when a run starts. Platform usage (compute, proxy, storage) is included — there is no separate infrastructure bill.

Two things keep the total down:

- **`maxItems` is a hard budget cap.** Set it and the run cannot exceed it. 200 results costs $0.60 on the free plan, 5,000 costs $15.00.
- **There is no charge per property detail.** The mobile search response already carries the full listing, so scrapers that open a detail page per home bill you roughly twice — once for the result, once for the detail — where this one bills once.

Filtering server-side is also cheaper than filtering afterwards: `priceMin`, `homeTypes` and `daysOnZillowMax` shrink what gets scraped in the first place, so you are not paying for rows you throw away.

### 🧰 Getting zero or too few results?

| Symptom | Cause and fix |
|---|---|
| Fewer items than the total Zillow shows | The area needs deeper splitting — raise `maxSplitLevel`. |
| Zero results with several filters set | Filters are combined with AND. A small neighborhood plus a narrow filter genuinely can hold nothing — widen the area or drop a filter to confirm. |
| Zero results for rent | Rentals are grouped buildings, so a neighborhood may have only a handful. Try the city instead of the neighborhood. |
| `carries no searchQueryState` in the log | The URL has no search state. Open it on zillow.com, move the map once, then copy the URL again. |
| A filter from a URL "did nothing" | Some website-only filters have no mobile-API equivalent. The run log names each one it skipped. |
| Wrong location matched | `search` takes the first autocomplete match. Be more specific (`Melrose, Bronx` rather than `Melrose`), or use a URL. |
| `px-captcha` in the log | PerimeterX blocked the IP. Enable Apify Proxy, ideally US residential. |

### 🔌 Using the data elsewhere

Results land in a dataset you can export as JSON, CSV, Excel, XML or HTML, or pull through the API:

```bash
curl "https://api.apify.com/v2/acts/<username>~zillow-scraper/runs?token=<TOKEN>" \
  -d '{ "search": "Austin, TX", "type": "sale", "maxItems": 100 }' \
  -H 'Content-Type: application/json'
```

In Python, with the [Apify client](https://docs.apify.com/api/client/python/):

```python
from apify_client import ApifyClient

client = ApifyClient("<TOKEN>")
run = client.actor("<username>/zillow-scraper").call(run_input={
    "search": "Austin, TX",
    "type": "sale",
    "priceMax": 1500000,
    "maxItems": 100,
})

for home in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(home["address"]["streetAddress"], home["price"])
```

It also connects to Make, Zapier, Slack, Airbyte, GitHub, Google Sheets, Google Drive and LangChain through [Apify integrations](https://apify.com/integrations), and [webhooks](https://docs.apify.com/integrations/webhooks) can trigger an action when a run finishes — which is how you build a new-listing alert. For AI agents, the Actor is callable through the Apify MCP server at `https://mcp.apify.com`.

### 🔐 Authentication and proxies

**No credentials of any kind.** Zillow's public web search is behind PerimeterX, but the mobile endpoints this Actor uses validate only client identity, not any device or session token:

- `x-client: com.zillow.ZillowMap` is required; without it the API answers `missingRequiredTrackingHeader`.
- The user agent must not look like automation or a desktop browser — `curl/*` and Chrome user agents get an `px-captcha` 403, while the app's own user agent passes.
- `zgsession`, `x-px-hello` and `x-px-uuid` rotate constantly in the real app and are never validated, so the Actor sends none of them.

Verified against the live endpoints. **Proxies are still recommended**: sustained unproxied traffic from one datacenter IP does eventually earn a `px-captcha` 403, so runs default to Apify Proxy, with US residential the safest choice for large runs.

### ❓ FAQ

#### Is there an official Zillow API?

Zillow publishes a handful of partner APIs (Property Details, Neighborhood Data, and others), but they need an approved API key, are rate limited, and cover only part of the data shown on the site. This Actor needs no key and has no daily call limit.

#### Do I need a Zillow search URL?

No — a plain place name is resolved to Zillow's own region ID for you, which is simpler and more precise than a hand-drawn map box. But if you already have a search URL, paste it into `startUrls`: its map area and its filters are both read out of the `?searchQueryState=…` part. A URL without that part carries no search state, so open it on zillow.com and move the map once before copying it.

#### How many results can I get?

As many as the region has. Any single Zillow query is capped at 1,000 listings, which the automatic map splitting works around — the practical limit is `maxItems` and `maxSplitLevel`, not Zillow.

#### Does it work for rentals and sold homes?

Yes — set `type` to `rent` or `sold`. Both have their own filters (pets, laundry and availability date for rentals; a sold-within window for sold listings) and their own output shape, shown above.

#### Can I scrape a specific property?

Yes. Put its URL in `startUrls` or its ID in `zpids` — both are fetched directly, with no search and no map area involved.

#### How do I track price drops in a neighborhood?

Run it with `showOnly: ["priceReduction"]` on a schedule, and send the dataset to a webhook or Google Sheet. Compare `priceChange` and `price` between runs.

#### Can I use it with Python or AI agents?

Yes — see [Using the data elsewhere](#-using-the-data-elsewhere) for an API and Python example. For AI agents, call it through the Apify MCP server at `https://mcp.apify.com`.

#### Is scraping Zillow legal?

Scraping publicly available data such as prices, availability and street addresses is generally legal. Listings can also carry personal data about agents, which is covered by the GDPR and similar laws — get legal advice before collecting or storing that.

### 📝 Changelog

#### 1.1.0

- Filters: price, beds, baths, home type, square feet, lot size, year built, days on market (sold-within for sold listings), keywords, HOA, basement, view, amenities, parking, open houses, 3D tours, price cuts, foreclosures, and rental pets/laundry/parking/availability.
- Sorting by price, newest, beds, baths, square feet, lot size or year built.
- **Zillow URLs** as input — a search URL's map area and filters are read from `searchQueryState`; property URLs are fetched by ZPID.
- **ZPIDs** as input, fetched directly with no search.

#### 1.0.0

- First release: search by place name for sale/rent/sold listings, with automatic map splitting.

# Actor input Schema

## `search` (type: `string`):

Location to scrape, in plain text - e.g. `Los Angeles`, `Melrose, Bronx`, `Brooklyn, NY` or `90210`. It is resolved through Zillow's own autocomplete to the best matching region (city, borough, county, neighborhood, ZIP, subdivision or state). Leave empty if you are using **Zillow URLs** or **ZPIDs** instead.

## `startUrls` (type: `array`):

Zillow search or property URLs to scrape. A **search URL** must carry a `?searchQueryState=…` part - it holds the map area and the filters, both of which are read from it (open the search on zillow.com and move the map once if the URL has no query state yet). A **property URL** (`/homedetails/…/12345678_zpid/`) is fetched directly by its ZPID. Filters set below apply on top, and anything in the URL wins.

## `zpids` (type: `array`):

Zillow property IDs to fetch directly, e.g. `89070667`. These skip the search entirely - no location, no map area needed.

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

Which listings to scrape. For rent returns grouped buildings (`minPrice`/`maxPrice`/`unitsGroup`) rather than single homes; recently sold adds `lastSoldDate`.

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

Lowest price to include. For **For rent** this is the monthly rent (the API prices rentals on a different field, which the actor picks automatically).

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

Highest price to include. For **For rent**, the highest monthly rent.

## `bedsMin` (type: `integer`):

Fewest bedrooms.

## `bedsMax` (type: `integer`):

Most bedrooms.

## `bathsMin` (type: `integer`):

Fewest bathrooms. Half baths count, so `2` also matches a 2.5-bath home.

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

Property types to include. Empty means every type.

## `sqftMin` (type: `integer`):

Smallest interior size in square feet.

## `sqftMax` (type: `integer`):

Largest interior size in square feet.

## `lotSizeMin` (type: `integer`):

Smallest lot in square feet. 1 acre = 43,560 sq ft.

## `lotSizeMax` (type: `integer`):

Largest lot in square feet.

## `yearBuiltMin` (type: `integer`):

Earliest year built.

## `yearBuiltMax` (type: `integer`):

Latest year built.

## `daysOnZillowMax` (type: `integer`):

Only listings posted within this many days. Use `1` for listings added today. For **Recently sold** this is the sold-within window instead - the API uses one field for both, so `182` means sold in the last 6 months.

## `keywords` (type: `string`):

Free-text search over the listing description, exactly like the app's keyword box - e.g. `pool`, `garage`, `waterfront`.

## `showOnly` (type: `array`):

Extra listing conditions. Every selected condition must hold.

## `amenities` (type: `array`):

Property amenities that must be present.

## `parkingSpotsMin` (type: `integer`):

Fewest parking spots.

## `basementStatuses` (type: `array`):

Basement types to include. *For sale.*

## `viewTypes` (type: `array`):

Views the property must have.

## `hoaMaxPerMonth` (type: `integer`):

Highest monthly HOA fee, in dollars. *For sale.*

## `includeHomesWithNoHoaData` (type: `boolean`):

Keep listings whose HOA fee is unknown when an HOA limit is set. Matches the app's default.

## `includePending` (type: `boolean`):

Zillow's app hides pending and backup-offer listings by default; turn this on to keep them.

## `includeForeclosed` (type: `boolean`):

Add foreclosed homes to the results. *For sale.*

## `includePreforeclosure` (type: `boolean`):

Add pre-foreclosure homes to the results. *For sale.*

## `pets` (type: `array`):

Rentals that allow these pets. *Rentals.*

## `rentalAmenities` (type: `array`):

Building amenities the rental must have. *Rentals.*

## `availableFrom` (type: `string`):

Only rentals available on or after this date. Format `YYYY-MM-DD`. *Rentals.*

## `excludeSeniorCommunity` (type: `boolean`):

Drop 55+/senior-community rentals. *Rentals.*

## `sortOrder` (type: `string`):

Order the results are requested in. Leave empty to use the app's own default for the listing type (relevance for sale, priority score for rentals, days on Zillow for sold).

## `sortAscending` (type: `boolean`):

Sort low to high instead of high to low.

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

How many properties to scrape. Every returned property is billed, so this is the cap on what the run can cost. Leave empty to scrape everything the location has.

## `maxSplitLevel` (type: `integer`):

Zillow returns at most 1,000 listings per map area, so bigger areas are split into quadrants and searched separately. This caps how deep that goes — higher means more complete results on dense areas but a longer run. Only splits that actually divide the results count towards it, so raising it costs nothing on small areas. Raise it for a large metro or a whole state.

## `proxy` (type: `object`):

Zillow's mobile API needs no credentials, but sustained traffic from a single datacenter IP eventually earns a PerimeterX block. US residential proxies are recommended for large runs.

## `debugLog` (type: `boolean`):

Log every request, split and page. Turn on when a run returns fewer results than expected.

## Actor input object example

```json
{
  "search": "Los Angeles",
  "startUrls": [],
  "zpids": [
    "89070667",
    "448148857"
  ],
  "type": "sale",
  "priceMin": 250000,
  "priceMax": 4250000,
  "bedsMin": 2,
  "bedsMax": 5,
  "bathsMin": 2,
  "sqftMin": 750,
  "lotSizeMin": 5000,
  "yearBuiltMin": 2017,
  "daysOnZillowMax": 7,
  "keywords": "pool",
  "includeHomesWithNoHoaData": true,
  "includePending": false,
  "includeForeclosed": false,
  "includePreforeclosure": false,
  "availableFrom": "2026-09-19",
  "excludeSeniorCommunity": false,
  "sortAscending": false,
  "maxItems": 200,
  "maxSplitLevel": 3,
  "proxy": {
    "useApifyProxy": true
  },
  "debugLog": false
}
```

# Actor output Schema

## `overview` (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 = {
    "search": "Los Angeles",
    "startUrls": [],
    "maxItems": 200,
    "maxSplitLevel": 3,
    "proxy": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("lukass/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 = {
    "search": "Los Angeles",
    "startUrls": [],
    "maxItems": 200,
    "maxSplitLevel": 3,
    "proxy": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("lukass/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 '{
  "search": "Los Angeles",
  "startUrls": [],
  "maxItems": 200,
  "maxSplitLevel": 3,
  "proxy": {
    "useApifyProxy": true
  }
}' |
apify call lukass/zillow-scraper --silent --output-dataset

```

## MCP server setup

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