# Zillow API — $1.30/1K homes, sale, rent & sold (`lergassy/zillow-api`) Actor

\[$1.30/1K homes] Zillow API alternative: one HTTP request returns Zillow homes for sale, for rent or recently sold as JSON — price, beds, baths, sqft, Zestimate, sold date, address, coordinates. Full details add agent contact, price history and photos. No fee per request.

- **URL**: https://apify.com/lergassy/zillow-api.md
- **Developed by:** [Matvey](https://apify.com/lergassy) (community)
- **Categories:** Real estate, Lead generation, MCP servers
- **Stats:** 6 total users, 5 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.91 / 1,000 search 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?

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 API** for developers: send one HTTP request, get Zillow listings back as JSON. Homes **for sale, for rent and recently sold** for any US city, ZIP code, neighborhood or Zillow search URL — price, beds, baths, square feet, lot size, Zestimate, rent Zestimate, sold date and sold price, days on Zillow, address split into street / city / state / ZIP, coordinates and listing flags. Switch on full details and each home also carries the description, price history, photos, facts and features, and the listing agent's and broker's published contact.

Zillow has no public listings API: its developer APIs are limited to approved partners and do not let you search listings by place. This Actor is a **Zillow API alternative** that runs on Apify: you call a standard Apify endpoint, it reads the same data the Zillow website shows to any visitor, and you get flat JSON rows — no Zillow account, no Zillow API key, no cookies, no proxy setup on your side.

> This is the API-first entrance to [Zillow Scraper](https://apify.com/lergassy/zillow-scraper) — same engine, same fields, same price. If you prefer a form, scheduling and CSV/Excel downloads, the main Actor is the place to start.

### Call it in one request

`run-sync-get-dataset-items` starts a run, waits for it and returns the rows in the response body:

```bash
curl -X POST "https://api.apify.com/v2/acts/lergassy~zillow-api/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"listingType": "forSale", "locations": ["78704"], "maxItems": 20}'
```

An empty body (`{}`) is valid too: it returns 50 homes for sale in Austin, TX, so you can see the row shape before writing any code.

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("lergassy/zillow-api").call(run_input={
    "listingType": "sold",
    "locations": ["Denver, CO"],
    "maxItems": 200,
})
for home in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(home["address"], home.get("soldPrice"), home.get("soldDate"))
```

Node.js:

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('lergassy/zillow-api').call({ listingType: 'forRent', locations: ['Brooklyn, NY'], maxItems: 100 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

`run-sync-get-dataset-items` waits up to 300 seconds. For large pulls (thousands of homes, or full details on many homes) start the run asynchronously with `POST /v2/acts/lergassy~zillow-api/runs`, then read `GET /v2/datasets/{defaultDatasetId}/items` when it finishes, or attach a webhook.

### ⬇️ Input

| Field | What it does |
|---|---|
| `listingType` | `forSale` (default), `forRent` or `sold` |
| `locations` | City, ZIP code, neighborhood, county or address, one per item: `["Austin, TX", "78704"]` |
| `searchUrls` | Zillow search URLs copied from the browser — their filters and map area are kept |
| `propertyUrls` | Zillow home URLs, ZPIDs or street addresses — returns the full page for each home |
| `includeDetails` | `true` adds description, price history, photos, facts, HOA and agent/broker contact to search rows |
| `maxItems` | Hard cap on rows for the run, so also your cost cap. Default 50; `0` = no limit |
| `bypassResultCap` | `true` (default): searches Zillow cuts at 820 results are split into smaller map areas so the whole area comes back |
| `sort` | `relevance`, `newest`, `priceLow`, `priceHigh`, `beds`, `baths`, `sqft`, `lot`, `yearBuilt`, `priceCut`, `daysOnZillow` |
| `priceMin` / `priceMax`, `bedsMin` / `bedsMax`, `bathsMin`, `sqftMin` / `sqftMax`, `lotSizeMin` / `lotSizeMax`, `yearBuiltMin` / `yearBuiltMax` | Range filters |
| `homeTypes`, `sellerTypes`, `features`, `daysOnZillow`, `keywords`, `hoaMax`, `parkingSpotsMin`, `includePending` | The rest of Zillow's filters |
| `oneRowPerUnit` | For rental buildings: one row per unit instead of one row per building |

Example — 3+ bed houses under $600k listed in the last 30 days, with full details:

```json
{
    "listingType": "forSale",
    "locations": ["Phoenix, AZ"],
    "homeTypes": ["house"],
    "bedsMin": 3,
    "priceMax": 600000,
    "daysOnZillow": "30",
    "includeDetails": true,
    "maxItems": 100
}
```

### ⬆️ Output

One flat JSON object per home. A search row (full details off):

```json
{
    "zpid": "331627751",
    "url": "https://www.zillow.com/homedetails/15000-Upland-Willow-Rd-Austin-TX-78724/331627751_zpid/",
    "listingType": "forSale",
    "status": "FOR_SALE",
    "statusText": "Active",
    "price": 279000,
    "pricePerSqft": 162,
    "address": "15000 Upland Willow Rd, Austin, TX 78724",
    "street": "15000 Upland Willow Rd",
    "city": "Austin",
    "state": "TX",
    "zip": "78724",
    "latitude": 30.262829,
    "longitude": -97.57543,
    "beds": 3,
    "baths": 2,
    "sqft": 1725,
    "lotSizeSqft": 5663,
    "homeType": "house",
    "zestimate": 281400,
    "rentZestimate": 1795,
    "daysOnZillow": 16,
    "isFsbo": false,
    "isNewConstruction": false,
    "isForeclosure": false,
    "isPending": false,
    "brokerName": "Compass RE Texas, LLC",
    "imageUrl": "https://photos.zillowstatic.com/fp/...",
    "searchLocation": "Austin, TX",
    "summary": "15000 Upland Willow Rd, Austin, TX 78724: 3 bd 2 ba 1,725 sqft house $279,000; 16 day(s) on Zillow."
}
```

With `includeDetails: true` (or for `propertyUrls`) the row also gets `description`, `yearBuilt`, `hoaFee`, `agentName`, `agentPhone`, `brokerPhone`, `mlsId`, `priceHistory`, `photos`, `highlights`, `heating`, `cooling`, `parking`, `facts` and more, when Zillow shows them. Rental buildings carry `minRent`, `maxRent` and a `units` list.

Rows that fail are returned as `rowType: "error"` with `errorCode` and `errorMessage` (for example `location-not-found`). They are free.

### 💰 Pricing

Pay per row, no subscription, no fee per request or per run:

| Event | Price |
|---|---|
| Home from a search | **$1.30 per 1,000** |
| Full property details (on top of the search row when `includeDetails` is on; alone for `propertyUrls`) | **$2.50 per 1,000** |

Paid Apify plans get the same rows 10–30% cheaper. Error rows and empty results cost nothing. `maxItems` caps the bill: a run never charges for more rows than that. The price is identical to [Zillow Scraper](https://apify.com/lergassy/zillow-scraper).

### ❓ FAQ

#### Does Zillow have an official API for listings?

Not one you can sign up for and search listings with. Zillow's developer programs are restricted to approved partners and specific use cases. This Actor gives you an HTTP endpoint that returns the listing data the public website shows.

#### Do I need a Zillow account, API key or proxy?

No. You only need an Apify API token. If Zillow refuses a request from the run's own address, the Actor retries it through a residential IP itself; you do not configure or pay for that separately.

#### How many homes can one call return?

Zillow shows at most 820 homes per search. With `bypassResultCap` on (default) the Actor splits the map and returns the whole area. Keep big jobs asynchronous: the synchronous endpoint waits at most 300 seconds.

#### Can I look up a single home?

Yes — put a Zillow URL, a ZPID or a street address into `propertyUrls`. That returns the full detail row for each one.

#### Why is `soldPrice` empty in Texas?

Texas and a few other states are non-disclosure states, and Zillow does not publish sale prices there. The sold date is still returned.

#### Does it return tax history and school ratings?

No. Everything else on the listing page is included.

#### Can an AI agent or n8n / Make / Zapier call it?

Yes. It is a standard Apify Actor: it works with the Apify MCP server, the official Python and JavaScript clients, and the Apify integrations for n8n, Make and Zapier.

#### Is it legal?

The Actor reads only public pages that Zillow shows to any visitor without logging in. How you use the data is your responsibility: respect Zillow's terms where they apply to you, fair-housing and privacy law, and get legal advice for commercial use.

### Related

- [Zillow Scraper](https://apify.com/lergassy/zillow-scraper) — the main Actor with the same engine: form input, schedules, CSV/Excel export and a longer guide to every field and filter.

Questions or a field you need? Open an issue on the **Issues** tab.

# Actor input Schema

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

What to search for: homes <b>for sale</b>, <b>for rent</b> (houses, condos and apartment buildings) or <b>recently sold</b> homes with their sold date and price.

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

One location per line, the way you would type it into Zillow: a city (<code>Austin, TX</code>), a ZIP code (<code>78704</code>), a neighborhood (<code>Zilker, Austin, TX</code>), a county (<code>Travis County, TX</code>) or a whole state (<code>Nevada</code>). Each location is searched separately and the rows say which one they came from.

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

Zillow search pages copied from the browser, filters included (for example <code>https://www.zillow.com/austin-tx/houses/?searchQueryState=…</code>). Use this when the Zillow website already shows exactly the homes you want. Filters set below are added on top of what the URL carries.

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

Homes you already know: a Zillow property URL (<code>https://www.zillow.com/homedetails/…\_zpid/</code>), an apartment-building URL, a bare ZPID (<code>331627751</code>) or a street address (<code>15000 Upland Willow Rd, Austin, TX 78724</code>). Each one returns a full property row with description, price history, photos, facts and listing contact — no search needed.

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

Open every home found by the search and add its full page: description, price history, all photos, facts and features (parking, heating, HOA, lot), listing agent and broker contact, MLS number, Zillow's own highlight phrases. Costs one extra request and one <i>Property detail</i> event per home. Leave off for a fast, cheap list.

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

Hard cap on rows for the whole run, across all locations and URLs. The run stops the moment it is reached, so this is also your cost cap: results × price per result. Set 0 for no limit.

## `bypassResultCap` (type: `boolean`):

Zillow shows at most 20 pages × 41 homes for one search. When a location has more, the scraper splits the map into smaller areas and searches each of them, so a whole city comes back complete. Turn off to stop at Zillow's first 820.

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

Order of the results, same options as Zillow's sort menu. Matters when <b>Maximum results</b> is smaller than the number of matching homes.

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

Minimum price in US dollars. For rentals this is the monthly rent.

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

Maximum price in US dollars (monthly rent for rentals).

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

Minimum number of bedrooms. <code>0</code> includes studios.

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

Maximum number of bedrooms.

## `bathsMin` (type: `number`):

Minimum number of bathrooms, halves allowed (<code>1.5</code>).

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

Which kinds of home to include. Empty means all types.

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

Minimum living area in square feet.

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

Maximum living area in square feet.

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

Minimum lot size in square feet (an acre is 43,560).

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

Maximum lot size in square feet.

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

Earliest construction year to include.

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

Latest construction year to include.

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

Only homes listed (or, for the <b>sold</b> type, sold) within this period.

## `sellerTypes` (type: `array`):

Narrow for-sale results to who is selling. Empty means all of them. <b>Owner posted</b> is the FSBO filter investors look for; <b>Foreclosures</b>, <b>Auctions</b> and <b>Pre-foreclosures</b> are the distressed-property filters.

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

For-sale searches: also return homes that are pending or under contract (accepting backup offers). Off returns active listings only.

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

Words that must appear in the listing text, for example <code>pool</code>, <code>ADU</code>, <code>fixer</code>, <code>mother-in-law</code>. Same as the keyword box on Zillow.

## `features` (type: `array`):

Home features the listing must have.

## `hoaMax` (type: `integer`):

Maximum monthly HOA fee in dollars. <code>0</code> means no HOA at all.

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

Minimum number of parking spots.

## `oneRowPerUnit` (type: `boolean`):

Rentals: apartment buildings list several units and floor plans. On, every unit becomes its own row (beds, baths, sqft, rent, availability). Off, a building is one row with its units nested in <code>units</code>.

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

Give this run a name (letters, digits and dashes, e.g. <code>austin-fsbo-watch</code>) and every later run with the same name returns <b>only homes that are new or whose price or status changed</b> since the previous run. Schedule it daily to get a change feed instead of the whole list each time. Leave empty for a normal full run.

## `includeRawData` (type: `boolean`):

Add a <code>raw</code> field with everything Zillow returned for the home, untouched. Useful for developers; makes rows large.

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

How many Zillow pages are fetched at the same time. Higher is faster; lower is gentler if you see blocked rows.

## `requestTimeoutSecs` (type: `integer`):

How long to wait for one Zillow page.

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

Leave off. Zillow shows its anti-bot page to some networks, and when that happens the Actor switches to an Apify US residential IP by itself, for the blocked requests only. Set your own proxy here only if you want to force a specific country or your own IPs.

## Actor input object example

```json
{
  "listingType": "forSale",
  "locations": [
    "Austin, TX"
  ],
  "searchUrls": [],
  "propertyUrls": [],
  "includeDetails": false,
  "maxItems": 50,
  "bypassResultCap": true,
  "sort": "relevance",
  "homeTypes": [],
  "daysOnZillow": "any",
  "sellerTypes": [],
  "includePending": false,
  "features": [],
  "oneRowPerUnit": false,
  "includeRawData": false,
  "maxConcurrency": 5,
  "requestTimeoutSecs": 30,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

One flat row per home or rental building: Zillow URL, status, price, sold date and price, address split into street, city, state and ZIP, coordinates, beds, baths, square feet, lot size, home type, Zestimate and rent Zestimate, days on Zillow, listing flags, listing agent and broker contact, price history, photos, facts and a one-sentence summary. Error rows carry the reason and cost nothing.

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

JSON summary of the run: rows delivered, rows filtered out, failed inputs (free) and request statistics.

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

JSON list of inputs the run did not reach (time limit or "Max cost per run"). Not charged — pass them as input to a new run to continue. Present only when the run stopped early.

# 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 = {
    "listingType": "forSale",
    "locations": [
        "Austin, TX"
    ],
    "searchUrls": [],
    "propertyUrls": [],
    "maxItems": 50,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("lergassy/zillow-api").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 = {
    "listingType": "forSale",
    "locations": ["Austin, TX"],
    "searchUrls": [],
    "propertyUrls": [],
    "maxItems": 50,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("lergassy/zillow-api").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 '{
  "listingType": "forSale",
  "locations": [
    "Austin, TX"
  ],
  "searchUrls": [],
  "propertyUrls": [],
  "maxItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call lergassy/zillow-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lergassy/zillow-api"
        }
    }
}
```

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/rdhqb5s4oyE5xI43T/builds/ThF6TvYp2bG1e8eHH/openapi.json
