Zillow Property & Agent Data Scraper
Pricing
Pay per event
Zillow Property & Agent Data Scraper
Extract Zillow property listings with agent contacts (emails, phones), price history, and 70+ data fields. Three search modes: ZIP codes, ZPID list, or any Zillow URL. 40+ filters including tri-state controls for auctions, foreclosures, and new construction. Volume discounts - save up to 37.5%!
Pricing
Pay per event
Rating
4.7
(3)
Developer
Andrey Afanasenko
Maintained by CommunityActor stats
8
Bookmarked
408
Total users
68
Monthly active users
7.7 hours
Issues response
6 days ago
Last modified
Categories
Share
Find homes for sale, rent, and sold across the US — get listing details, photos, and agent contacts in one structured row per property. From $0.05 per property on paid plans, $0.08 on Free.
Zillow's public API only covers properties you own or sell on the Zillow brand network. This actor reads anything Zillow shows in the browser — full filter set, agent emails and phone numbers, price-history arrays, school ratings, photo galleries, and 70+ output columns per row.
🎯 What it does
Three input shapes — pick the one that matches what you have:
| Mode | Input | What it returns |
|---|---|---|
1: ZIP Code Search (mode: "zip") | ZIP codes + 40+ filters | Listings Zillow returns for those ZIPs, enriched. Most-used mode (74% of runs). Cost cap: maxPropertiesPerZip. |
2: ZPID List (mode: "zpid") | Known ZPIDs | Enrichment-only — full property + agent + history per ZPID. Filters and Walk/Photos enrichments ignored. |
3: Zillow URL (mode: "url") | One zillowUrl (search / sold / single-listing) | Whatever the URL resolves to upstream, enriched. Filters embedded in the URL. |
Each row carries the listing essentials (price, status, address, beds/baths, sqft, year built), the financial layer (Zestimate, rent Zestimate, HOA fee, property tax, last-sold, full price history), the agent contact layer (agent name, email, phone, license, brokerage), and the property-detail layer (heating, cooling, appliances, view, fireplace, pool, garage, photos, schools).
ZIP-code mode adds 40+ filters that narrow the search before the actor pays for an enrichment. Tri-state filters (isAuction, isNewConstruction, isForSaleForeclosure) accept any / only / exclude, so you can flip a single field to filter foreclosures out without losing the rest of your filter set. Optional enrichments — Walk Score / Transit Score / Bike Score and full photo galleries — attach extra columns when you enable them.
📦 Output sample
One dataset row, ZIP mode, listing in Beverly Hills with full enrichment enabled:
{"zpid": "20533889","hdpUrl": "https://www.zillow.com/homedetails/123-Palm-Dr-Beverly-Hills-CA-90210/20533889_zpid/","price": 5500000,"status": "ForSale","homeType": "SINGLE_FAMILY","streetAddress": "123 Palm Dr","city": "Beverly Hills","state": "CA","zipcode": "90210","county": "Los Angeles County","neighborhood": "Beverly Hills Flats","latitude": 34.0901,"longitude": -118.4065,"bedrooms": 5,"bathrooms": 4,"bathroomsFull": 3,"bathroomsHalf": 2,"livingArea": 3500,"lotSize": "10,890 sqft","yearBuilt": 2010,"stories": 2,"architecturalStyle": "Contemporary","agentName": "Jane Doe","agentEmail": "jane@example-realty.com","agentEmailSource": "property_details","cellPhone": "310-555-0199","brokerName": "Luxury Real Estate Inc.","zestimate": 5600000,"rentZestimate": 18500,"pricePerSqft": 1571,"hoaFee": 500,"propertyTax": 68500,"priceChange": -100000,"datePriceChanged": "2026-04-12","hasPool": true,"hasGarage": true,"garageSpaces": 3,"hasBasement": false,"view": "City, Mountain(s)","heating": "Forced Air, Natural Gas","cooling": "Central Air","daysOnZillow": 14,"lastSoldDate": "2018-06-22","lastSoldPrice": 4250000,"lastTaxAssessedValue": 4400000,"priceHistory": [{"date": "2026-04-12", "price": 5500000, "event": "Price changed", "pricePerSquareFoot": 1571, "source": "Listing", "postingIsRental": false},{"date": "2018-06-22", "price": 4250000, "event": "Sold", "pricePerSquareFoot": 1214, "source": "Public Record", "postingIsRental": false}],"schools": [{"name": "Beverly Vista Elementary", "level": "Elementary", "rating": 9, "distance": 0.6}],"mainPhoto": "https://photos.zillowstatic.com/fp/abc123-uncropped_scaled_within_1536_1152.jpg","photos": ["https://photos.zillowstatic.com/fp/abc123-uncropped_scaled_within_1536_1152.jpg"],"walkScore": 95,"transitScore": 80,"bikeScore": 88,"listingType": "FSBA, openHouse"}
74 columns are documented in the .actor/dataset_schema.json — you can see every column's type, description, and example in the Apify Console's dataset view.
⚡ Quick start
- Pick a mode: ZIP codes (discover), ZPID list (enrich knowns), or Zillow URL (browser-configured filters).
- Fill in the inputs for that mode. The other modes' inputs are ignored.
- (Optional) Toggle enrichments — Walk Score and Photos — for ZIP mode.
- Run the actor.
- Download in JSON / CSV / Excel / XML, or read the dataset programmatically (see § Programmatic / API use).
Minimal ZIP-mode input:
{"mode": "zip","zipCodes": ["94103"],"maxPropertiesPerZip": 5}
That's a single ZIP, capped at 5 properties — under $0.50 to test on the free plan.
🛠 Input
The input schema is grouped into the following sections (open the Input tab in the Apify Console for the full UI):
- Operation Mode —
mode("zip"/"zpid"/"url"). - ZIP Mode Inputs —
zipCodes,maxPropertiesPerZip. - Search Filters (ZIP only) —
status_type,price_min/max,rentMinPrice/MaxPrice,beds_min/max,baths_min/max,doz,sort,keywords. - Home Type —
isSingleFamily,isTownhouse,isCondo,isMultiFamily,isApartment,isManufactured,isLotLand. - Listing Type & Status —
isForSaleByOwner,isForSaleByAgent,isNewConstruction,isAuction,isForSaleForeclosure,includeForeclosed,includePreForeclosure,isPendingUnderContract,isAcceptingBackupOffers. - Property Features —
sqft_min/max,lotSize_min/max,built_min/max,parkingSpots_min,hasGarage,hasPool,hasAirConditioning,isWaterfront,isBasementFinished,isBasementUnfinished,hoa_max. - View Filters —
isCityView,isMountainView,isParkView,isWaterView. - Tour Filters —
isOpenHousesOnly,is3dHome. - Rental-Only Filters — pet policies (
largeDogsAllowed,smallDogsAllowed,catsAllowed,noPets) + amenities (inUnitLaundry,furnished,hardwoodFloor,utilitiesIncluded,disabledAccess,shortTermLease,outdoorSpace,controlledAccess,highSpeedInternet,elevator,acceptsApplications,incomeRestricted,parkingAvailable). - School Filters —
schools,schoolsRating,includeUnratedSchools. - ZPID Mode Inputs —
zpids. - URL Mode Inputs —
zillowUrl. - Enrichment Options (ZIP only) —
enrichWalkScore,enrichPhotos.
Highlights:
- Tri-state filters (
isAuction,isNewConstruction,isForSaleForeclosure) acceptany(no filter),only(require), orexclude(block). Flip one toexcludeto drop foreclosures without losing your other filter logic. - Filter and enrichment options are silently ignored in ZPID and URL modes — they're not errors, they just don't apply.
- Free plan caps: 15 properties / 20 ZIPs per run, agent emails masked. See § Free vs paid plan.
JSON snippets per mode:
{ "mode": "zip", "zipCodes": ["94103"], "status_type": "ForSale", "maxPropertiesPerZip": 50, "isAuction": "exclude", "hasPool": true }
{ "mode": "zpid", "zpids": ["20521978", "95547747"] }
{ "mode": "url", "zillowUrl": "https://www.zillow.com/homes/for_rent/?searchQueryState=..." }
💰 Pricing
Pay-per-event. You pay only when the actor finishes enriching a property — not for failed lookups, ZIPs that produced zero matches, or URL fetches that didn't yield a property.
| Event | Trigger | Free | Bronze | Silver | Gold | Platinum | Diamond |
|---|---|---|---|---|---|---|---|
apify-actor-start | Actor starts (1 event per GB of memory, minimum 1) | $0.00005 | $0.00005 | $0.00005 | $0.00005 | $0.00005 | $0.00005 |
PROPERTY_ENRICHED | Detailed property info fetched (price, agent contacts, price history, specs) | $0.08 | $0.07 | $0.06 | $0.05 | $0.05 | $0.05 |
Cost math:
- 100 properties on Free ≈ 100 × $0.08 + actor-start ≈ $8.00
- 100 properties on Diamond ≈ 100 × $0.05 + actor-start ≈ $5.00
- 1,000 properties on Diamond ≈ 1,000 × $0.05 + actor-start ≈ $50.00
The actor self-bounds via budgetManager — it stops paying for new enrichments once the budget cap is reached, and records freeLimitBudget to the FREE_LIMITS_APPLIED storage record. You can set a custom per-run budget in the input.
🆓 Free vs paid plan
| Plan | Max properties / run | Max ZIPs / run | Agent emails | Per-event price |
|---|---|---|---|---|
| Free | 15 | 20 | Masked (j***@e***.com) | $0.08 / PROPERTY_ENRICHED |
| Paid (Bronze → Diamond) | Unlimited (budget-bounded) | Unlimited | Full (jane@example.com) | $0.07 → $0.05 / PROPERTY_ENRICHED |
Free-plan ceilings hit during a run are recorded to the FREE_LIMITS_APPLIED storage record so API consumers can switch on them without log-parsing.
🧪 Filter recipes
Single-family for-sale homes in 90210, exclude auctions, must have pool:
{"mode": "zip","zipCodes": ["90210"],"status_type": "ForSale","maxPropertiesPerZip": 50,"isSingleFamily": true,"isCondo": false,"isAuction": "exclude","hasPool": true}
New-construction-only in three Texas ZIPs:
{"mode": "zip","zipCodes": ["78701", "78704", "78745"],"status_type": "ForSale","isNewConstruction": "only","maxPropertiesPerZip": 100}
Furnished pet-friendly rentals in NYC with in-unit laundry:
{"mode": "zip","zipCodes": ["10001", "10011"],"status_type": "ForRent","rentMinPrice": 2500,"rentMaxPrice": 6000,"beds_min": 1,"largeDogsAllowed": true,"inUnitLaundry": true,"furnished": true}
Re-enrich a saved list of ZPIDs (ZPID mode):
{"mode": "zpid","zpids": ["20521978", "95547747", "12345678"]}
🔁 Resume / checkpoint
Long ZIP-mode runs are checkpointed automatically. If the run is aborted, paused, or hits the platform timeout, resurrecting the run picks up from the last checkpoint instead of restarting — you don't pay for already-enriched properties twice.
Resurrect from the Apify Console: open the aborted run → Resurrect button. The next run instance reads the actor's per-run KVS state and skips the already-processed batch. Live progress is mirrored to the status.html storage record while the run is active.
📡 Live status & storage records
The actor writes structured records to its key-value store on every run. Read them with Actor.getValue(<KEY>) from another actor, or fetch them via the REST API.
| Key | What it is | When |
|---|---|---|
RUN_SUMMARY | JSON object with search params, property counts, email-discovery rates, billing totals, and any free-tier limits hit during the run. | End of every run. |
status.html | Auto-updating HTML status page with live scrape progress, budget, and ETA. Open from the Storage tab while the run is active. | Streaming throughout the run. |
FREE_LIMITS_APPLIED | Array<{id, message}> — every free-tier ceiling hit during the run (property cap, ZIP cap, budget exhaustion, email masking). Empty / omitted on paid runs. | End of every free-plan run. |
USER_MESSAGE | {id, title, body} onboarding banner shown to a paying user on their 1st and 3rd paid run. Empty / omitted otherwise. | First / third paid run only. |
SKIPPED_ITEMS | Per-item list of zpids / ZIPs / URLs skipped during the run, with reason and category (filter / not_found / error / free_limit). Useful to re-run the error cohort. | End of every run. |
🤖 Programmatic / API use
Start a run from your own code via the Apify REST API:
TOKEN="<your-apify-token>"ID=YwkoMBHoFxCLI4gpM# Start a synchronous run + read datasetcurl -s -X POST "https://api.apify.com/v2/acts/$ID/run-sync-get-dataset-items?token=$TOKEN&format=json" \-H 'Content-Type: application/json' \-d '{"mode":"zip","zipCodes":["94103"],"maxPropertiesPerZip":5}'
Read the run-end summary from another script:
RUN_ID="<run-id-from-the-launch-call>"curl -s "https://api.apify.com/v2/actor-runs/$RUN_ID/key-value-store/records/RUN_SUMMARY?token=$TOKEN"
The actor is also available via the Apify MCP server (https://mcp.apify.com) — any MCP-aware client (Claude Desktop, Cursor, etc.) can call it as a tool. Input + output schemas in this repo are the source of truth the MCP client reads to build the call signature.
❓ FAQ
Is it legal to scrape Zillow?
The actor extracts only publicly available property listing data; private user data is never touched. Listings include personal information for licensed agents (a public role), which can fall under GDPR and similar regimes — make sure you have a legitimate basis to process it. If unsure, consult legal counsel.
What's the difference between ZIP, ZPID, and URL modes?
- ZIP — discovery from scratch, full filter control.
- ZPID — enrichment of properties you already know.
- URL — Zillow's own UI does the filtering; you paste the resulting URL.
ZIP mode is the only mode where input-schema filters and enrichment toggles take effect.
Can I get agent emails and phone numbers?
Yes. agentEmail, cellPhone, agentLicenseNumber, brokerPhoneNumber ship in the output when Zillow exposes them. The agentEmailSource column tells you which lookup path produced the email (property_details → from the Zillow listing page; agent_profile_direct → from the agent's Zillow profile; agent_search_fallback → name-search match).
On the free plan emails are masked (j***@e***.com); upgrade to a paid plan for the unmasked value.
How do I get a Zillow URL for URL mode?
Configure your filters at zillow.com in the browser, then copy the full address-bar URL (it includes a long searchQueryState=... query string) and paste it into zillowUrl.
Why are some fields null?
Zillow doesn't always publish every field for every listing. Common reasons:
- The data isn't in Zillow's feed for this property.
- An enrichment toggle was off (
walkScore/transitScore/bikeScoreneedenrichWalkScore: true; fullphotosneedsenrichPhotos: true). - The listing is incomplete (e.g. agent details on FSBO listings).
Missing values are returned as null, not the string "N/A".
Can I schedule runs?
Yes — use Apify's built-in Schedules tab on the actor's detail page to trigger the run hourly / daily / on a cron. Each scheduled run is its own paid run.
What happens when a run is aborted mid-way?
The actor checkpoints progress per ZIP / per batch. Resurrecting the aborted run resumes from the last checkpoint (see § Resume / checkpoint). The status.html storage record reflects live progress while the run is active.
🔗 Related actors
| You want to scrape Zillow by… | Use this actor |
|---|---|
| Multi-mode (ZIP + ZPID + URL) — full flexibility | This actor |
| ZIP code only — simpler input, single-mode | zillow-zip-search |
| Search URL — paste any Zillow search page | zillow-url-search |
| MCP server — connect Claude Desktop / Cursor / ChatGPT to Zillow tools | zillow-mcp-server |
🛟 Support & feedback
- Bug or feature request — file an issue from the actor's Issues tab on the Apify Console.
- Custom solutions / enterprise needs — reach out via the actor's Apify Store page.
⚖️ Disclaimer
This actor is a tool for automated retrieval of publicly available data. You're responsible for using it in compliance with Zillow's terms of service, your jurisdiction's data-protection laws (GDPR, CCPA, etc.), and any third-party licenses. The author makes no representation about the accuracy or fitness of Zillow's underlying data for any purpose.