Zillow Search Scraper With Property Enrichment avatar

Zillow Search Scraper With Property Enrichment

Pricing

$19.99/month + usage

Go to Apify Store
Zillow Search Scraper With Property Enrichment

Zillow Search Scraper With Property Enrichment

Automate Zillow search scraping with reliable filtering for price, home type, beds, baths, and neighborhood. Retrieve complete listing details, photos, and agent insights. Perfect for building market datasets, powering dashboards, or enriching real estate intelligence tools.

Pricing

$19.99/month + usage

Rating

0.0

(0)

Developer

API Empire

API Empire

Maintained by Community

Actor stats

1

Bookmarked

4

Total users

0

Monthly active users

2 days ago

Last modified

Share

🏑 Zillow Search Scraper

Scrape Zillow property listings at scale from search URLs, locations, or ZIP codes. This Apify actor uses Zillow's internal search API with a dynamic map-zoom engine that subdivides dense areas to beat Zillow's ~820-results-per-query cap, lifts clean columns out of Zillow's raw data, computes derived real-estate metrics, and supports price / beds / baths / sqft / home-type / status filters. An optional detail-enrichment mode adds price history, tax history, agent contact, and schools.

Keywords: zillow scraper, zillow search scraper, real estate data, property listings, zillow api, home prices, zestimate, rent zestimate, real estate lead generation, housing market data, zillow zpid, days on market, price cut, price per sqft, property tax data.

Key features

  • Beats the ~820 cap β€” the dynamic-zoom engine reads Zillow's totalResultCount, recursively subdivides the map bounds into quadrants, paginates each tile, and deduplicates by ZPID across every tile and every URL.
  • Clean lifted columns β€” homeType, homeStatus, rentZestimate, daysOnZillow, lotAreaValue/lotAreaUnit, taxAssessedValue/taxAssessedYear, yearBuilt, priceReduction/priceChange/datePriceChanged, brokerName, and open-house / days-on-Zillow text β€” all lifted from Zillow's nested hdpData blob into flat, usable fields.
  • Honest data (no fake zeros) β€” a listing with no price ("Contact for price") emits unformattedPrice: null (never 0), and shouldShowRequestOnPrice stays as the honest signal. Missing zestimate is null, not 0. Zestimate is always labeled as Zillow's estimate, never a sale price.
  • Derived metrics β€” pricePerSqft, priceVsZestimateDelta + priceVsZestimatePct, priceCutFlag, daysOnMarketBucket, plus scrapedAt.
  • Filters β€” status (for sale / for rent / sold), minPrice/maxPrice, minBeds/maxBeds, minBaths, minSqft/maxSqft, homeType, maxDaysOnMarket, keywords β€” injected into Zillow's searchQueryState.filterState.
  • Location / ZIP resolver β€” bare inputs like dallas-tx or 90210 are resolved into a real Zillow map search (with map bounds), not a naive keyword URL.
  • Photos β€” photoCount and up to N hi-res photoUrls built from Zillow's photo keys.
  • Honest anti-bot handling β€” soft-block detection flags a 200 that actually carries a captcha/HTML challenge (so it is not silently parsed as "empty"), and the proxy chain escalates honestly from direct to Apify Residential.
  • Optional detail enrichment β€” opt-in per-property priceHistory, taxHistory, agent/broker contact, schools, and description, emitted as separate child rows.

Input

