# Cheap Zillow Details Scraper (`corner_cutter/cheap-zillow-details-scraper`) Actor

Scrape complete Zillow property details from up to 1,000 URLs or ZPIDs. Get prices, Zestimate and rent estimates, tax and price history, schools, photos, climate risk, agent attribution, and more—without a browser or Zillow login.

- **URL**: https://apify.com/corner\_cutter/cheap-zillow-details-scraper.md
- **Developed by:** [ReactRuby](https://apify.com/corner_cutter) (community)
- **Categories:** Real estate, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 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/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

Cheap Zillow Details Scraper takes any list of **Zillow property URLs** and returns the **complete property record** behind each listing — price, beds/baths, tax and price history, schools, climate risk, agent attribution, photos and more. It is built for high-volume real estate workflows, with predictable pay-per-result pricing as low as **$0.80 per 1,000 successful properties**.

[Open Cheap Zillow Details Scraper in Apify Store](https://apify.com/corner_cutter/cheap-zillow-details-scraper). You can run it from Apify Console, the REST API, integrations, or an MCP-compatible AI client.

> **Independent tool:** Cheap Zillow Details Scraper is an unofficial tool and is not affiliated with, endorsed by, or sponsored by Zillow.

### What does Cheap Zillow Details Scraper do?

This Actor is a **Zillow API alternative** for property detail pages. Give it one or many [Zillow](https://www.zillow.com) property URLs and it returns the full property payload for each one, exactly as Zillow's own property page receives it — around **146 fields per property**.

It scrapes **property detail pages only**. It does not search listings, crawl result pages, or discover URLs for you — you bring the URLs, it brings the data.

### Why scrape Zillow property details?

- 🏠 **Complete records, not summaries** — everything Zillow's own page loads, including data not visible in the UI.
- 💸 **Low cost at scale** — $1.00 per 1,000 successful properties on Bronze and as little as $0.80 per 1,000 on Gold and higher plans.
- 📊 **Comps and valuation** — Zestimate, rent Zestimate, price history, tax history, and nearby homes.
- 🌡️ **Climate risk** — flood, fire, heat, wind, and air-quality risk scores per property.
- 🏫 **Schools and neighborhood** — assigned schools with ratings, plus neighborhood context.
- 🔁 **Bulk-friendly** — pass 1 URL or 1,000; requests run in parallel with automatic retries.
- 🤖 **MCP-ready contract** — typed inputs, documented nested output fields, deterministic run summaries, and structured failures.
- 🛡️ **Proxy handled for you** — a working residential proxy is built in, so it runs out of the box.

Running on Apify, you also get scheduling, a REST API, webhooks, monitoring, and integrations with Make, Zapier, Google Sheets, and more.

### What data can Cheap Zillow Details Scraper extract?

Each item contains the full raw payload. These are some of the most useful fields, all nested under `data.property`:

| Field                         | Type    | Description                                                     |
| ----------------------------- | ------- | --------------------------------------------------------------- |
| `zpid`                        | integer | Zillow's unique property id                                     |
| `address`                     | object  | Street address, city, state, zipcode, neighborhood, subdivision |
| `price`                       | number  | Current list price                                              |
| `homeStatus`                  | string  | `FOR_SALE`, `SOLD`, `PENDING`, `FOR_RENT`, …                    |
| `homeType`                    | string  | `SINGLE_FAMILY`, `CONDO`, `MULTI_FAMILY`, …                     |
| `bedrooms` / `bathrooms`      | number  | Bed and bath counts                                             |
| `livingArea` / `lotSize`      | number  | Interior and lot size                                           |
| `yearBuilt`                   | integer | Year the home was built                                         |
| `zestimate` / `rentZestimate` | number  | Zillow's value and rent estimates                               |
| `priceHistory`                | array   | Every listing event with date, price, and source                |
| `taxHistory`                  | array   | Assessed value and tax paid per year                            |
| `resoFacts`                   | object  | Deep facts: appliances, heating, parking, HOA, rooms, utilities |
| `schools` / `assignedSchools` | array   | Nearby and assigned schools with ratings                        |
| `originalPhotos`              | array   | Full-resolution photo URLs                                      |
| `attributionInfo`             | object  | Listing agent, broker, MLS id and name                          |
| `description`                 | string  | The listing's written description                               |
| `latitude` / `longitude`      | number  | Geo coordinates                                                 |

Climate risk lives under `data.zgProperty.odpPropertyModels.climate`.

### How to scrape Zillow property details

1. Click **Try for free** / **Start** to open the Actor.
2. Paste one or more Zillow property URLs into **Zillow property URLs**. Any URL containing a zpid works, for example `https://www.zillow.com/homedetails/11826-Garden-Terrace-Dr-Dallas-TX-75243/26890226_zpid/`.
3. *(Optional)* Set your own **Proxy configuration**. Leave it off to use the built-in default proxy.
4. Click **Save & Start**.
5. When the run finishes, open the **Output** tab and download your data as JSON, CSV, or Excel.

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

Cheap Zillow Details Scraper is one of the most affordable full-payload Zillow property detail options on Apify. You pay only for successful property results, and higher Apify plans automatically receive lower per-result prices.

| Apify plan | Price per successful property | Price per 1,000 | Price per 10,000 |
| ---------- | ----------------------------- | --------------- | ---------------- |
| Free       | $0.0050                       | $5.00           | $50.00           |
| Bronze     | $0.0010                       | $1.00           | $10.00           |
| Silver     | $0.0009                       | $0.90           | $9.00            |
| Gold       | $0.0008                       | **$0.80**       | **$8.00**        |
| Platinum   | $0.0008                       | **$0.80**       | **$8.00**        |
| Diamond    | $0.0008                       | **$0.80**       | **$8.00**        |

Each run also has a small **$0.00005 Actor-start charge per GB of configured memory**. With the default 1 GB memory setting, that is $0.00005 per run.

Failed URLs and skipped duplicates do not create dataset rows, so they are not charged as property-result events. To keep usage down, deduplicate your input first—the Actor also skips URLs that resolve to a property already scraped in the same run.

Prices can change. See the Actor's **Pricing** tab in Apify Store for the current schedule; that page is the source of truth.

### Input

See the **Input** tab for all options. Supply at least one URL or ZPID and no more than 1,000 combined property inputs.

| Field                | Type    | Default | Description                                                                                        |
| -------------------- | ------- | ------- | -------------------------------------------------------------------------------------------------- |
| `startUrls`          | array   | —       | Zillow property URLs. Do not place bare ZPIDs in this URL-list field.                              |
| `zpids`              | array   | —       | Bare numeric Zillow property IDs such as `"26890226"`. Intended for API, MCP, and Console callers. |
| `proxyConfiguration` | object  | *(off)* | Proxy used to reach Zillow. Leave off to use the built-in default proxy.                           |
| `maxAttempts`        | integer | `3`     | Attempts per property before it is recorded as failed.                                             |
| `maxConcurrency`     | integer | `5`     | How many properties to fetch in parallel.                                                          |

Example input:

```json
{
    "startUrls": [
        { "url": "https://www.zillow.com/homedetails/11826-Garden-Terrace-Dr-Dallas-TX-75243/26890226_zpid/" },
        { "url": "https://www.zillow.com/homedetails/11920-SW-51st-St-Miami-FL-33175/117595874_zpid/" }
    ],
    "maxConcurrency": 5
}
```

### How to use Cheap Zillow Details Scraper with MCP

Apify's hosted MCP server exposes this Actor as a tool for ChatGPT, Claude, Cursor, VS Code, Codex, and other MCP-compatible AI clients. The Actor itself does not need to run as a separate always-on MCP server.

#### Connect from an MCP client

1. Create or sign in to your [Apify account](https://console.apify.com/).
2. Add a remote MCP server to your client with the configuration below. The `tools` parameter limits the connection to this Actor.

```json
{
    "mcpServers": {
        "apify": {
            "url": "https://mcp.apify.com?tools=corner_cutter/cheap-zillow-details-scraper"
        }
    }
}
```

3. Reload or reconnect the MCP server, then complete the Apify OAuth flow in your browser when prompted.
4. Enable the `apify` server for your conversation and ask the AI to run the scraper.

You can also install the connection with the [Apify CLI](https://docs.apify.com/cli):

```bash
apify login
apify mcp install <client> --tools corner_cutter/cheap-zillow-details-scraper
```

Replace `<client>` with `claude-code`, `cursor`, `vscode`, `vscode-insiders`, `codex`, `kiro`, or `antigravity`. This method uses the Apify account authenticated by `apify login`.

If your client uses a bearer token instead of OAuth, create one under **Apify Console → Settings → API & Integrations** and store it in the client's secret or environment-variable facility. Never commit an Apify API token to source control. See the [Apify MCP server documentation](https://docs.apify.com/integrations/mcp) for client-specific setup and local `stdio` configuration.

#### Connect from ChatGPT

1. Enable **Developer mode** in ChatGPT.
2. Go to **Settings → Apps & Connectors → Create**.
3. Set the MCP server URL to `https://mcp.apify.com?tools=corner_cutter/cheap-zillow-details-scraper` and choose **OAuth** authentication.
4. Authorize Apify, start a new chat, and add the new connector from **+ → More**.

#### Run the scraper

Example prompt:

> Run Cheap Zillow Details Scraper for `https://www.zillow.com/homedetails/.../26890226_zpid/`. Return the address, price, Zestimate, beds, baths, climate risks, and the Apify dataset ID.

The MCP tool accepts the same typed input documented in the [Input](#input) section. A run returns an output preview and a dataset ID. If the preview is truncated, ask the client to call `get-actor-output` with that dataset ID; it supports pagination and field selection, so large results do not need to be loaded into the model's context all at once.

For a bare property ID, MCP and API callers should use the dedicated field:

```json
{
    "zpids": ["26890226"]
}
```

### Output

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

The **Output** tab shows all fields returned for each property, including the complete Zillow response.

Each item starts with useful summary fields and preserves the complete raw Zillow GraphQL envelope under `data` (abridged here — the real `property` object has ~146 fields):

```json
{
    "input": "26890226",
    "address": "11826 Garden Terrace Dr, Dallas, TX 75243",
    "price": 550000,
    "homeStatus": "FOR_SALE",
    "bedrooms": 3,
    "bathrooms": 2,
    "livingArea": 2558,
    "zestimate": 531700,
    "zpid": 26890226,
    "scrapedAt": "2026-07-15T11:26:43.510Z",
    "data": {
        "property": {
            "zpid": 26890226,
            "address": {
                "streetAddress": "11826 Garden Terrace Dr",
                "city": "Dallas",
                "state": "TX",
                "zipcode": "75243"
            },
            "price": 550000,
            "homeStatus": "FOR_SALE",
            "homeType": "MULTI_FAMILY",
            "bedrooms": 3,
            "bathrooms": 2,
            "priceHistory": [{ "date": "2026-02-10", "price": 550000, "event": "Listed for sale" }],
            "taxHistory": [{ "time": 1752569991519, "taxPaid": 5218.9, "value": 448420 }]
        },
        "viewer": null,
        "zgProperty": { "odpPropertyModels": { "climate": { "floodSources": {} } } }
    }
}
```

URLs that fail do **not** appear in the dataset, so every item keeps the same shape. They are written to the `FAILED_URLS` record in the run's key-value store, each with the URL, the zpid, and why it failed:

```json
[
    {
        "url": "https://www.zillow.com/dallas-tx/",
        "zpid": null,
        "reason": "INVALID_URL",
        "error": "Could not find a zpid in this URL."
    }
]
```

Failure reasons are `INVALID_URL`, `NOT_FOUND`, `BLOCKED`, `HTTP_ERROR`, `PROXY_ERROR`, `NETWORK_ERROR`, and `INVALID_RESPONSE`. The run itself only fails when **every** URL failed.

Every run also writes a `RUN_SUMMARY` JSON record to its key-value store:

```json
{
    "status": "SUCCEEDED",
    "totalInputUrls": 2,
    "uniqueProperties": 2,
    "succeeded": 2,
    "failed": 0,
    "duplicatesSkipped": 0,
    "finishedAt": "2026-07-29T08:15:00.000Z"
}
```

This compact record is useful to automations and AI agents that need to confirm completion without loading the full dataset.

### Live run status

While a batch scrape is running, its **Live View** exposes `GET /` as a read-only JSON status endpoint. It reports the current phase, input counts, successful results, failures, and skipped duplicates. The endpoint is available only for the lifetime of that run and is intended for monitoring; submit scrape inputs through the Actor input form or Apify API.

### Tips and advanced options

#### Proxies

Zillow protects this data with PerimeterX, which scores the IP the request comes from. **Residential proxies are effectively required** — datacenter IPs are blocked almost immediately.

- Leave **Proxy configuration** off to use the built-in default residential proxy. This works out of the box.
- Supply your own by enabling Apify Proxy with the `RESIDENTIAL` group, or by passing custom `proxyUrls`.

A share of residential IPs are blocked at random regardless of proxy provider. Every retry uses a **fresh IP and a fresh user-agent**, which is what the default of 3 attempts is there to absorb. If you see a high block rate, raise `maxAttempts` and lower `maxConcurrency`.

#### Speed

`maxConcurrency` is the main lever. 5 is a safe default; raising it speeds up large lists and costs only a small increase in blocked requests, which retries absorb.

Measured over 854 real properties across Phoenix, Scottsdale, Austin, Dallas, Fort Worth, Houston and Miami, using the built-in default proxy:

| Concurrency | Throughput | Scraped | Requests blocked | Recovered by retry | Gave up |
| ----------- | ---------- | ------- | ---------------- | ------------------ | ------- |
| 5           | 0.9 URL/s  | 210/210 | 7%               | 17                 | 0       |
| 10          | 1.8 URL/s  | 504/504 | 12%              | 59                 | 0       |
| 20          | 2.6 URL/s  | 140/140 | 10%              | 14                 | 0       |

About 90% of requests succeed on the first attempt and the rest recover on a retry, so the default of 3 attempts left nothing behind in any of these runs. The block rate stayed flat from the start of a run to the end (12% → 9% across a 504-URL run) and no `429` rate-limiting appeared, so blocks are per-IP reputation rather than a penalty for sustained volume — there is no benefit to running slowly.

#### Proxy bandwidth

Measured at the socket (TLS handshake, headers and both directions, including retry overhead), one property costs about **72 KB** of proxy traffic:

| Direction       | Per property | Notes                                                 |
| --------------- | ------------ | ----------------------------------------------------- |
| Up (request)    | ~36 KB       | The GraphQL query, sent uncompressed on every request |
| Down (response) | ~33 KB       | ~171 KB of JSON, gzipped ~6.6x by Zillow              |
| Retry overhead  | ~5 KB        | ~11% of requests are blocked and retried              |

At that rate, **1,000 properties use about 72 MB** of proxy traffic, while **10,000 properties use about 720 MB**.

Note the request is the *larger* half: the 34 KB query is sent up every time and is not compressed, so bandwidth scales with request count, not with how much data a property happens to have.

### FAQ

#### Which Zillow URLs are supported?

Any Zillow URL containing a zpid — `/homedetails/<slug>/<zpid>_zpid/`, `/homes/<zpid>_zpid/`, or a `?zpid=` query parameter. A bare zpid works too. Search, city, and agent pages are **not** supported: there is no single property behind them.

#### Why did a URL come back as `NOT_FOUND`?

Zillow has no property for that zpid — usually a typo or a delisted property. This is not retried, because retrying cannot change the answer.

#### Does it need cookies or a login?

No. The endpoint is public and needs no cookies, no session, and no account.

#### Can it scrape sold or rental listings?

Yes. Any property with a zpid works, whatever its `homeStatus`.

### Disclaimer

Our Actors are ethical and do not extract any private user data, such as email addresses, gender, or location. They only extract what the user has chosen to share publicly. We therefore believe that our Actors, when used for ethical purposes by Apify users, are safe. However, you should be aware that your results could contain personal data. Personal data is protected by the GDPR in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

Note that Zillow listing data includes **agent and broker contact details** (`attributionInfo`). Treat those as personal data.

### Support

Need help, found a bug, or want to request a field? Email <business@karbon-tech.store>.

For programmatic access, see the Actor's **API** tab.

# Actor input Schema

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

Zillow property-detail URLs. URLs containing `<zpid>_zpid` or `?zpid=` are supported. Use the separate Zillow property IDs field for bare ZPIDs. Add at least one URL or ZPID, with no more than 1,000 combined inputs.

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

Bare numeric Zillow property IDs for API, MCP, or Console runs. Example: `26890226`. Use this field instead of placing bare IDs in the URL field. Add at least one URL or ZPID, with no more than 1,000 combined inputs.

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

Optional proxy settings. Leave Apify Proxy disabled to use the Actor's built-in proxy. If you provide a proxy, residential IPs are strongly recommended because Zillow blocks most unproxied datacenter traffic.

## `maxAttempts` (type: `integer`):

Maximum attempts for each property. Retriable blocks and network failures use a fresh proxy session and user-agent. Invalid or unknown ZPIDs fail immediately.

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

Maximum properties fetched in parallel. Lower this value if a run sees frequent blocking; increase it cautiously for large URL lists.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.zillow.com/homedetails/11826-Garden-Terrace-Dr-Dallas-TX-75243/26890226_zpid/"
    }
  ],
  "zpids": [
    "26890226"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "maxAttempts": 3,
  "maxConcurrency": 5
}
```

# Actor output Schema

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

Default dataset containing a readable overview and the complete Zillow GraphQL data envelope for each successfully scraped property.

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

JSON summary with input, success, failure, duplicate, and unique-property counts for this run.

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

JSON array of failed inputs with URL, parsed ZPID, machine-readable reason, and error message. The record exists only when at least one input fails.

# 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 = {
    "startUrls": [
        {
            "url": "https://www.zillow.com/homedetails/11826-Garden-Terrace-Dr-Dallas-TX-75243/26890226_zpid/"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("corner_cutter/cheap-zillow-details-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 = { "startUrls": [{ "url": "https://www.zillow.com/homedetails/11826-Garden-Terrace-Dr-Dallas-TX-75243/26890226_zpid/" }] }

# Run the Actor and wait for it to finish
run = client.actor("corner_cutter/cheap-zillow-details-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 '{
  "startUrls": [
    {
      "url": "https://www.zillow.com/homedetails/11826-Garden-Terrace-Dr-Dallas-TX-75243/26890226_zpid/"
    }
  ]
}' |
apify call corner_cutter/cheap-zillow-details-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/8gwby52aWJcKowk0w/builds/tVB5jSB5TVzzazN4J/openapi.json
