Zillow is where most US home searches start, and its search results already hold what an investor or analyst needs for a first pass: price, size, Zestimate, rent estimate, tax-assessed value and, for sold homes, the sale date and price. What Zillow doesn't offer is an export button. This guide shows how to turn any Zillow search into one row per home, for $1 per 1,000 homes.
What you get
A real row from a recorded run, trimmed:
{
"position": 24,
"zpid": "48848917",
"url": "https://www.zillow.com/homedetails/6008-Oberlin-Ave-NE-Seattle-WA-98115/48848917_zpid/",
"status": "SOLD",
"statusText": "Sold",
"price": 2660000,
"priceText": null,
"soldPrice": 2660000,
"dateSold": "2026-09-25",
"address": "6008 Oberlin Avenue NE, Seattle, WA 98115",
"street": "6008 Oberlin Avenue NE",
"city": "Seattle",
"state": "WA",
"zipcode": "98115",
"latitude": 47.672535,
"longitude": -122.27842,
"beds": 5,
"baths": 4,
"livingArea": 3580,
"lotArea": 6033.06,
"lotAreaUnit": "sqft",
"homeType": "SINGLE_FAMILY",
"daysOnZillow": null,
"zestimate": 2387400,
"rentZestimate": 6636,
"taxAssessedValue": 2035000,
"brokerName": null,
"isBuilding": false,
"buildingName": null,
"units": [],
"imageUrl": "https://photos.zillowstatic.com/fp/1be43f35367174578cfdc5d224aa18ef-p_e.jpg",
"photos": [
"https://photos.zillowstatic.com/fp/1be43f35367174578cfdc5d224aa18ef-p_e.jpg",
"https://photos.zillowstatic.com/fp/cb23425a3f5c2b733dd7a0f07119d34f-p_e.jpg",
"https://photos.zillowstatic.com/fp/0d4baa407e66c88336aaf19f0af3c410-p_e.jpg"
],
"has3DModel": false,
"hasVideo": false,
"isFeatured": false,
"listingLabel": "RecentChange",
"searchLocation": "Seattle, WA",
"searchUrl": null,
"listingType": "sold",
"region": "Seattle",
"totalResults": 28793
}| Field | Meaning |
|---|---|
zpid, url, status, statusText |
Zillow's home ID, the listing link and its status |
price, priceText, soldPrice, dateSold |
Asking price, or sale price and date for sold homes |
address, street, city, state, zipcode, latitude, longitude |
Location |
beds, baths, livingArea, lotArea, lotAreaUnit, homeType |
The property |
zestimate, rentZestimate, taxAssessedValue |
Zillow's value and rent estimates, and the tax assessment |
daysOnZillow, brokerName, listingLabel |
Market context |
imageUrl, photos, has3DModel, hasVideo |
Media |
isBuilding, buildingName, units |
Apartment buildings with their units and prices (rentals) |
searchLocation, searchUrl, listingType, region, totalResults |
Which search produced the row |
Step-by-step
- Open the tool and enter Locations — a city, ZIP code, neighborhood or county, several separated by
;(Austin, TX; 90210; Brooklyn, NY). - Choose a Listing type: homes for sale, for rent, or recently sold.
- Optional: choose Sort by (newest, price low or high, beds, baths, size and more).
- Or paste Search URLs copied from zillow.com after you set filters such as price range, beds, home type or a drawn map area — they are paged exactly as they are.
- Set Max listings per location or URL and click Start. Export as JSON, CSV or Excel.
Run Zillow Scraper (Homes for Sale, Rent & Sold, Zestimates) on Apify →
Call it from code
import json
import os
from apify_client import ApifyClientclient = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("webdatatools/zillow-scraper").call(run_input=json.loads("{\n "locations": "Austin, TX",\n "listingType": "sale",\n "sortBy": "relevance"\n}"))
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('webdatatools/zillow-scraper').call({
"locations": "Austin, TX",
"listingType": "sale",
"sortBy": "relevance"
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
curl -X POST "https://api.apify.com/v2/acts/webdatatools~zillow-scraper/run-sync-get-dataset-items"
-H "Authorization: Bearer $APIFY_TOKEN"
-H "Content-Type: application/json"
-d '{"locations":"Austin, TX","listingType":"sale","sortBy":"relevance"}'Recipes
Sold comps for a neighborhood
Set Listing type to recently sold and Sort by to newest for the ZIP codes around a property. soldPrice, dateSold, livingArea and beds give you a comps table; dividing price by living area gives price per square foot. Note the non-disclosure caveat below for states like Texas.
Rental yield screening
Run the same area twice — once for sale, once for rent — or use the rentZestimate that comes with for-sale listings. Comparing price with rentZestimate across hundreds of homes is a fast first filter for investors before anyone looks at a single listing.
From search results to full property details
Search results don't include a home's full description or price history. Pass this tool's dataset to Zillow Home Details Scraper with inputDatasetId set to this run's dataset ID — it reads the url column and returns description, photos and price history for every home you found.
Covering a whole city
Zillow shows at most 20 pages — about 820 homes — per search. For a large city, split the area: run ZIP codes or neighborhoods separately, or paste several search URLs that split the market by price range. Each row records the search it came from and its zpid, so duplicates across overlapping searches are easy to remove.
How much does it cost?
| Apify plan | Per home | Per 1,000 |
|---|---|---|
| Free plan | $0.001 | $1 |
| Starter | $0.0008 | $0.80 |
| Scale | $0.0007 | $0.70 |
| Business | $0.0006 | $0.60 |
| Enterprise | $0.0006 | $0.60 |
| Enterprise+ | $0.0006 | $0.60 |
Primary event rates from a catalog snapshot; this is not the total price of a run. Additional charge events and Actor Start fees may apply; start fees can scale with memory. Check the Actor's Pricing tab on Apify for all events, conditions and current plan-specific rates, and set a maximum run budget before starting.
The residential proxy Zillow requires from cloud servers is included in the price. Searches that fail or find nothing are listed in the ERRORS record and cost nothing.
How it compares
| Approach | Good at | Watch out for |
|---|---|---|
| This tool | Search results at scale: for sale, rentals and sold; any location or your own filtered search URL; proxy included | Only what search results show — full descriptions, price history, school ratings and agent phone numbers are on each home's own page |
| Browsing zillow.com | Looking at a few homes | No export; copying by hand |
| MLS access | Complete, authoritative listing data | Requires a licensed agent or a paid data agreement |
| Commercial real-estate data providers | Nationwide coverage, history, APIs | Contracts and pricing aimed at enterprises |
FAQ
Why is soldPrice empty for some sold homes?
Texas, Utah and other non-disclosure states don't publish sale prices, so soldPrice stays empty there. dateSold and the Zestimate are still filled.
Why is the Zestimate missing on some homes?
Zillow doesn't publish a Zestimate for every property — new construction and rentals often don't have one.
How many homes can one search return?
Up to about 820 (20 pages), which is Zillow's own limit. Split big areas by ZIP code or price range to collect more.
Why does it need a residential proxy?
Zillow blocks cloud-server IP addresses, so after its first request the tool switches to a US residential proxy. That cost is already included in the per-home price.
Is scraping Zillow legal?
The tool reads public search results that anyone can see without an account. Check that your use is allowed where you are, and respect Zillow's terms if you republish listings.