Redfin Scraper - Homes for Sale & Sold Listings
Pricing
from $1.20 / 1,000 listing results
Redfin Scraper - Homes for Sale & Sold Listings
Scrape redfin.com home listings: price, beds, baths, sqft, lot, year built, coordinates, address, MLS, status, days on market, photos, schools, amenities, tax records, agent and brokerage plus 90+ fields. Search any city, ZIP, neighborhood, or county with sort and filters, or paste Redfin URLs.
Pricing
from $1.20 / 1,000 listing results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
4
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Redfin Scraper: Homes for Sale, Sold Listings & Property Data
Redfin Scraper pulls structured home listings from redfin.com at scale. Search any city, ZIP code, neighborhood, or county, narrow with sort and filters, and get a clean JSON record per home with price, beds, baths, square footage, lot size, year built, coordinates, address, MLS number, status, days on market, photo data, key facts, and listing remarks, plus the listing agent and brokerage when detail enrichment is on. Or paste Redfin region and listing URLs and let the scraper walk them for you, then export to JSON, CSV or Excel, or pull the results straight into your app through the API.
Why This Scraper?
- 90+ fields per listing. Price, price per sq ft, beds, full and partial baths, square footage, lot size, stories, year built, HOA dues, coordinates, MLS number, status, days on market, photos, key facts, tags and the full listing remarks on every search result.
- Search or paste URLs. Find homes by city, ZIP, neighborhood or county with sort and filters, or paste exact Redfin region and listing URLs and pull them verbatim.
- For sale or recently sold. Switch between active listings and homes sold in the last three years.
- Optional detail enrichment. Add the listing agent, brokerage, valuation label, nearby schools with ratings, structured amenities, home highlights, public and tax records, and the Redfin Estimate per home.
- Predictable cost. One Max listings cap controls exactly how many records a run returns, with a separate Max pages safety stop for paging depth.
- Built for schedules. Incremental mode returns only new and changed listings on recurring runs, and a genuinely blocked run fails loudly instead of returning an empty dataset.
- MCP export. Optionally pipe results straight into Notion, Linear, Airtable, or Apify.
Use Cases
- Real estate investors and analysts: track pricing, days on market and price-per-sqft trends across neighborhoods to spot value.
- Agents and brokerages: monitor competing listings, new inventory and price changes in a farm area on a schedule.
- Real estate data products and dashboards: feed structured listing data into your own search, map or comps tool.
- Market researchers: build historical datasets of sold homes, including sale dates and property details, for trend analysis.
- Lead generation tools: collect listing agent and brokerage details alongside property data for outreach lists.
Data You Get
Sample shape: values are illustrative placeholders, not from a live listing. Fields below come from a search result or a pasted region URL. A pasted single listing URL returns a narrower record; see "Paste a single listing URL" under How to Use.
| Field | Example |
|---|---|
id | 12345678 |
url | "https://www.redfin.com/IL/Chicago/123-Example-St-60601/home/12345678" |
price | 575000 |
priceType | "List price" (when detail enrichment is on) |
pricePerSqFt | 311 |
beds | 3 |
baths | 2.5 |
bathFull / bathPartial | 2 / 1 |
sqft | 1850 |
lotSize | 4200 |
yearBuilt | 1998 |
hoaDues | 250 |
propertyTypeLabel | "Condo/Co-op" |
status | "Active" |
daysOnMarket | 12 |
streetLine | "123 Example St" |
city / state / zip | "Chicago" / "IL" / "60601" |
latitude / longitude | 41.8781 / -87.6298 |
mlsId | "mred00000000" |
photos | "0-24:0" (photo count descriptor) |
listingTags | ["Hardwood flooring"] |
listingRemarks | "Bright corner unit with lake views and an updated kitchen." |
listingAgent | "Alex Example" (when detail enrichment is on) |
brokerName | "Example Realty Group" (when detail enrichment is on) |
scrapedAt | "2025-01-01T00:00:00+00:00" |
With detail enrichment on, each record also carries mainHouseInfo (full street address plus canonical URL), schools (nearby schools with ratings, grade ranges and distance), amenities (structured group/value pairs), homeHighlights, publicRecords (APN, tax rate, county), and redfinEstimate (amount and label, only on homes where Redfin publishes one). Incremental mode additionally adds changeType, changedFields, firstSeenAt and lastSeenAt to every returned row.
How to Use
- Pick a mode:
search(by location + filters) orurl(paste Redfin links). - Fill in the fields for that mode: locations, listing type, sort and filters for search, or region/listing links for url mode.
- Set Max listings (and optionally Max pages) to control run size and cost, then click Start.
- Download the dataset as JSON, CSV or Excel, or read it through the API.
Search a city for homes for sale (default):
{"mode": "search","locations": ["Chicago, IL"],"listingType": "for_sale","maxItems": 50}
Filtered search, cheapest first, condos only:
{"mode": "search","locations": ["Austin, TX", "78701"],"propertyTypes": ["Condo"],"sortBy": "price_low","minPrice": 300000,"maxPrice": 700000,"minBeds": 2,"maxItems": 100}
Recently sold homes with full detail:
{"mode": "search","locations": ["Brooklyn, NY"],"listingType": "sold","fetchDetails": true,"maxItems": 40}
Paste region and listing URLs:
{"mode": "url","urls": ["https://www.redfin.com/city/29470/IL/Chicago","https://www.redfin.com/IL/Chicago/123-Example-St-60601/home/12345678"]}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/redfin-scraper").call(run_input={"mode": "search", "locations": ["Chicago, IL"], "maxItems": 50})for home in client.dataset(run["defaultDatasetId"]).iterate_items():print(home["streetLine"], home["price"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/redfin-scraper').call({ mode: 'search', locations: ['Chicago, IL'], maxItems: 50 });const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
How Max listings and Max pages interact
Max listings (maxItems) is the only cap on total results; it defaults to 20 and 0 means unlimited. Max pages (maxPages) is an optional safety stop on the number of result pages fetched per location (350 listings per page) and does not by itself cap your totals; Max listings still decides when a run stops. Leave Max pages at 0 (the default) for uncapped paging.
Detail enrichment and its cost
Turn on Fetch full listing details to add the listing agent, brokerage, a valuation label, nearby schools, structured amenities, public and tax records, and the Redfin Estimate. Each listing enriched this way bills a separate detail-enrichment charge in addition to the per-listing result charge; the Pricing tab shows the current rates. This toggle governs search-mode results, pasted region URLs, and a pasted single listing URL (a link containing /home/<id>), which needs it on (the default) to return anything more than its id and URL. With it off, a pasted listing URL is still billed the per-listing result charge, but the row carries only id, propertyId, a fallback URL and scrapedAt, with no detail fields and no detail-enrichment charge.
Paste a single listing URL
A pasted listing URL fetches that home's detail panels directly; it never re-walks the search page the listing came from. That means the record it returns carries the listing agent, brokerage, full address (under mainHouseInfo), schools, amenities, public records and the Redfin Estimate when available, but it does not carry price, beds, baths, sqft, lotSize, yearBuilt, streetLine/city/state/zip, latitude/longitude, photos, keyFacts, listingTags or listingRemarks - those only come from a search-result card. To get the full field set for one specific property, search by its address or ZIP instead of pasting its listing URL; paste the URL only when you already have the fields above from elsewhere and just need the detail-only data.
Resume and incremental mode
- Resume (
resumeFromRunId) continues one interrupted run: paste its run or dataset ID and the actor skips every listing already collected there, so you don't pay twice. - Incremental mode (
incrementalMode) is for scheduled runs over the same search or URL list. Each listing is classifiedNEW,UPDATED(withchangedFields),UNCHANGED(suppressed and not billed unlessemitUnchangedis on), orEXPIRED(only after a run that completely covered every selected location/URL, and only withemitExpiredon). Counters that tick on their own (days on market, time on Redfin, the scrape timestamp) are ignored when deciding whether a listing changed, so an unchanged listing never looks "updated" just because a day passed. REAPPEAREDis not something that happens "by default": it can only be reported for a listing this actor has already tombstonedEXPIREDin an earlier run (which itself required a prior complete, uncapped, non-resumed scan withemitExpiredon). A listing dropping out of one run and coming back in a later one, without ever having been markedEXPIREDfirst, is reported asNEWorUPDATEDlike any other change, notREAPPEARED.emitExpiredonly fires after a run that resolved every given location/URL, was not truncated by Max listings or Max pages, was not a resumed or checkpoint-continued run, and hit no rejected or failed requests. If any of that is not true, expiry reporting is skipped for that run (with a log line explaining why) and previously tracked listings stay as they were.- Leave
stateKeyempty unless you want to control the baseline yourself: it is otherwise derived from your search settings, so changing a filter starts a separate baseline instead of reporting your whole result set as new.
Send results into your apps (MCP connectors)
Optionally pipe each run's results into the apps you already use through Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.
What gets written to the connector: a condensed, human-readable summary of each listing, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify, Settings, Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
- For Notion, also set
notionParentPageUrlto the page where records should be created.
The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search (location + filters) or url (paste Redfin links). |
locations | array | ["Chicago, IL"] | Search mode only. Cities, ZIPs, neighborhoods or counties, e.g. "Chicago, IL". |
listingType | string | for_sale | for_sale or sold (last 3 years). |
sortBy | string | recommended | recommended, newest, price_low, price_high, sqft, lot_size, or price_per_sqft. |
propertyTypes | array | [] (all types) | Keep only these property types (House, Condo, Townhouse, Multi-Family, Land, Manufactured). |
minPrice | integer | no default (optional) | Only listings priced at or above this amount (search mode). |
maxPrice | integer | no default (optional) | Only listings priced at or below this amount (search mode). |
minBeds | integer | no default (optional) | Only listings with at least this many bedrooms (search mode). |
minBaths | integer | no default (optional) | Only listings with at least this many bathrooms (search mode). |
minSqft | integer | no default (optional) | Only listings with at least this much interior area (search mode). |
urls | array | sample region URL | URL mode only. Redfin region or listing URLs to fetch verbatim; filter fields are ignored. |
fetchDetails | boolean | true | Fetch each listing's detail panels for the agent, brokerage, valuation label, schools, amenities and public records. See "Detail enrichment and its cost" above for how this interacts with pasted listing URLs. |
maxItems | integer | 20 | The only cap on total results. Set 0 for unlimited. |
maxPages | integer | 0 (unlimited) | Optional safety stop on result pages per location (350 listings per page). Does not cap totals; Max listings still decides. |
resumeFromRunId | string | no default (empty) | Optional. ID of a previous run or dataset of this actor; listings already there are skipped. |
incrementalMode | boolean | false | Track this exact search or URL list across scheduled runs and classify every listing NEW / UPDATED / UNCHANGED / REAPPEARED / EXPIRED. |
stateKey | string | no default (auto-derived) | Optional name for the saved baseline. Leave empty and one is derived from your search settings. |
emitUnchanged | boolean | false | Also return (and bill) listings that did not change since the last run. |
emitExpired | boolean | false | Also return (and bill) a row for listings tracked before that are gone this run, once a complete scan proves it. |
proxy | object | Apify Proxy (datacenter) | Connection settings. The default works on every plan. |
maxResidentialMB | integer | 0 (unlimited) | Cap residential traffic in MB; the run auto-downgrades to the lower-cost tier after the cap. |
mcpConnectors | array | no default (empty) | Optional. Pipe results into Notion, Linear, Airtable, or Apify via MCP. |
notionParentPageUrl | string | no default (empty) | Optional. Parent page for a selected Notion connector. |
maxNotifyListings | integer | 50 | Optional. Cap how many listings are pushed to the connectors. |
Output Example
Sample shape: values are illustrative placeholders, not from a live listing.
{"id": 12345678,"propertyId": 12345678,"listingId": 200000000,"url": "https://www.redfin.com/IL/Chicago/123-Example-St-60601/home/12345678","mlsId": "mred00000000","mlsStatus": "Active","status": "Active","price": 575000,"priceType": "List price","pricePerSqFt": 311,"hoaDues": 250,"beds": 3,"baths": 2.5,"bathFull": 2,"bathPartial": 1,"sqft": 1850,"lotSize": 4200,"stories": 2,"yearBuilt": 1998,"streetLine": "123 Example St","city": "Chicago","state": "IL","zip": "60601","latitude": 41.8781,"longitude": -87.6298,"propertyTypeLabel": "Condo/Co-op","daysOnMarket": 12,"photos": "0-24:0","hasVirtualTour": false,"keyFacts": [{ "description": "Large windows", "rank": 0 }],"listingTags": ["Hardwood flooring"],"listingRemarks": "Bright corner unit with lake views and an updated kitchen.","listingAgent": "Alex Example","brokerName": "Example Realty Group","mainHouseInfo": {"fullStreetAddress": "123 Example St, Chicago, IL 60601","url": "https://www.redfin.com/IL/Chicago/123-Example-St-60601/home/12345678"},"schools": [{ "name": "Example Elementary", "rating": 8, "distanceMiles": 0.4 }],"scrapedAt": "2025-01-01T00:00:00+00:00"}
Plan Requirement
The default connection setting works on every plan: runs use the lower-cost datacenter tier by default. Switch to the residential proxy group under Connection only if you see connection errors; the run auto-downgrades back to the lower-cost tier once your residential traffic budget is spent. The Pricing tab shows the current per-listing and detail-enrichment rates.
FAQ
How much does it cost?
You pay per listing returned, plus a separate detail-enrichment charge for any listing that was given full detail treatment, which includes a pasted single-listing URL only when Fetch full listing details is on (the default). The Pricing tab shows the current rates. Use Max listings to cap the cost of any run.
Is it legal to scrape Redfin?
This actor collects only publicly available listing data. You are responsible for how you use it: follow Redfin's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Facts like price, beds and square footage are generally not protected, but photos, remarks and agent/brokerage details may be subject to third-party rights.
Can I get only new or changed listings on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new and updated listings, and unchanged ones are not billed unless you turn on Emit unchanged rows.
Why does a pasted listing URL return fewer fields than a search result?
Because fetching a single listing's detail panels is the only way to identify it directly, a pasted listing URL needs Fetch full listing details on (the default) to return anything beyond its id and URL; with it on, you get the detail-only fields (agent, brokerage, address, schools, amenities, public records, Redfin Estimate) but never the search-card fields (price, beds, baths, sqft, lot size, year built, city/state/zip, coordinates, photos, tags, remarks). Search by the address or ZIP instead if you need the full field set for one property.
Why did my run fail instead of returning an empty dataset?
If every request to Redfin was rejected, the run stops with a clear message so "no listings for this search" is never confused with "nothing could be read". Retry in a few minutes, or switch to a residential proxy group under Connection. If the site answered but genuinely has no matching listings, the run still succeeds and reports "No listings found" without billing anything for it.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.
๐ Want more real estate data?
Pair this actor with these related scrapers from the same team:
| ๐ Crexi Scraper Scrape crexi.com commercial listings: asking price, cap rate, square footage, units, year... | ๐ Realtor.com From $0.9/1K. Extract property listings from realtor.com. Get comprehensive data... |
| ๐งฉ Zillow Scraper Scrape zillow.com properties for sale, for rent and recently sold across the US: price... | ๐ Trulia Scraper Scrape Trulia.com property listings by location, filters, or URL. Extract prices, beds... |
| ๐งฉ Homes.com Scraper Scrape US property records from Homes.com. Pick a city, state or ZIP and a channel (for... | ๐ NewHomeSource Scrape new homes, floor plans, builders and communities from NewHomeSource.com. Search by... |
๐ Browse all abotapi scrapers
๐ฌ Support & custom scrapers
- ๐ Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- ๐ ๏ธ Need another site, extra fields or a private build? Email abotapi@proton.me or message Telegram @abotapi.
- โญ Enjoying it? A quick review on the actor page helps other users find it.