Zillow Property Scraper: Sale, Rent & Sold Homes avatar

Zillow Property Scraper: Sale, Rent & Sold Homes

Pricing

from $1.75 / 1,000 property results

Go to Apify Store
Zillow Property Scraper: Sale, Rent & Sold Homes

Zillow Property Scraper: Sale, Rent & Sold Homes

Search Zillow listings by city, ZIP or search link and get full property details in the same run: description, photos, price and tax history, agent phone, sale date. Apartments for rent come back one row per unit with leasing phone and office hours. $2.50 per 1,000 homes, details included.

Pricing

from $1.75 / 1,000 property results

Rating

0.0

(0)

Developer

herus13

herus13

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

17 hours ago

Last modified

Categories

Share

This Zillow scraper returns homes for sale, sold homes and rentals with full property details in one run: description, photos, price and tax history, and the listing agent's name and phone. There is no second detail run to set up or pay for. $2.50 per 1,000 homes on the Free plan, less on paid plans.

What you get

Built for:

  • Sold-home research: sale date and county assessed value on sold rows, kept even in states that withhold the sale price.
  • Rental market research: apartment buildings come back one row per unit, with rent, beds, baths, the leasing office's phone and its office hours.
  • Agent outreach: listing agent name, phone and brokerage on most for-sale and sold listings.

Search a city or ZIP, paste a Zillow search link, or list property URLs.

Three listing types, one input. for_sale, for_rent and sold (sale date and final price where the state discloses it).

Rentals in apartment buildings come back one row per unit. Each row has the unit number, rent, beds, baths, sqft, the leasing office's name and phone, its office hours (such as Mon - Fri: 8:30AM - 5:30PM) and a verified_source flag when Zillow marks the contact as a trusted source. Search a city for rentals; building links are not required.

One dataset row per property, flat enough to open in Excel. Export as JSON, CSV or Excel.

{
"zpid": "12345678",
"url": "https://www.zillow.com/homedetails/123-main-st/12345_zpid/",
"address": "123 Main St, San Francisco, CA 94102",
"city": "San Francisco",
"state": "CA",
"zipcode": "94102",
"latitude": 37.7749,
"longitude": -122.4194,
"price": 1250000,
"listing_type": "for_sale",
"status": "for_sale",
"beds": 3,
"baths": 2.0,
"sqft": 1850,
"year_built": 1965,
"property_type": "house",
"days_on_market": 14,
"price_per_sqft": 676,
"zestimate": 1300000,
"rent_zestimate": 5800,
"agent_name": "Jane Smith",
"agent_phone": "415-555-0100",
"brokerage": "Compass",
"mls_id": "ML81912345",
"scraped_at": "2026-04-12T10:30:00Z",
"_meta": {"author": "https://apify.com/herus13", "status": "ok", "message": null}
}

_meta is run metadata, not scraped data. A target that fails appears as a row with only _meta (status failed, the reason in message); those rows are never charged.

A full row also carries street, lot_size_sqft, hoa_fee, description, features, agent_email, photos, price_history, tax_history, office_hours, verified_source, walk_score, bike_score, transit_score, date_sold and tax_assessed_value. photos and features are lists of strings; price_history and tax_history arrive as JSON-encoded strings, so a CSV or Excel export opens without a column blowing up. A field Zillow does not publish for a listing is null, never guessed:

  • zestimate and rent_zestimate come back from Zillow as null for most active for-sale and for-rent listings (Zillow only attaches one to some), and are filled for sold listings.
  • agent_name, agent_phone, brokerage and mls_id are filled for most for-sale and sold listings; a few sold listings carry no agent phone.
  • Rentals in apartment buildings (one row per unit) carry the leasing office as agent_name and brokerage, its agent_phone, office_hours (a list such as "Mon - Fri: 9:00AM - 6:00PM", empty when the building lists none) and verified_source (true when Zillow marks the contact as a trusted source). They have no description, mls_id or price history.
  • walk_score, bike_score and transit_score are filled for for-sale and sold listings and null for apartment-building units. A score outside 0-100 is null, and transit_score is null where Zillow has no transit data for the address.
  • date_sold is the sale date (YYYY-MM-DD) of a sold listing, and null for every other listing type or when Zillow gives none. It is filled even where price is withheld.
  • tax_assessed_value is the county's assessed value, filled for any listing type where Zillow publishes one and null otherwise. It is not a sale price.
  • price is null for sold homes in states that do not disclose sale prices (Texas, Utah, Missouri, Idaho, Wyoming, Montana, New Mexico, North Dakota, Mississippi, Kansas, Alaska and Louisiana were checked; the same applies to any other state that withholds it). The row still carries the address, size, Zestimate, scores and description; some of those rows also lack agent fields.
  • agent_email is always null: Zillow does not publish listing agents' email addresses on any listing type.