FieldTypeDescription
searchUrls (required)arrayFull Zillow search URLs (with searchQueryState) or bare locations / ZIP codes.
extractionMethodstringPAGINATION_WITH_DYNAMIC_ZOOM_INCREASE (default, beats the cap), PAGINATION_WITHOUT_ZOOMING_IN (HTML, ~820), MAP_MARKERS (~500).
maxItemsintegerGlobal cap across all URLs (deduped by ZPID). 0 = as many as possible. Default 10.
statusstringall (default), forSale, forRent, sold.
minPrice / maxPriceintegerPrice range (USD).
minBeds / maxBeds / minBathsintegerBed/bath filters.
minSqft / maxSqftintegerLiving-area range.
homeTypestringall, houses, condos, townhomes, multiFamily, apartments, manufactured, lotsLand.
maxDaysOnMarketintegerNewest-listing filter (mapped to Zillow's nearest bucket).
keywordsstringFree-text keyword filter passed to Zillow.
rawDatabooleanAlso include the raw hdpData blob + full carousel. Default off.
maxPhotosintegerHi-res photo URLs per listing. Default 5.
enableDetailEnrichmentbooleanOpt-in detail pages. Default off.
detailUrlsOrZpidsarrayZPIDs / property URLs to enrich (used only when enrichment is on).
proxyConfigurationobjectResidential recommended (Zillow blocks datacenter IPs).

Input example

{
"searchUrls": ["https://www.zillow.com/dallas-tx/?searchQueryState=%7B...%7D"],
"extractionMethod": "PAGINATION_WITH_DYNAMIC_ZOOM_INCREASE",
"maxItems": 100,
"status": "forSale",
"minPrice": 200000,
"maxPrice": 750000,
"minBeds": 3,
"homeType": "houses",
"proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}

Output

Each listing row includes (among others):

{
"type": "listing",
"zpid": "26822756",
"detailUrl": "https://www.zillow.com/homedetails/...",
"unformattedPrice": 525000,
"price": "$525,000",
"shouldShowRequestOnPrice": false,
"addressStreet": "3810 Hawthorne Ave",
"addressCity": "Dallas",
"addressState": "TX",
"addressZipcode": "75219",
"beds": 3, "baths": 2, "area": 2100,
"homeType": "SINGLE_FAMILY",
"homeStatus": "FOR_SALE",
"yearBuilt": 1998,
"zestimate": 531000,
"rentZestimate": 3200,
"taxAssessedValue": 480000,
"daysOnZillow": 5,
"daysOnMarketBucket": "0-7 days (new)",
"priceCutFlag": false,
"pricePerSqft": 250.0,
"priceVsZestimateDelta": -6000,
"priceVsZestimatePct": -1.13,
"brokerName": "Some Realty",
"photoCount": 34,
"photoUrls": ["https://photos.zillowstatic.com/fp/...jpg"],
"latLong": { "latitude": 32.82, "longitude": -96.81 },
"scrapedAt": "2026-07-03T00:00:00Z"
}

Fields that are genuinely unavailable are emitted as null β€” never a fabricated 0.

Field coverage note (honest): Zillow's search API returns homeType, homeStatus, daysOnZillow, rentZestimate, taxAssessedValue, lotArea*, zestimate and price/bed/bath/area with high coverage. It does not return yearBuilt, priceReduction, or brokerName in the search feed (Zillow only exposes those on the property page), so in a pure search run they are null β€” they are populated when you use Detail Enrichment. priceReduction/priceCutFlag populate only on listings that actually had a price cut.

Detail-enrichment rows (opt-in)

When enableDetailEnrichment is on, each ZPID/URL produces a child row with type: "detail", isDetail: true, and priceHistory, taxHistory, schools, agentName/agentPhoneNumber/agentEmail, brokerName, and description. Absent fields are null. These rows are mirrored to a per-run zillow-details-<runId> dataset and billed under the separate detail_result event.

How to use

  1. Open the actor in the Apify Console.
  2. Paste one or more Zillow search URLs (or locations / ZIP codes).
  3. Optionally set filters (price, beds, home type, status).
  4. Set maxItems and keep proxyConfiguration on Residential.
  5. Run, then open the OUTPUT tab to view / export (JSON, CSV, Excel).

Notes on extraction methods

  • Dynamic zoom (recommended) subdivides the map to collect more than the ~820 listings Zillow returns per single query, deduping by ZPID.
  • Pagination without zooming parses Zillow's HTML pages via __NEXT_DATA__ (capped ~820).
  • Map markers paginates a single query (capped ~500).

Compliance

  • Data is collected only from publicly available Zillow pages.
  • No private, password-protected, or personal-account data is accessed.
  • The user is responsible for legal compliance (privacy, data-protection, and applicable terms).