Request a tool
All toolsAutomationsGuidesMCP serverRequest a toolPlatformsCategories
Zillow Scraper icon

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.

128 runs on Apify $0.0008 per property ($0.8 / 1,000)
Run this in the cloudRun on Apify →

Real Estate & Classifieds

How it works

  1. 1
    Open it on Apify

    Hit Run on Apify — it opens the tool in the cloud, no install.

  2. 2
    Set the inputs

    Adjust propertyUrls, searchUrls, maxSearchResultsPerUrl (sensible defaults are pre-filled).

  3. 3
    Click Run

    The tool runs on Apify’s cloud and collects the data for you.

  4. 4
    Export 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 forWhenPrice
Property scrapedCharged 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

FieldWhat it doesType
propertyUrlsPublic Zillow /homedetails/ listing URLs to enrich. Empty input returns one clearly labelled, uncharged sample row.array
searchUrlsPublic 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
maxSearchResultsPerUrlCap public listing rows emitted from each supplied result page. Lower limits reduce traffic and cost.integer
includePhotoUrlsInclude public listing photo URLs when Zillow renders them in the current property data.boolean
includeHistoryInclude publicly rendered price and tax history when Zillow provides it for the property.boolean
includeSchoolsAdds 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
enableResidentialFallbackThe 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:

addresshomeStatuspricebedroomsbathroomslivingAreazestimateurl

Export 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 iconReal Estate & Classifieds

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.

Ready to run — no setup

Craigslist Scraper iconReal Estate & Classifieds

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.

1 use cases

Airbnb Listings Scraper iconTravel, Hotels & Events

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.

Ready to run — no setup

Avito Listings Scraper iconReal Estate & Classifieds

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.

1 use cases

Facebook Marketplace Scraper iconReal Estate & Classifieds

Facebook Marketplace Scraper

Scrape Facebook Marketplace listings by keyword and city. Rows carry title, price, currency, location, link, posted date, sold status.

Ready to run — no setup

See all Real Estate & Classifieds →

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.

InputZillow listing URLs, search-result URLs, or both
OutputOne row per property
Ceiling10 listing URLs, and 5 search pages at up to 50 rows each
Account neededNone, 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
}
FieldDefaultWhat it is
propertyUrlsempty listUp to 10 public /homedetails/ URLs. The Console box starts with one example; an API call has to send its own.
searchUrlsempty listUp to 5 public result-page URLs. A /homedetails/ link put in here is rejected, because it belongs in the field above.
maxSearchResultsPerUrl101 to 50 rows kept from each search page.
includePhotoUrlsonKeeps the public photo URLs Zillow renders on the page.
includeHistoryonKeeps the price and tax history, on detail rows.
includeSchoolsonAdds the schools near the address to detail rows, with their GreatSchools rating.
enableResidentialFallbackoffLets a URL that came back refused be retried once over a different route.
proxyConfigurationUS networkUsed 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"
}
FieldWhat it is
zpidZillow's own property ID. Stable, and the deduplication key across runs.
homeStatusWhat Zillow currently says about it. That row above reads OTHER, which is an off-market home, and it still carries a Zestimate.
priceThe 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, rentZestimateZillow's own estimates. Their model, not a valuation from us.
priceHistory, taxHistoryDetail 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.
schoolsDetail 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.
typesearch_listing on a row that came off a search page. Absent on a detail row.
searchUrl, rankOn search rows: which of your URLs produced it, and its position on that page.
photosPublic 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.

RowHow to spot itCharged
A propertyok: true and a zpidyes
The sample row_sample: trueno
A diagnosticok: false and an errorCodeno
CodeWhat it means
BAD_INPUTThe URL is not a Zillow URL this actor takes, or a listing URL landed in the search list.
NOT_FOUNDZillow has no page there any more.
NO_RESULTSThe page loaded but held no usable property record.
NO_LISTINGSA search page came back with no cards on it. Often a filter combination with nothing behind it.
BLOCKEDZillow refused the request for that URL.
NETWORKZillow 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, using price and

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 wantUse
Zillow listings and full property detailsThis one
US listings, prices and agents on Realtor.comRealtor.com Scraper
Property in Spain, Italy and PortugalIdealista Scraper
Spanish listings from FotocasaFotocasa Scraper
Brazilian property dataVivaReal & 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.