Feedback

Found this useful? Leave a review on Apify - five stars, Herus13

Found this useful? Leave a review on Apify.

What it costs

EventFreeBronzeSilverGold+
Actor Start (apify-actor-start)$0.00005$0.00005$0.00005$0.00005
property result (property-result)$0.0025$0.00225$0.002$0.00175

Input

FieldTypeRequiredDefaultWhat it does
search_urlstringno—A Zillow search results page to scrape in full, for example https://www.zillow.com/san-francisco-ca/rentals/. Build the search on Zillow, copy the URL, paste it here, and every listing it returns becomes a row. The URL carries its own filters, so the filter fields below are not applied to it. Leave empty to search by location or to scrape property_urls instead.
locationstringno—Where to search, written as city and state or as a ZIP code, for example San Francisco, CA or 94102. Combine it with the listing type and the price, bedroom, bathroom, area and property-type filters below. Leave empty when you are using search_url or property_urls instead.
listing_typestringno"for_sale"Which listings a location search returns: for_sale for homes on the market, for_rent for rentals, sold for recently sold homes with their final price (null where the state does not disclose sale prices, such as Texas). Default for_sale. It has no effect on search_url or property_urls, which carry their own listing type.
min_priceintegerno—Lowest listing price to keep, in US dollars, 0 or more — for example 500000. Leave empty for no lower bound. Applies to a location search only.
max_priceintegerno—Highest listing price to keep, in US dollars, 0 or more — for example 1500000. Leave empty for no upper bound. Applies to a location search only.
beds_minintegerno—Fewest bedrooms a listing may have, 0 or more. Leave empty for no lower bound. Applies to a location search only.
beds_maxintegerno—Most bedrooms a listing may have, 0 or more. Leave empty for no upper bound. Applies to a location search only.
baths_minnumberno—Fewest bathrooms a listing may have, 0 or more; half baths count as 0.5. Leave empty for no lower bound. Applies to a location search only.
baths_maxnumberno—Most bathrooms a listing may have, 0 or more; half baths count as 0.5. Leave empty for no upper bound. Applies to a location search only.
sqft_minintegerno—Smallest interior area to keep, in square feet, 0 or more — for example 1000. Leave empty for no lower bound. Applies to a location search only.
sqft_maxintegerno—Largest interior area to keep, in square feet, 0 or more — for example 4000. Leave empty for no upper bound. Applies to a location search only.
property_typearrayno—Kinds of property to keep, one per entry: house, condo, townhouse, multi_family, land, apartment. Leave empty to keep every kind. Applies to a location search only.
days_on_market_maxintegerno—Keep only listings that have been on the market this many days or fewer, at least 1 — 7 gives you the past week, which is what a new-listings alert wants. Leave empty to keep listings of any age. Applies to a location search only.
property_urlsarrayno—Zillow property pages to scrape exactly, one URL per entry, shaped https://www.zillow.com/homedetails/123-main-st/12345_zpid/. Each URL returns one row with the full field set. Leave empty to work from search_url or location instead.
max_resultsintegerno100Most properties the whole run may return, from 1 to 10000. Default 100. A Zillow search page holds about 40 listings, and pages are followed until this cap or the end of the results, whichever comes first. It is the ceiling on how much one run collects.
include_photosbooleannotrueAdd the listing's photo URLs to each row, as photos. Default true. Set it to false for a narrower export when you only need the numbers.
include_price_historybooleannotrueAdd the dates, events and prices behind the current asking price to each row, as price_history. Default true. It is what makes a price cut or a relisting visible without scraping the same home twice. Set it to false to leave it out.
proxyUrlsarrayno—Leave empty and the run uses the residential proxy this actor ships with, included in the price of the run. To route the run through your own account instead, add one gateway URL per entry, for example http://user:pass@host:port — works with any provider that issues URLs. When set, the run uses these first and switches to the included proxy if they stop working, so a broken proxy never fails the run.

