How to use Zillow Scraper
Step by step: in the Apify Store, over the API, from JavaScript or Python, in n8n, and from AI agents through MCP or LangChain.
$2.10 per 1,000 properties on the Free plan, down to $1.20 on higher plans (live Apify price on 2026-11-02).
1. In the Apify Store (no code)
- Open arcadium/zillow-properties and sign in to Apify (a free account works).
- Fill in the input form. The fields below are the ones the example uses.
- Set a maximum cost per run in the run options if you want a hard cap.
- Start the run. Rows appear in the Output tab as they arrive.
- Export the dataset as JSON, CSV or Excel, or connect an integration.
| Input field | Type | Description |
|---|---|---|
locations | array | Places to search, as you would type them on Zillow: for example a city ("Austin, TX"), ZIP code ("78704"), county ("Travis County, TX"), neighborhood or state. Each location is searched on its own with the filters below; every row keeps the location and its position in the results. Also accepted as zipCodes, search, searchTerms, queries or addresses (maxcopell actors). |
maxResultsPerSearch | integer | Properties per location or search URL, e.g. 200 (the default). Zillow lists at most 820 homes per query; larger areas are split into map sections automatically, so whole metros can be read. Also accepted as resultsLimit or maxResults. |
Example input:
{
"locations": [
"Austin, TX"
],
"maxResultsPerSearch": 50
}
2. Over the Apify API
The synchronous endpoint runs the actor and returns its rows in one call (for runs up to about five minutes; use the asynchronous run endpoint for longer ones).
curl -X POST "https://api.apify.com/v2/acts/arcadium~zillow-properties/run-sync-get-dataset-items" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"locations":["Austin, TX"],"maxResultsPerSearch":50}'
3. From JavaScript
// npm install apify-client
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('arcadium/zillow-properties').call({
"locations": [
"Austin, TX"
],
"maxResultsPerSearch": 50
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
4. From Python
# pip install apify-client
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("arcadium/zillow-properties").call(run_input={
"locations": ["Austin, TX"],
"maxResultsPerSearch": 50,
})
items = client.dataset(run.default_dataset_id).list_items().items # apify-client 3.x returns a Run object
print(items)
5. In n8n
Paste this node into a workflow (it is a plain HTTP Request node). Create a Header Auth credential with name Authorization and value Bearer <APIFY_TOKEN>; each returned row becomes one item for the next node.
{
"nodes": [
{
"name": "Run arcadium/zillow-properties",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
0,
0
],
"parameters": {
"method": "POST",
"url": "https://api.apify.com/v2/acts/arcadium~zillow-properties/run-sync-get-dataset-items",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "{\"locations\":[\"Austin, TX\"],\"maxResultsPerSearch\":50}",
"options": {
"timeout": 300000
}
}
}
],
"connections": {}
}
6. From an AI assistant (MCP)
Add Apify’s MCP server to Claude Desktop, Cursor, VS Code or any MCP client, limited to this actor:
{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com/?tools=arcadium/zillow-properties",
"headers": {
"Authorization": "Bearer <APIFY_TOKEN>"
}
}
}
}
More on the MCP page.
7. From LangChain
# pip install langchain-apify (reads APIFY_API_TOKEN from the environment)
from langchain_apify import ApifyActorsTool
tool = ApifyActorsTool("arcadium/zillow-properties")
rows = tool.invoke({"run_input": {
"locations": ["Austin, TX"],
"maxResultsPerSearch": 50,
}})
# or give `tool` to an agent: create_react_agent(llm, [tool])
Sample output
One row, from the example in the actor’s README. Long text is shortened and lists are cut to two items.
{
"rowType": "property",
"platform": "zillow",
"propertyId": "70345655",
"url": "https://www.zillow.com/homedetails/3207-Wickham-Ln-Austin-TX-78725/70345655_zpid/",
"status": "FOR_SALE",
"price": 324900,
"currency": "USD",
"address": "3207 Wickham Ln, Austin, TX 78725",
"city": "Austin",
"state": "TX",
"zipcode": "78725",
"latitude": 30.232096,
"longitude": -97.5937,
"beds": 4,
"baths": 3,
"livingArea": 2575,
"lotArea": 4800.312,
"lotAreaUnit": "sqft",
"homeType": "SINGLE_FAMILY",
"daysOnMarket": 140,
"zestimate": null,
"rentZestimate": null,
"taxAssessedValue": 365588,
"priceChange": -15000,
"priceChangeDate": "2026-10-14",
"brokerName": "T J Lewis Real Estate",
"photos": null,
"detailed": false,
"searchInput": "Austin, TX",
"searchRank": 1,
"scrapedAt": "2026-10-22T10:00:00.000Z"
}
| Field | What it holds |
|---|---|
rowType | Kind of row. Filter on this first. 'property': one Zillow property (charged as 'property', or 'property-details' when detailed is true). 'error': an input could not be read; see code and message (free). |
platform | Always 'zillow'. |
propertyId | Zillow property id (zpid), the number before _zpid in the property URL. Unique per run. |
url | Property page URL on zillow.com. |
status | Listing status as Zillow states it: FOR_SALE, FOR_RENT, RECENTLY_SOLD, PENDING, OFF_MARKET, ... |
statusText | Status as shown on the card, e.g. 'Active', 'House for rent', 'Sold'. |
price | List price in USD; monthly rent for rentals; null for sold homes in search rows (see lastSoldPrice on detail rows). |
currency | Currency of all money fields, normally USD. |
address | Full address line, e.g. '3207 Wickham Ln, Austin, TX 78725'. |
street | Street address. |
city | City name of the property address. |
state | Two-letter state code. |
zipcode | ZIP code of the property address. |
latitude | Latitude (WGS84). |
longitude | Longitude (WGS84). |
beds | Number of bedrooms. |
baths | Bathrooms (half baths count 0.5). |
livingArea | Living area in square feet. |
lotArea | Lot size in lotAreaUnit. |
lotAreaUnit | Unit of lotArea: sqft or acres. |
homeType | SINGLE_FAMILY, CONDO, TOWNHOUSE, MULTI_FAMILY, APARTMENT, LOT, MANUFACTURED, ... |
yearBuilt | Year built (detail rows). |
daysOnMarket | Days on Zillow. |
zestimate | Zillow's estimated market value in USD (Zestimate). |
rentZestimate | Zillow's estimated monthly rent in USD. |
taxAssessedValue | Latest tax-assessed value in USD. |
priceChange | Last price change in USD (negative = price cut). |
priceChangeDate | ISO date of the last price change. |
dateSold | ISO date of the last sale, when known. |
lastSoldPrice | Last sold price in USD (detail rows). |
brokerName | Listing brokerage (company). Agent names, phones and emails are never included. |
photos | Property photo URLs (photos.zillowstatic.com). |
photoCount | Number of photos on the listing (detail rows). |
hasVideo | True when the listing has a video. |
has3DModel | True when the listing has a 3D home tour. |
detailed | True when the row carries the detail fields (description, facts, priceHistory, taxHistory, schools). |
description | Listing description; emails, phone numbers and agent names removed. |
monthlyHoaFee | Monthly HOA fee in USD. |
propertyTaxRate | Property tax rate in percent. |
mlsId | MLS listing number. |
listingDataSource | Where the listing comes from, e.g. the MLS name or 'Phoenix'. |
county | County name (detail rows). |
parcelId | County parcel number. |
facts | Selected building and lot facts: heating, cooling, appliances, flooring, parkingFeatures, garageParkingCapacity, stories, basement, poolFeatures, view, lotFeatures, sewer, waterSource, associationFee, taxAnnualAmount, school names, atAGlanceFacts and more (keys present only when Zillow has them). |
priceHistory | Price events, newest first: {date, event ('Listed for sale', 'Price change', 'Sold', 'Listed for rent'...), price, pricePerSquareFoot, priceChangeRate, source}. No agent names. |
taxHistory | Public tax record per year: {date, taxPaid, value, taxIncreaseRate, valueIncreaseRate}. |
schools | Nearby assigned schools: {name, rating (GreatSchools 1-10), distance (miles), grades, level, link}. |
pageViewCount | Page views Zillow reports for the listing. |
favoriteCount | Times the listing was saved. |
searchInput | The location or search URL this row was found by (null for property URLs). |
searchRank | 1-based position in that search's results. |
scrapedAt | ISO time the row was read. |
input | Error rows: the input that failed. |
code | Error rows: invalid_input, not_found, blocked or unavailable. |
message | Error rows: what went wrong, in plain words. |
Schedule it
In Apify Console, create a Task from your input and add a Schedule (for example daily). Each run writes a new dataset; integrations can push the rows to Google Sheets, Slack, a webhook or your database.