Zillow Scraper: Sale, Rent and Sold Property Listings
Pricing
from $1.00 / 1,000 results
Zillow Scraper: Sale, Rent and Sold Property Listings
Scrape zillow.com properties for sale, for rent and recently sold across the US: price, beds, baths, area, address, GPS, photos, home value and rent estimates. Optional property page read adds HOA fee, tax rate, MLS id, agent, brokerage and the fact sheet. 25 filters, or paste links.
Pricing
from $1.00 / 1,000 results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Pull structured property records from zillow.com across the United States: homes for sale, homes for rent and recently sold homes, in one consistent shape. Search by any US place with 25 filters, or paste links you already have. Every record carries price, beds, baths, area, full address, GPS, photos and the site's own home value and rent estimates; switch on the property page read and it also carries the description, year built, HOA fee, property tax rate, MLS id, listing agent, brokerage and the full fact sheet.
Built for people who need coverage rather than a sample: a large city holds far more homes than any single read of the site returns, so this actor covers the area by splitting it into smaller areas and reading each one, and it tells you plainly when an area still held more than the run collected.
Why this scraper
- Coverage past the site's own ceiling. One read of a map area returns at most 500 records however many exist inside it. This actor splits the area into quarters and reads each, so a city with thousands of homes is genuinely covered instead of truncated at the first few hundred.
- Honest completeness. Every run reports whether it scanned an area end to end. A refused read, an unresolved place or a run cap all mark the scan partial, and the expiry tracking below refuses to act on a partial scan.
- Three channels, one shape. For sale, for rent and recently sold return the same columns, so a rental feed and a sold-comparables feed line up without post-processing.
- 25 filters that were each measured to narrow. Price, beds, baths, area, lot size, year built, HOA fee, property type, keyword, time on market and eight feature toggles. Every one was checked against the live site and moved the result count.
- Recurring monitoring built in. Run the same search daily and get only what changed, marked NEW, UPDATED, REAPPEARED or EXPIRED, with the exact list of fields that moved.
- Pay for results, not for pages. The search-level record costs one result event. Reading each property's own page is optional and billed separately, so you never pay for detail you did not ask for.
- No fields quietly dropped. Agent name, phone, brokerage and MLS id are returned when the property page publishes them, rather than being silently omitted.
Data you get
One record per property. The first block is always present; the second appears when the property page read is switched on.
| Field | Example |
|---|---|
id / zpid | "00000001" |
url | "https://www.zillow.com/homedetails/00000001_zpid/" |
listingType | "FOR_SALE" |
homeStatus | "FOR_SALE" |
propertyType | "SINGLE_FAMILY" |
price | 750000 |
formattedPrice | "$750,000" |
zestimate | 762300 |
rentZestimate | 3450 |
taxAssessedValue | 558793 |
priceChange | -15000 |
streetAddress | "1 Sample Street" |
city / state / zipCode | "Austin" / "TX" / "78759" |
latitude / longitude | 30.4220 / -97.7590 |
bedrooms / bathrooms | 4 / 3 |
livingArea | 2164 |
lotAreaValue / lotAreaUnit | 9352 / "sqft" |
daysOnZillow | 8 |
heroImage / photos | "https://photos.zillowstatic.com/fp/00000000-p_e.jpg" |
description | "Single story home with a large yard..." |
yearBuilt | 1969 |
monthlyHoaFee / propertyTaxRate | 85 / 1.46 |
mlsId / mlsName | "0000000" / "Sample MLS" |
listingAgentName / listingAgentPhone | "Agent Name" / "(555) 010-0000" |
brokerageName | "Sample Brokerage" |
resoFacts | { "parkingCapacity": 2, "propertySubType": ["Single Family Residence"] } |
How to use
Search one city for homes for sale:
{"mode": "search","locations": ["Austin, TX"],"listingType": "FOR_SALE","maxItems": 200}
Search several places for rentals under a price, with filters:
{"mode": "search","locations": ["Brooklyn, NY", "Jersey City, NJ"],"listingType": "FOR_RENT","maxPrice": 3500,"minBeds": 2,"homeTypes": ["APARTMENT", "CONDO"],"daysOnZillow": "30_DAYS","maxItems": 500}
Recently sold comparables with the property page read switched on:
{"mode": "search","locations": ["78759"],"listingType": "SOLD","daysOnZillow": "12_MONTHS","fetchDetails": true,"maxItems": 100}
Paste links you already have:
{"mode": "url","startUrls": ["https://www.zillow.com/homes/for_sale/Austin,-TX/","https://www.zillow.com/homedetails/00000001_zpid/"],"maxItems": 50}
Input parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search builds the search from the location and filters. url takes links you already have. |
locations | array | ["Austin, TX"] | Search mode only. US places written the way you would type them into the site. |
listingType | string | FOR_SALE | Search mode only. FOR_SALE, FOR_RENT or SOLD. |
homeTypes | array | [] | Search mode only. Empty means every type. |
minPrice / maxPrice | integer | none | Search mode only. On a rental search these are the monthly rent bounds. |
minBeds / maxBeds | integer | none | Search mode only. |
minBaths | integer | none | Search mode only. |
minSqft / maxSqft | integer | none | Search mode only. Interior area. |
minLotSize / maxLotSize | integer | none | Search mode only. Lot area in square feet. |
minYearBuilt / maxYearBuilt | integer | none | Search mode only. |
maxHoaFee | integer | none | Search mode only. 0 returns only properties with no HOA fee. |
keywords | string | none | Search mode only. Narrows to properties whose listing text mentions the word. |
daysOnZillow | string | ANY | Search mode only. How recently the property was listed, or sold on a sold search. |
sortBy | string | RECOMMENDED | Search mode only. Changes the order results arrive in, not which properties match. |
hasPool, hasGarage, hasAirConditioning, isWaterfront, singleStoryOnly, has3dTour, openHouseOnly, priceReducedOnly | boolean | false | Search mode only. Feature toggles. |
startUrls | array | none | URL mode only. Search links or property links ending in _zpid. |
fetchDetails | boolean | false | Read each property's own page. Billed per enriched result. |
maxItems | integer | 20 | Run cap across every location or link. 0 means unlimited. |
maxPages | integer | 0 | Optional cap on search reads per location. 0 means no read limit. |
resumeFromRunId | string | none | Continue one interrupted run without returning or billing for what it already collected. |
incrementalMode | boolean | false | Return only what changed since the previous run of the same search. |
stateKey | string | none | Name a monitoring campaign, or deliberately share state between runs. |
emitUnchanged | boolean | false | Also return unchanged results. Adds and bills extra rows. |
emitExpired | boolean | false | Also return results that disappeared. Adds and bills extra rows. |
proxy | object | Apify Proxy | How the run reaches the site. |
mcpConnectors | array | none | Connectors to also send results into. See the section below. |
notionParentPageUrl | string | none | Notion page under which item pages are created. Notion connector only. |
maxNotifyListings | integer | 50 | Cap on items written to each connector per run. Does not affect the dataset. |
Output example
Sample shape - values are illustrative placeholders, not from a live listing.
{"id": "00000001","zpid": "00000001","url": "https://www.zillow.com/homedetails/00000001_zpid/","listingType": "FOR_SALE","homeStatus": "FOR_SALE","statusText": "Active","propertyType": "SINGLE_FAMILY","price": 750000,"formattedPrice": "$750,000","currency": "USD","zestimate": 762300,"rentZestimate": 3450,"taxAssessedValue": 558793,"priceChange": -15000,"priceChangeDate": "2026-01-01","streetAddress": "1 Sample Street","city": "Austin","state": "TX","zipCode": "78759","country": "USA","address": "1 Sample Street, Austin, TX 78759","latitude": 30.422,"longitude": -97.759,"bedrooms": 4,"bathrooms": 3,"livingArea": 2164,"lotAreaValue": 9352,"lotAreaUnit": "sqft","daysOnZillow": 8,"brokerName": "Sample Brokerage","isZillowOwned": false,"has3dTour": true,"heroImage": "https://photos.zillowstatic.com/fp/00000000-p_e.jpg","photos": ["https://photos.zillowstatic.com/fp/00000000-p_e.jpg"],"description": "Single story home with a large yard and a covered patio.","yearBuilt": 1969,"monthlyHoaFee": 85,"propertyTaxRate": 1.46,"pricePerSquareFoot": 254,"mlsId": "0000000","mlsName": "Sample MLS","listingAgentName": "Agent Name","listingAgentPhone": "(555) 010-0000","brokerageName": "Sample Brokerage","resoFacts": {"parkingCapacity": 2,"propertySubType": ["Single Family Residence"]},"detailFetched": true,"scrapedAt": "2026-01-01T00:00:00.000Z"}
Send results into your apps (MCP connectors)
Results can be piped straight into the tools you already use, through Model Context Protocol connectors, without writing any glue.
- Authorize a connector once under Apify, Settings, Integrations.
- Select it in
mcpConnectors. - For Notion, also set
notionParentPageUrlto the page under which item pages should be created. - Use
maxNotifyListingsto cap how many items reach each connector per run. The dataset is unaffected.
Supported connectors: Notion, Linear, Airtable and Apify. Each connector receives a condensed, human-readable summary per item; the complete record always stays in the dataset.
Resume and recurring updates
Two different things, in one input section.
Resume continues ONE interrupted run. Paste that run's id into resumeFromRunId and this run returns only what the previous one did not collect, without billing again for rows you already have.
Incremental mode is for running the same search over and over. Switch on incrementalMode and the first run returns every match as NEW; later runs return only NEW, UPDATED and REAPPEARED, each with changedFields listing exactly what moved, plus firstSeenAt and lastSeenAt. Counters that tick on their own, such as a property's age in days, are deliberately ignored so an unchanged property does not re-bill every day.
Switch on emitExpired to also receive properties that were present before and are gone now. Expiry is only reported after a run scanned the search end to end: a capped run, a resumed run, a refused read or an unresolved place all mark the scan partial, and a partial scan never marks anything expired.
State is kept separately per mode, locations or links, every filter and the property page setting, so two differently configured searches never mix. Set stateKey to name a campaign, or to deliberately share one.
Notes on coverage
- Coverage is US only.
- One read of a map area returns at most 500 records regardless of how many exist there, so the actor splits a busy area into quarters and reads each. A very dense area can still hold more than the split reaches, and when that happens the run says so in its log rather than reporting a complete scan.
- Price history, tax history and school assignments are not returned. Those tables are not published on the pages this actor reads, and inventing empty columns for them would be worse than leaving them out.
- Rental results include building and community entries, which carry a price range rather than one price. They are returned with the fields the site publishes for them.
Plan requirement
Runs on any Apify plan.