Zillow Scraper
Scrape Zillow search results and full listing details: price, beds, baths, sqft, photos, price history, schools. No login or API key. $0.0008 per property.
How it works
- 1Open it on Apify
Hit Run on Apify — it opens the tool in the cloud, no install.
- 2Set the inputs
Adjust
propertyUrls,searchUrls,maxSearchResultsPerUrl(sensible defaults are pre-filled). - 3Click Run
The tool runs on Apify’s cloud and collects the data for you.
- 4Export the results
Download as JSON, CSV or Excel, or pipe straight into your app, Google Sheets, or an AI agent.
Pricing
$0.0008 per property = $0.8 per 1,000
| You are charged for | When | Price |
|---|---|---|
| Property scraped | Charged once per property row successfully returned. Failed, blocked and duplicate lookups are never charged. | $0.0008 |
Pay-per-event pricing: you are billed per result, not per subscription. Billing is handled by Apify on your own account. These are the live Apify store prices, in effect since 2026-08-04, and they are what you are actually charged.
Inputs
| Field | What it does | Type |
|---|---|---|
propertyUrls | Public Zillow /homedetails/ listing URLs to enrich. Empty input returns one clearly labelled, uncharged sample row. | array |
searchUrls | Public Zillow result-page URLs copied from your browser after selecting a location and any public filters. Each URL is fetched once; no hidden or private Zillow endpoint is used. | array |
maxSearchResultsPerUrl | Cap public listing rows emitted from each supplied result page. Lower limits reduce traffic and cost. | integer |
includePhotoUrls | Include public listing photo URLs when Zillow renders them in the current property data. | boolean |
includeHistory | Include publicly rendered price and tax history when Zillow provides it for the property. | boolean |
includeSchools | Adds the schools near each address to detail rows: name, GreatSchools rating, distance, level and type. Empty when Zillow has no school data for that address. | boolean |
enableResidentialFallback | The actor always tries direct browser traffic first. Switch this on to retry each blocked URL once through the proxy below. Metered groups are not offered by this actor. | boolean |
What you get
A structured dataset — each result includes fields like:
addresshomeStatuspricebedroomsbathroomslivingAreazestimateurlExport every run as JSON, CSV or Excel, or send it to your app, a database, Google Sheets, or an AI agent.
1 ready-to-run use cases
Zillow Listing Details, Price History and Schools
Get full Zillow listing details: price, beds, baths, sqft, photos, price history, tax history and schools. No login.
Related tools in Real Estate & Classifieds
Other ready-to-run tools in the same category — all pay-per-use on the Apify cloud.
Realtor.com Scraper
Realtor.com listings as JSON, by city, ZIP or county. Fields: address, price, beds, baths, sqft, year built, days on market, agent, broker. $0.68/1k.
Craigslist Scraper
Scrape Craigslist listings by city, category and keyword: id, title, price, neighborhood, date, images and URL. No account or API key. $0.85 per 1,000.
Airbnb Listings Scraper
Scrape Airbnb listings by location, dates and guests. Get listing ID, name, room type, price, rating, reviews and host. No account, no API key.
Avito Listings Scraper
Scrape Avito.ru listings by keyword, category or city. Get id, title, price, seller name and type, publish date and photos. $0.30 per 1,000 listings.
Facebook Marketplace Scraper
Scrape Facebook Marketplace listings by keyword and city. Rows carry title, price, currency, location, link, posted date, sold status.
Where this tool sits
- Categories
- Real Estate & Classifieds
- Platforms
- Zillow
Zillow Scraper: search results and full listing details, from one actor
Paste Zillow URLs and get property rows back. A /homedetails/ link gives you the full record: price, beds, baths, square feet, the address and coordinates, year built, Zestimate and rent Zestimate, photos, price history, tax history and nearby schools. A search-results link gives you the cards off that page. Same actor, same price for both. No login, no API key.
The limit to know before you plan around it: there is no pagination. A search URL is fetched once, and you get up to 50 rows from that one page. Five search URLs and ten listing URLs per run. Scraping a whole metro means feeding it many narrower search URLs, not one broad one.
| Input | Zillow listing URLs, search-result URLs, or both |
| Output | One row per property |
| Ceiling | 10 listing URLs, and 5 search pages at up to 50 rows each |
| Account needed | None, and no Zillow API key |
| Price | $0.80 per 1,000 properties, flat on every plan |
🔍 What Zillow Scraper does
Two kinds of input, one dataset.
propertyUrls takes canonical /homedetails/ links. Each one is read in full, so those rows carry the history, the nearby schools, the description and the broker attribution when Zillow publishes them.
searchUrls takes result pages copied out of your browser after you have picked a location and any filters on Zillow itself. Those rows are the cards from that page: address, price, beds, baths, living area, Zestimate, status, a photo and the listing URL. They are marked type: "search_listing" so you can tell them apart.
Tracking parameters are stripped and identical URLs collapse, including a listing that appears both in your detail list and on one of your search pages. You pay for it once.
📥 What you give it
{
"searchUrls": ["https://www.zillow.com/austin-tx/"],
"maxSearchResultsPerUrl": 10,
"propertyUrls": [
"https://www.zillow.com/homedetails/7300-Quicksilver-Cir-Austin-TX-78744/29508680_zpid/"
],
"includeHistory": true,
"includeSchools": true
}
| Field | Default | What it is |
|---|---|---|
propertyUrls | empty list | Up to 10 public /homedetails/ URLs. The Console box starts with one example; an API call has to send its own. |
searchUrls | empty list | Up to 5 public result-page URLs. A /homedetails/ link put in here is rejected, because it belongs in the field above. |
maxSearchResultsPerUrl | 10 | 1 to 50 rows kept from each search page. |
includePhotoUrls | on | Keeps the public photo URLs Zillow renders on the page. |
includeHistory | on | Keeps the price and tax history, on detail rows. |
includeSchools | on | Adds the schools near the address to detail rows, with their GreatSchools rating. |
enableResidentialFallback | off | Lets a URL that came back refused be retried once over a different route. |
proxyConfiguration | US network | Used only by that retry. Your own server list, if you give one, is used exactly as supplied. |
Start the run with both lists empty and you get one clearly labelled sample row, so a new task has something in its dataset without pulling any real property.
📤 What you get back
A real detail row from a recent run, with most of the 30 photo URLs cut short:
{
"ok": true,
"zpid": "29508680",
"url": "https://www.zillow.com/homedetails/7300-Quicksilver-Cir-Austin-TX-78744/29508680_zpid/",
"address": "7300 Quicksilver Cir, Austin, TX, 78744",
"city": "Austin",
"state": "TX",
"zipcode": "78744",
"county": null,
"latitude": 30.174002,
"longitude": -97.75795,
"homeStatus": "OTHER",
"homeType": "SINGLE_FAMILY",
"price": 320200,
"currency": "USD",
"bedrooms": 2,
"bathrooms": 2,
"livingArea": 1030,
"lotSize": 8712,
"yearBuilt": 1983,
"zestimate": 320200,
"rentZestimate": 1695,
"daysOnZillow": 3516,
"description": null,
"brokerName": null,
"mlsId": null,
"photos": ["https://photos.zillowstatic.com/fp/3924195d7f4f98284b710c16ff170b00-p_d.jpg", "..."],
"priceHistory": [],
"taxHistory": [],
"schools": [
{ "name": "Perez Elementary School", "rating": 4, "distance": 0.3, "level": "Primary", "type": "Public" },
{ "name": "Paredes Middle School", "rating": 2, "distance": 3.3, "level": "Middle", "type": "Public" },
{ "name": "Akins High School", "rating": 4, "distance": 3.1, "level": "High", "type": "Public" }
],
"scrapedAt": "2026-09-25T00:07:12.598Z"
}
| Field | What it is |
|---|---|
zpid | Zillow's own property ID. Stable, and the deduplication key across runs. |
homeStatus | What Zillow currently says about it. That row above reads OTHER, which is an off-market home, and it still carries a Zestimate. |
price | The asking price when the home is for sale. On an off-market home it is whatever Zillow chooses to show, which is not an asking price. |
zestimate, rentZestimate | Zillow's own estimates. Their model, not a valuation from us. |
priceHistory, taxHistory | Detail rows only, and only when Zillow publishes them. The row above came back with both empty even with the toggle on, which is normal for an off-market property. |
schools | Detail rows only. Up to 30 schools near the address. rating is the GreatSchools score out of 10, distance is in miles, and level and type are Zillow's own labels, such as Primary and Public. Off-market homes get them as well. Empty when Zillow has no school data for the address, or when it could not be read on that run, which the run log says. |
type | search_listing on a row that came off a search page. Absent on a detail row. |
searchUrl, rank | On search rows: which of your URLs produced it, and its position on that page. |
photos | Public listing photos as URLs. Empty when Zillow renders none. |
Fields Zillow leaves out come back null or as an empty array. That does not make the row invalid, and those rows are still charged.
🧾 Reading the output
Three kinds of row can land in your dataset.
| Row | How to spot it | Charged |
|---|---|---|
| A property | ok: true and a zpid | yes |
| The sample row | _sample: true | no |
| A diagnostic | ok: false and an errorCode | no |
| Code | What it means |
|---|---|
BAD_INPUT | The URL is not a Zillow URL this actor takes, or a listing URL landed in the search list. |
NOT_FOUND | Zillow has no page there any more. |
NO_RESULTS | The page loaded but held no usable property record. |
NO_LISTINGS | A search page came back with no cards on it. Often a filter combination with nothing behind it. |
BLOCKED | Zillow refused the request for that URL. |
NETWORK | Zillow was unreachable or answered badly. Re-run it. |
One bad URL never stops the others, and a diagnostic row never fails the run.
A NO_RESULTS that surprises you is worth one retry. Zillow occasionally declines to serve a page in a way that reads as an empty page rather than a refusal, and a second attempt often gets it.
▶️ How to run it
1. Open Zillow Scraper and click Try for free. 2. On Zillow, pick your location and filters, then copy the address bar into Zillow search-result URLs. 3. Paste any specific listings into Zillow property URLs. 4. Set Maximum search listings per URL, then click Start. 5. Download the dataset as JSON, CSV or Excel, or read it from the Apify API.
💰 How much does it cost?
$0.80 per 1,000 properties. Flat on every Apify plan, no volume tiers.
Search rows and detail rows cost the same. Photos, price history, tax history and schools are included at that price and do not add anything per property.
You pay per property row delivered. Duplicates across your two lists, the sample row and every diagnostic row are free.
💡 What people use it for
- Building comps for a valuation: a handful of
/homedetails/URLs in one run, with tax and price
history attached.
- Screening a neighbourhood by pasting a filtered search from Zillow and keeping the top 50 cards.
- Tracking what a specific address does over months, keyed on
zpid, usingpriceand
priceHistory.
- Feeding a model with beds, baths, living area, lot size, year built and Zestimate in one row.
- Pulling listing photos for a set of properties without saving each one by hand.
🚧 What it does not do
- No pagination. One fetch per search URL, capped at 50 rows. A whole city needs many narrower
searches.
- Five search URLs and ten listing URLs per run. That is the hard ceiling.
- No agent contact details. Broker and agent attribution appear only where Zillow publishes
them on the page.
- No Zestimate history. The current estimate, not the series behind it.
- It returns what Zillow publishes. A field Zillow has no data for comes back empty, toggles or
not.
- No logins, no private listings, nothing behind an account.
- Zestimates are Zillow's numbers, with Zillow's accuracy. Nothing here recalculates them.
- Rentals, sold homes and off-market properties come back with whatever Zillow chooses to show
for that status, which is less than an active for-sale listing.
🧭 Which property scraper do you need?
| If you want | Use |
|---|---|
| Zillow listings and full property details | This one |
| US listings, prices and agents on Realtor.com | Realtor.com Scraper |
| Property in Spain, Italy and Portugal | Idealista Scraper |
| Spanish listings from Fotocasa | Fotocasa Scraper |
| Brazilian property data | VivaReal & ZAP Scraper |
❓ Questions people ask
Do I need a Zillow account or API key? No. Paste a public URL.
Can I scrape a whole city in one run? No. Each search URL gives you one page, up to 50 rows. Narrow the search on Zillow first, by ZIP, price band or home type, and run several.
Do photos, history and schools cost extra? No. Same price per property either way.
Why is priceHistory empty when I switched it on? Because Zillow did not publish it for that property. The toggle keeps the data when it exists, it does not create it.
Can I schedule it? Yes, like any Apify actor. A saved set of search URLs makes a weekly sweep straightforward.
Is scraping Zillow legal? These are public listing pages. They can carry personal data, which GDPR, CCPA and similar laws cover, and Zillow has its own terms, so have a reason for collecting it and keep to a sensible request rate. Apify's write-up on scraping and the law is a good place to start, and we are not lawyers.
🆘 If something breaks
Open the Issues tab on the actor page. Send the exact URL and the run ID. The errorCode on the diagnostic row usually names the problem on its own.