Zillow Property Listings Scraper – For Sale, Rent & Sold
Pricing
from $1.00 / 1,000 listing row — basic data
Zillow Property Listings Scraper – For Sale, Rent & Sold
Scrape Zillow property listings by city, ZIP, neighborhood, address or search URL — for sale, for rent, sold, new construction and foreclosures. One row per home: address, price, beds, baths, sqft, lot size, year built, Zestimate, agent contact, full-res photos and geo.
Pricing
from $1.00 / 1,000 listing row — basic data
Rating
0.0
(0)
Developer
R.L.
Maintained by CommunityActor stats
1
Bookmarked
15
Total users
2
Monthly active users
5 days ago
Last modified
Categories
Share
Zillow Property Listings Scraper — For Sale, For Rent, Sold, Prices & Zestimates
Zillow Property Listings Scraper — Search Zillow real-estate listings by city, ZIP, neighborhood, address or search-page URL, or look up full property detail by ZPID, via Zillow's private mobile API. Returns the maximum field set: all photos (full-res), price, tax assessment, facts & features, agent contact, Zestimate, geo and IDs. It reads Zillow's own API directly, so it's fast, reliable and complete — no flaky HTML parsing, no headless browser. Export to JSON, CSV, Excel, or an API.
Search any US city, ZIP, neighborhood or address — for-sale, for-rent and sold homes — or look up exact ZPIDs.
What does this Zillow scraper do?
You give it a location — Austin, TX, 90210, Downtown, Austin, TX — or paste Zillow
search-page URLs, or hand it a list of ZPIDs. It returns one row per property: address,
price, beds, baths, living area, lot size, year built, property type, listing status, agent and
broker contact, tax assessment, full-resolution photos, latitude/longitude and the ZPID. Turn on
Include details and each row also gets facts & features, the Zestimate and the listing-type
flags from Zillow's property-detail endpoint.
- No code required — set your input, click Start, download your data.
- Fast & accurate — reads Zillow's own private API and returns structured JSON, not scraped HTML.
- Rich, structured data — every field below, clean and ready to use.
- Full pagination — 40 listings per request, collected to your
maxItemscap. - Transparent pay-per-result pricing — pay only for the rows you get.
- Export anywhere — JSON, CSV, Excel, XML, or pull it live via the Apify API.
What can you do with Zillow data?
- Market research — price, price-per-sqft and days-on-market distributions across a city or ZIP.
- Price & availability monitoring — re-run on a schedule and diff
price,marketingStatusandpriceChange. - Comparable sales (comps) — pull
recentlySoldlistings around an address. - Rental analysis — pull
forRentlistings and compare asking rent againstrentZestimate. - Agent and broker lead lists —
agentName,agentBusinessName,agentPhone,brokerName.
Which listing types and property types can I search?
Listing types (listingType) — pick one bucket per run:
listingType value | What you get |
|---|---|
fsba,fsbo,newConstruction,comingSoon,auction | Everything currently for sale (the default for-sale mix) |
forRent | Rentals |
recentlySold | Sold homes |
foreclosure,preforeclosure,foreclosed | Foreclosures, pre-foreclosures and bank-owned |
Property types (homeTypes) — leave empty for all, or pick any combination. These are the exact
values the API accepts and the exact values that come back in the propertyType field:
homeTypes value | Zillow's label |
|---|---|
singleFamily | Houses |
condo | Condos |
townhome | Townhomes |
multiFamily | Multi-family / duplex |
apartment | Apartments |
manufactured | Manufactured homes |
land | Lots & land |
Can I just paste Zillow search URLs?
Yes — put them in Search URLs and the actor reads the filters straight out of the URL. It understands the location slug, the category segment, and Zillow's inline range filters:
| URL you paste | What the actor derives |
|---|---|
zillow.com/austin-tx/houses/ | Austin, TX + homeTypes: singleFamily |
zillow.com/austin-tx/for-rent/ | Austin, TX + listingType: forRent |
zillow.com/austin-tx/sold/ | Austin, TX + listingType: recentlySold |
zillow.com/austin-tx/new-homes/ | Austin, TX + listingType: newConstruction |
zillow.com/austin-tx/foreclosures/ | Austin, TX + foreclosure statuses |
zillow.com/austin-tx/houses/2-_beds/ | …plus a 2-bed minimum |
zillow.com/austin-tx/3-4_baths/ | …plus a 3–4 bath range |
zillow.com/austin-tx/400000-900000_price/ | …plus a $400k–$900k price range |
zillow.com/90210/ | ZIP slugs pass through as-is |
Other recognised category segments: for-sale-by-owner, fsbo, rentals, recently-sold,
foreclosure, new-construction, coming-soon, auctions, condos, townhomes, apartments,
multi-family, duplex, land, lots-land, single-family. When the URL carries a
searchQueryState blob, its filterState price/beds/baths bounds and its status toggles are read
from there instead.
What do Zillow's own terms mean?
- ZPID — Zillow's permanent numeric ID for a property, the number in a
.../12345678_zpid/URL. Stable across relistings, which makes it the right key to join runs on. - Zestimate — Zillow's estimated market value, computed by Zillow, not an asking price and not an appraisal.
rentZestimateis the same idea for monthly rent. Both are only populated when Include details is on, and Zillow does not publish one for every property. - FSBA vs FSBO — for sale by agent (
isFsba) vs for sale by owner (isFsbo). - The three status fields —
listingStatusis the API bucket (forSale,forRent,recentlySold,other);marketingStatusis the lifecycle (active,comingSoon,offMarket,closed);trueStatusis the MLS-side status string, e.g.Active,Active Under Contract. They can disagree, and the MLS one is the most precise when present. - Contingent / pending —
contingentListingTypeandisPendingmark a listing that is under contract but not closed. - Days on Zillow —
daysOnZillowcounts days since the listing appeared on Zillow, not days since it hit the MLS. - resoFacts — the RESO-standard facts & features block (bathroom breakdowns by full/three-quarter/half/quarter, and more). Only populated when Include details is on.
- Tax assessed value — the county's assessment in
taxAssessmentYear. It is not a market price and is often years stale.
How do I scrape Zillow listings? (3 steps)
- Set your input — a Location (
q), Search URLs, or a list of ZPIDs. - Pick options — listing type, home types, price/beds/baths minimums, Include details, and a
maxItemscap. Keep the default Residential (US) proxy. - Run & export — click Start, then download the dataset as JSON/CSV/Excel or fetch it via the API.
What input does it take?
| Field | Type | Default | Description |
|---|---|---|---|
searchUrls | array of URL | – | Zillow search-page URLs to scrape, e.g. "https://www.zillow.com/austin-tx/houses/2-_beds/". Location, listing type (for-sale-by-owner, new-homes, foreclosures, for-rent, recently-sold), home type (houses, condos, townhomes, land, ...) and inline beds/baths/price ranges are parsed from the URL, as is a searchQueryState blob when present. If set, takes priority over Location (q). |
q | string | – | City, ZIP code, neighborhood, or street address to search — e.g. "Austin, TX", "90210", "Downtown, Austin, TX". This is the main search input; it is resolved to a map area automatically. |
zpids | array of string | – | Look up full detail for these Zillow property IDs. If set, the location/search inputs are ignored. |
north | string | – | Advanced: raw bounding-box north latitude (e.g. 30.35). Optional power-user override — supply all four of north/south/east/west to search an exact map box instead of a Location. |
south | string | – | Advanced: raw bounding-box south latitude (e.g. 30.20). Optional power-user override; used only when all four of north/south/east/west are given. |
east | string | – | Advanced: raw bounding-box east longitude (e.g. -97.70). Optional power-user override; used only when all four of north/south/east/west are given. |
west | string | – | Advanced: raw bounding-box west longitude (e.g. -97.85). Optional power-user override; used only when all four of north/south/east/west are given. |
priceMin | integer | – | Minimum price (USD) |
priceMax | integer | – | Maximum price (USD) |
bedsMin | integer | – | Minimum bedrooms |
bathsMin | integer | – | Minimum bathrooms |
includeDetail | boolean | false | Enrich each search result with facts & features, agent contact, Zestimate and listing-type flags from the GraphQL HDP endpoint (slower, one extra request per property). |
maxItems | integer | 100 | 0 = all matches |
listingType | enum | – | What kind of listings to search for — one of fsba,fsbo,newConstruction,comingSoon,auction, forRent, recentlySold, foreclosure,preforeclosure,foreclosed |
homeTypes | enum array | [] | Restrict results to these property types. Leave empty for all types. Values: singleFamily, multiFamily, condo, townhome, apartment, manufactured, land |
proxyConfiguration | object | Apify Proxy | Route requests through a proxy. Residential (US) is the default and recommended — Zillow's PerimeterX blocks datacenter IPs. |
Example input
{"q": "Austin, TX","zpids": [],"includeDetail": false,"maxItems": 100,"proxyConfiguration": {"useApifyProxy": true,"apifyProxyGroups": ["RESIDENTIAL"]}}
What does a row look like?
Each result is a JSON object like this:
{"zpid": 454188962,"url": "https://www.zillow.com/homedetails/454188962_zpid/","streetAddress": "Madison-321 Plan, The San Francisco Shipyard : Madison","city": "San Francisco","state": "CA","zipcode": "94124","price": 554000,"currency": "usd","pricePerSquareFoot": 773,"bedrooms": 1,"bathrooms": 1,"livingArea": 717,"lotSize": null,"lotSizeUnit": null,"yearBuilt": 2026,"propertyType": "condo","listingStatus": "forSale","marketingStatus": "active","daysOnZillow": 0,"latitude": 37.7281,"longitude": -122.3706,"brokerName": null,"agentName": null,"agentBusinessName": null,"agentPhone": null,"taxAssessedValue": null,"taxAssessmentYear": null,"photoCount": 13,"photos": ["https://photos.zillowstatic.com/fp/d90d5a51db965cc028d2d54e6a887bb4-p_f.jpg","https://photos.zillowstatic.com/fp/8a8bf73710dc2133ccc047446ce33a58-p_f.jpg","…+11 more"],"hasVideos": false,"has3DTour": true,"resoFacts": {"bedrooms": 1,"bathrooms": 1,"bathroomsFloat": 1,"bathroomsFull": 1,"bathroomsThreeQuarter": 0,"bathroomsHalf": 0,"bathroomsOneQuarter": null,"bathroomsPartial": null},"homeStatusText": "Active","trueStatus": "Active","contingentListingType": null,"newConstructionType": null,"isZillowOwned": false,"timeZone": "America/Chicago","zestimate": 409100,"rentZestimate": null,"priceChange": null,"virtualTourUrl": null,"floorPlanUrl": null,"isFsba": true,"isFsbo": false,"isPending": false,"isNewHome": false,"isForeclosure": false,"isComingSoon": false,"isBankOwned": false,"isForAuction": false,"isOpenHouse": true}
Which fields are in the dataset?
| Field | Type | Description |
|---|---|---|
zpid | number | ZPID |
url | link | URL |
streetAddress | text | Street address |
city | text | City |
state | text | State |
zipcode | text | ZIP |
price | number | Price |
currency | text | Currency |
pricePerSquareFoot | number | Price / sqft |
bedrooms | number | Beds |
bathrooms | number | Baths |
livingArea | number | Living area (sqft) |
lotSize | number | Lot size |
lotSizeUnit | text | Lot size unit |
yearBuilt | number | Year built |
propertyType | text | Property type |
listingStatus | text | Listing status |
marketingStatus | text | Marketing status |
daysOnZillow | number | Days on Zillow |
latitude | number | Latitude |
longitude | number | Longitude |
brokerName | text | Broker |
agentName | text | Agent |
agentBusinessName | text | Agent business |
agentPhone | text | Agent phone |
taxAssessedValue | number | Tax assessed value |
taxAssessmentYear | text | Tax year |
photoCount | number | Photo count |
photos | array | Photos (full-res) |
hasVideos | text | Has videos |
has3DTour | text | Has 3D tour |
resoFacts | object | Facts & features |
homeStatusText | text | Status (display) |
trueStatus | text | MLS status |
contingentListingType | text | Contingent type |
newConstructionType | text | New construction type |
isZillowOwned | boolean | Zillow owned |
timeZone | text | Time zone |
zestimate | number | Zestimate |
rentZestimate | number | Rent Zestimate |
priceChange | text | Price change |
virtualTourUrl | link | Virtual tour |
floorPlanUrl | link | Floor plan |
isFsba | boolean | For sale by agent |
isFsbo | boolean | For sale by owner |
isPending | boolean | Pending |
isNewHome | boolean | New home |
isForeclosure | boolean | Foreclosure |
isComingSoon | boolean | Coming soon |
isBankOwned | boolean | Bank owned |
isForAuction | boolean | For auction |
isOpenHouse | boolean | Open house |
raw | object | Raw API record |
zestimate, rentZestimate, resoFacts, priceChange, virtualTourUrl, floorPlanUrl,
trueStatus, contingentListingType, timeZone and the is* listing-type flags come from the
property-detail endpoint, so they are populated when Include details is on and on ZPID lookups
(which always return the full detail set). raw carries the untouched API record if you need a
field this table does not flatten.
How much does it cost?
This actor uses pay-per-event pricing: you pay only for the rows it delivers.
| You scrape | Price |
|---|---|
| Listing row — basic data | $1.00 per 1,000 rows |
| Listing details — photos, price/tax history, facts | $0.50 per 1,000 rows |
How do I run it from my own code?
Run it programmatically with the Apify API:
curl -X POST "https://api.apify.com/v2/acts/zillow-api-scraper/runs?token=YOUR_TOKEN" \-H 'Content-Type: application/json' \-d '{"q": "Austin, TX","zpids": [],"includeDetail": false,"maxItems": 100,"proxyConfiguration": {"useApifyProxy": true,"apifyProxyGroups": ["RESIDENTIAL"]}}'
Or with the Apify CLI: apify call zillow-api-scraper -i input.json -o.
FAQ
Do I need a Zillow account or API key?
No. The actor carries the Zillow Android app's own credentials and calls Zillow's mobile API for you — all you need is an Apify account.
Do I need a residential proxy?
Yes, and it is the default. Zillow fronts its endpoints with PerimeterX, which blocks datacenter IPs, so the input ships with Apify Proxy set to Residential, country US. Leave it alone unless you are supplying your own US residential pool.
How do I search a whole city, a ZIP or one exact address?
All three go in the Location field. A city or ZIP resolves to Zillow's own map region and is paginated 40 listings at a time. A full street address resolves to that one property, and the actor looks that property up directly instead of searching its neighbourhood — so you get the home you asked for, not its block.
Can I scrape sold homes and rentals, not just for-sale?
Yes. Set Listing type to recentlySold for sold homes, forRent for rentals, or the foreclosure bucket for foreclosures, pre-foreclosures and bank-owned. Or just paste a /sold/, /for-rent/ or /foreclosures/ Zillow URL and the actor derives it.
What does "Include details" actually add?
One extra request per property against Zillow's property-detail endpoint, which fills in the Zestimate, the rent Zestimate, resoFacts (facts & features), price-change info, virtual-tour and floor-plan URLs, the MLS status, and the isFsba/isFsbo/isPending/isForeclosure-style flags. It is slower and billed as a second event per row, so leave it off if the search fields are enough.
Can I schedule it and only pick up what changed?
Yes — run it on Apify's scheduler and join runs on zpid, which is stable across relistings. daysOnZillow, marketingStatus and priceChange are the fields to diff. Results come back sorted by days on Zillow ascending, so the newest listings arrive first.
How is the cost bounded?
You pay per row. maxItems is the hard ceiling for a run (0 = every match), and leaving Include details off halves the per-row event count. Set maxItems and you know your maximum bill before you start.
Is scraping this legal?
You are responsible for how you use the data. Scrape only public real-estate listing data and comply with Zillow.com's Terms and applicable law (e.g. GDPR/CCPA for personal data).
How does it work under the hood?
The actor impersonates Zillow's official Android app and calls the same private endpoints the app does — mobile search for listings, mobile lookup for ZPIDs, and Zillow's GraphQL property-detail query for the extras — then normalises each response into the flat record above. Location strings go through the app's own autocomplete to get a region ID and viewport, which is cached for the run so a paginated job resolves once. No browser, no HTML scraping — just clean, structured data.
Good to know
- Scrape only public real-estate listing data and respect Zillow.com's Terms of Service and robots policy.
- For personal data, comply with GDPR/CCPA and applicable law — you are the data controller.
- Fields can be
nullwhen Zillow doesn't expose them for a given record.
Global real estate toolkit
Part of the Global real estate toolkit — real-estate listing data across major US, European, and Australian property portals:
- Redfin API Scraper — Scrape Redfin listings — address, price, beds/baths, sqft, status, agent.
- realestate.com.au API Scraper — Scrape realestate.com.au property listings (buy/rent/sold) with full detail, media, and agent contact.
- ImmoScout24 API Scraper — Scrape ImmoScout24 real-estate listings (Germany) with full detail, images, and agent contact.
Found this useful?
Give the Zillow Property Listings Scraper a star on Apify and check out my other apify-*-api-scraper actors.