How to run it

  1. Open the actor on Apify Console and click Try for free.
  2. Pick one way in: paste a Search URL, set a Location with filters, or paste Property URLs.
  3. Choose the listing type and any filters, then Run. Export JSON, CSV or Excel from the dataset.
{
"location": "San Francisco, CA",
"listing_type": "for_sale",
"min_price": 500000,
"max_price": 1500000,
"beds_min": 2,
"property_type": ["house", "condo"],
"days_on_market_max": 30,
"max_results": 200
}

Minimal input:

{
"location": "San Francisco, CA"
}

Available as the MCP tool herus13--zillow-property-scraper on mcp.apify.com and through the Apify API; send the same JSON.

Why this scraper

  • Three ways in. A saved Zillow search you already use, a plain location with filters, or exact property URLs — whichever matches how you work.
  • For sale, for rent and sold from one input. Comparable sales and active inventory land in the same table with the same columns, which is what a comps analysis needs.
  • Price history on the row. Reductions, relistings and time on market are visible from a single run, instead of having to be reconstructed by scraping the same home week after week.
  • Zestimate next to the asking price. The estimate and the market's answer sit side by side, which is the pair a pricing model is judged against.
  • Agent and brokerage details included. Name, phone, brokerage and MLS ID come with most sale and sold listings (no email: Zillow does not publish it), so market activity can be segmented by who is selling it.

Use cases

  • Real estate databases — Build and refresh a table of active, rented and sold inventory for a city or ZIP code, with 30 fields per home rather than the handful a listing page shows.
  • Price-change and days-on-market tracking — Watch reductions and stale inventory per property using price_history and days_on_market, not a diff of two exports.
  • Valuation modelling — Train or check a model against zestimate, price, price_per_sqft, year_built and lot_size_sqft on real inventory.
  • Comparable sales research — Set the listing type to sold and pull the recent closings in a neighbourhood with their final prices and history.
  • Agent and brokerage lead sourcing — Find who is active in a market and at what price point, from the agent and brokerage fields on every listing.
  • Rental market analysis — Compare asking rents against rent_zestimate by neighbourhood, bedroom count and square footage.

FAQ

Which of the three input modes should I use? A Search URL when you already built the search on Zillow and want exactly what it shows. Location plus the filters when you want to describe the search here. Property URLs when you have a specific list of homes.

Can I scrape sold properties? Yes. Set Listing Type to sold and you get recently sold homes with their final price (where the state discloses it, see the field notes above) and price history, alongside the same address, size and agent fields as active listings, plus the Zestimate and rent Zestimate that Zillow attaches to sold homes.

How many results can I get in one run? Up to 10,000 through Max Results. A Zillow search page holds about 40 listings, and pages are followed until the cap or the end of the results.

Which property types can I filter by? house, condo, townhouse, multi_family, land and apartment. Pass any combination, or leave the field empty to keep every type.

Is a proxy included? A residential proxy is included in the price of the run. To use your own, paste gateway URLs into Your own proxy URLs.

What happens if my input is wrong? The run stops before it scrapes anything, so no results are charged. Its status and log name each field that is wrong and say what to change — fix the input and run again.

Is scraping Zillow legal? This actor collects only publicly available listing data. You are responsible for complying with Zillow's terms and applicable laws. Do not collect personal data without a lawful basis.

Building a wider property or lead pipeline? Pair this actor with: