Zillow Group Scraper - Zillow, Trulia & HotPads
Pricing
from $2.20 / 1,000 listings
Zillow Group Scraper - Zillow, Trulia & HotPads
Extract US property listings from Zillow, Trulia, and HotPads, including prices, bedrooms, addresses, and available contact details. Pay per delivered row plus a start fee.
Pricing
from $2.20 / 1,000 listings
Rating
0.0
(0)
Developer
kane liu
Maintained by CommunityActor stats
1
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Security
Limited permissionsShare
Zillow Group Scraper
Extract US property listings from Zillow, Trulia, and HotPads as structured rows for market research and export.
- Sale, rental, and recently sold listings, with coverage depending on the brand.
- Prices, bedrooms, bathrooms, addresses, listing links, and available photos.
- Individual property links or several US locations in one run.
- Available agent, property broker, and building contact details.
- Pay for delivered rows: $3.00 per 1,000 rows on the Free plan, plus a start fee.
What does Zillow Group Scraper do?
Zillow Group Scraper collects property data from zillow.com, trulia.com, and hotpads.com. Each dataset row represents one listing or apartment building, identified by rowType="listing" and a brand-specific id.
- Location search: Zillow supports
sale,rent, andsold; Trulia supports sale and rental searches; HotPads is rental-only. - Property links:
detailUrlsreads specific listing or building pages, including mixed brands. - Detail enrichment:
enrichDetailsis on by default and adds available property and contact fields to the same row. - Additional source data:
includeRawis on by default. Zillow details can include Zestimate, price history, tax history, schools, and photos insiderawwhen present.
Separate new_homes, building, zestimate, and mortgage search channels are not available. These options remain in the input form for compatibility; do not select them. Building pages can still be supplied through detailUrls. expandUnits does not create individual apartment-unit rows.
What data can you extract from Zillow Group?
Listing rows
| Field | Description | Example |
|---|---|---|
rowType | Row category, including building pages. | listing |
id | Identity including the source brand. | zillow:12345678 |
listingId | Property identifier from the source. | 12345678 |
brand | Zillow Group brand. | zillow |
name | Display address or property name. | 123 Example St |
listingType | Listing category. | sale |
status | Available listing status. | FOR_SALE |
propertyType | Source property classification. | SINGLE_FAMILY |
price | Numeric price in USD. | 450000 |
priceDisplay | Formatted price; rentals can show monthly rent. | $2,400/mo |
beds | Bedroom count. | 3 |
baths | Bathroom count. | 2.5 |
sqft | Living area in square feet. | 1850 |
yearBuilt | Construction year, if shown. | 2005 |
daysOnMarket | Available days-on-market value. | 12 |
address | Structured postal address. | {"street":"123 Example St","unit":null} |
city | City name. | Austin |
state | US state abbreviation. | TX |
zipCode | ZIP code. | 78701 |
geo | Coordinates, when available. | {"lat":30.27,"lng":-97.74} |
listingUrl | Original property-page URL. | https://www.zillow.com/homedetails/123-Example-St/12345678_zpid/ |
imageUrl | Available main image link. | null |
phones | Agent, brokerage, or building phone entries. | [{"value":"+1 555 0100","type":"agent"}] |
emails | Public attribution email entries, if present. | [{"value":"name@example.com","type":"attribution"}] |
person | Available contact name and role. | {"name":"Jane Doe","role":"agent"} |
org | Brokerage or building organization. | {"name":"Example Realty"} |
leadAbsences | Reasons for missing contact fields. | {} |
leadSource | Whether contact data came from search or detail. | detail |
raw | Additional source fields when enabled and available. | {"zestimate":448000} |
scrapedAt | Collection timestamp. | 2026-10-24T00:00:00+00:00 |
These are illustrative values, not a collected property. Attribute arrays are limited to 50 entries. The same property on different brands can have different IDs; cross-brand matching is not guaranteed.
How to scrape Zillow Group
- Open Zillow Group Scraper in Apify Console.
- Fill
location,locations, ordetailUrls. - Choose a supported brand and channel, and set
maxResultsto3for a small first run. - Click Start and wait for completion.
- Open the dataset and download your rows or read them through the API.
An empty input uses the form's example: Austin, TX, Zillow sale listings, and at most 3 rows. Normal start and row charges apply. A location selects search automatically; nonempty detailUrls selects property details and takes priority over locations.
Location search
Enter a US city and state, such as Austin, TX. Zillow also accepts ZIP, county, and neighborhood searches where recognized. Use city and state for Trulia and HotPads. locations accepts several areas; if you also fill location, that area is included too. Set channel explicitly, or leave it empty to use listingType.
Property details
Paste property links into detailUrls. The brand is detected separately from each URL, regardless of the brand setting. Use actual listing or building pages, not homepages or search-result links. A direct URL usually represents one row; a larger maxResults does not produce multiple copies of that property.
What to fill in
| Field | What to enter | Default |
|---|---|---|
location | One US area. | Empty; example Austin, TX |
locations | Additional US areas. | Empty |
detailUrls | Zillow, Trulia, or HotPads property URLs. | Empty |
brand | zillow, trulia, hotpads, or all. | zillow |
channel | sale, rent, or sold, within brand coverage. | Empty |
listingType | Used when channel is empty: sale, rent, sold, both, or all. | sale |
maxResults | Maximum rows per location or URL, from 1 to 500. | 70; form example 3 |
maxPages | Legacy preference, not a page limit for current collection. | 1 |
propertyTypes | Zillow: house, condo, townhouse, apartment, land, multi_family. | Empty |
minPrice, maxPrice | Zillow price range in USD. | Unset |
minBeds, maxBeds | Zillow bedroom range, from 0 to 10. | Unset |
includeRaw | Include additional source data. | true |
enrichDetails | Add available details to search rows. | true |
failover | Allow another collection attempt after failure. | true |
The fields expandUnits, geoType, saleStatuses, minBaths, maxBaths, minSqft, maxSqft, minLotSqft, maxLotSqft, minYearBuilt, maxYearBuilt, maxHoa, maxDaysOnMarket, loanAmount, creditBand, ltv and loanType are shown in the form but not applied; leave them empty or at their defaults.
Search example:
{"location": "Austin, TX","brand": "zillow","channel": "sale","maxResults": 3,"includeRaw": false}
Detail example; replace the illustrative URL with a real property link:
{"detailUrls": ["https://www.zillow.com/homedetails/123-Example-St/12345678_zpid/"],"maxResults": 1,"includeRaw": false}
maxItems and limit are aliases for maxResults. search, query, city, and zip can name location; startUrls and urls can name detailUrls. Close field-name misspellings are corrected; other unknown fields are ignored with a note.
Each run records how its input was interpreted in INPUT_REPORT in the default key-value store. Invalid inputs that prevent execution stop with INVALID_INPUT: and the field to fix, such as INVALID_INPUT: check detailUrls. No rows are charged in that case; the start fee can still apply. This is not strict validation of every option: unrecognized enum values may be ignored with a warning. Review the report if the selected settings differ from your request.
Output example
{"rowType": "listing","id": "zillow:12345678","recordType": "listing","listingId": "12345678","brand": "zillow","name": "123 Example St","type": "SINGLE_FAMILY","status": "FOR_SALE","country": "United States","authority": "zillow.com","listingType": "sale","price": 450000,"priceDisplay": "$450,000","beds": 3,"baths": 2,"sqft": 1850,"city": "Austin","state": "TX","zipCode": "78701","address": {"street": "123 Example St", "unit": null, "locality": "Austin", "region": "TX", "postalCode": "78701", "country": "US", "full": "123 Example St, Austin, TX 78701"},"phones": [],"emails": [],"listingUrl": "https://www.zillow.com/homedetails/123-Example-St/12345678_zpid/","scrapedAt": "2026-10-24T00:00:00+00:00"}
You can export the dataset as JSON, CSV, Excel, XML, RSS, or an HTML table. RUN_SUMMARY describes the outcome; INPUT_ECHO contains interpreted settings; ERROR_SUMMARY holds details when an error is recorded.
Why use this Zillow Group scraper?
- Pay per delivered row. In addition to the start fee, row charges apply to dataset rows, not unsuccessful page attempts.
- Keep delivered data. Rows already written to the dataset remain available if the run stops. Undelivered data is not guaranteed after a manual stop or failure.
- Compare areas. Several locations or property links can share one run.
- Control output size. Turn off
includeRawfor compact rows, or retain it for available history and property facts. - Inspect missing fields. Missing property values can be null or empty;
leadAbsencesexplains unavailable contacts. - No proxy configuration. You do not need to set up proxies.
How much does it cost to scrape Zillow Group?
The Actor uses pay-per-event pricing. The start event costs $0.005 per GB of selected memory, with a minimum of one event. At the default 512 MB, the start charge is $0.005. Platform usage is included in these prices.
| Apify plan | Start charge at 512 MB | Price per row | Price per 1,000 rows |
|---|---|---|---|
| Free | $0.005 | $0.003 | $3.00 |
| Starter | $0.005 | $0.003 | $3.00 |
| Scale | $0.005 | $0.0026 | $2.60 |
| Business | $0.005 | $0.0022 | $2.20 |
maxResults applies to each input, not separately to every brand or channel. It defaults to 70; larger requests are collected in parts of 70. Available listings may be fewer than requested. All rows for one input share its limit.
Free Apify plan runs are capped at 200 total rows, and free-plan users have 10 runs of this Actor. Paid plans do not have that 10-run cap. The whole run also stops at your Maximum cost per run, set as maxTotalChargeUsd in the API.
Example: two locations delivering 5 rows each produce 10 billed rows. On the Free plan at 512 MB, that is 10 × $0.003 + $0.005 = $0.035.
What happens when the run timeout is too short
When automatic continuation is accepted, a run can pause rather than fail while waiting for results. It shows ABORTED with the status message “Queued on the collection backend; this run will resume automatically when results are ready (about N s).” The same run resumes automatically, writes to the same dataset, and finishes as SUCCEEDED if collection succeeds. Rows already delivered are skipped rather than delivered and charged again.
A resumed delivery can show “Resumed: delivering N rows.” Automatic continuation allows at most 3 pauses per run. Keep the default timeout of 3600 seconds to reduce interruptions. An unrelated failure or manual abort does not carry this promise; check the status message.
The synchronous API endpoints run-sync and run-sync-get-dataset-items wait at most 300 seconds and can return an empty dataset while a run is paused. For longer jobs, start asynchronously and read the dataset after SUCCEEDED, or use a succeeded-event webhook.
Use with AI agents and the API
Apify MCP server (Claude, ChatGPT, Cursor, VS Code)
Add this Actor to a client that supports remote MCP servers:
https://mcp.apify.com?tools=lentic_clockss/zillow-group-scraper
Sign in with Apify through OAuth, or send Authorization: Bearer <YOUR_APIFY_TOKEN>. The tool returns run and dataset IDs; read rows with get-dataset-items. Clients without remote support can use npx @apify/actors-mcp-server --tools lentic_clockss/zillow-group-scraper with APIFY_TOKEN set.
Example prompt: "Get three Zillow sale listings in Austin, TX, and return their prices, bedrooms and listing URLs."
Apify API
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("lentic_clockss/zillow-group-scraper").call(run_input={"location": "Austin, TX", "brand": "zillow", "channel": "sale", "maxResults": 3})for row in client.dataset(run["defaultDatasetId"]).iterate_items():print(row)
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('lentic_clockss/zillow-group-scraper').call({location: 'Austin, TX', brand: 'zillow', channel: 'sale', maxResults: 3});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
For an asynchronous HTTP run, send the input as JSON to POST https://api.apify.com/v2/acts/lentic_clockss~zillow-group-scraper/runs with an Authorization: Bearer <YOUR_APIFY_TOKEN> header. Check GET https://api.apify.com/v2/actor-runs/<runId> for completion, then read GET https://api.apify.com/v2/datasets/<datasetId>/items?format=json.
Integrations
Use Apify integrations with Google Sheets, Make, Zapier, n8n, Slack, Airtable, or your own webhook to pass on results. Use Apify Schedules for recurring runs.
FAQ
Is it legal to scrape Zillow Group sites?
Use public data responsibly. You are responsible for the site's terms and applicable data-protection law. Public availability alone does not give permission for every use; personal data requires a lawful basis.
Why did my run end as ABORTED?
It may be an automatic pause described above, or a manual abort. Only the automatic-resume status message means no action is needed. Inspect the run's status and records before starting another run.
How many results can I get?
maxResults accepts 1–500 rows per input. Source availability, brand coverage, the free-plan cap, and your maximum cost can reduce delivery. A limit is not a guarantee that enough matching properties exist.
Why are some fields empty?
Search cards contain fewer details than property pages. Even with enrichDetails: true, a source may omit a phone, year, or coordinate. HotPads coordinates can be missing. Check leadAbsences for contact-specific explanations.
Can I get email addresses and social links?
Some Zillow detail pages contain public attribution emails, which can appear in emails. Emails hidden behind contact forms are not obtained by submitting those forms. Agent social links are not a supported contact source.
Can I mix brands or collect properties outside the US?
Mixed-brand detailUrls are supported. For location searches, brand: "all" uses the supported brand paths, but does not guarantee equal coverage. This Actor covers the United States, not international portals.
Why did a HotPads sale request return rentals?
HotPads supports rentals only. A non-rental selection falls back to rentals there. Use Zillow for sold listings and avoid Trulia sold searches, which do not have a dedicated sold-results path.
Why did the free-plan run stop without rows?
The 10-run trial allowance may be exhausted. Check the status message and RUN_SUMMARY. A completed search with no matches can also return zero rows; failed collection is reported separately.
Limitations
- Property type, bedroom, and price filters apply to Zillow searches, not Trulia or HotPads searches or direct property links.
- The other inactive filters listed above do not narrow results. Filter downloaded rows where the needed values exist.
- Trulia and HotPads searches read the available first results page; raising the limit does not ensure more inventory.
- Dedicated mortgage, Zestimate, new-home, and building-search channels are unavailable, even though related information may appear on ordinary property pages.
- Complete contact coverage, unit-by-unit building expansion, and a full historical property database are not provided.
- Source changes, removed listings, and unavailable pages can cause missing rows or failed runs.
Related scrapers
More real estate and property data scrapers from the same publisher:
- Zumper Scraper
- Booli Scraper
- Craigslist Scraper
- PropertyGuru Scraper
- OpenSooq Scraper
- Apartments.com Rental Scraper
- Dot Property Scraper
- FINN.no Scraper
Browse all of our scrapers at apify.com/lentic_clockss.
Support
Report a problem or request a field through the Issues tab of this Actor's page. Include the run ID and the input you used.
