How do you scrape Redfin listings via API without getting blocked?
Call ReefAPI's redfin search action with a location and read listings with price, beds, baths, sqft, MLS id, coordinates, days on market and the full agent remarks back as JSON. The trap is the status filter: for_sale is a bucket, not a state, and the per-listing status field is the one that tells you what you actually have.
This guide demonstrates the real Redfin API engine with a captured response from . The example is only published because the engine passed the SEO snapshot gate.
Real-estate investing, market analysis, lead generation and property dashboards.
Call the live endpoint
- 1
Search by location, then read each status
status 'for_sale' includes Coming Soon listings, and they sort first. All twenty of our Austin results were pre-market. Filter on the per-listing status field.
- 2
Keep mls_id as well as property_id
property_id is Redfin's key for listing_detail and similar. mls_id is what matches the same house on another portal.
- 3
Screen on listing_remarks before enriching
The full agent narrative comes back in search on almost every row. Text-filter first, then spend detail calls on the shortlist.
- 4
Get lot size and HOA from the detail call
lot_sqft and hoa_fee_monthly_usd were null on all twenty search rows. They are property-page fields.
- 5
Read the basis line on market_stats
It reports a snapshot of current active inventory, not a historical value index, and the response says so in the basis field.
Copy the request
These snippets use the captured request params for redfin/v1/search.
curl -X POST https://api.reefapi.com/redfin/v1/search \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"location":"Austin, TX","max_results":30}'import requests
r = requests.post(
"https://api.reefapi.com/redfin/v1/search",
headers={"x-api-key": REEF_KEY},
json={
"location": "Austin, TX",
"max_results": 30
},
)
print(r.json()["data"])const res = await fetch("https://api.reefapi.com/redfin/v1/search", {
method: "POST",
headers: {
"x-api-key": process.env.REEF_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
"location": "Austin, TX",
"max_results": 30
}),
});
const { ok, data, meta, error } = await res.json();Ask your MCP-connected assistant: call reefapi.redfin.search with {"location":"Austin, TX","max_results":30}.Captured output from ReefAPI
Captured on UTC. The response below is the committed snapshot, including the API envelope and metadata.
{
"method": "POST",
"url": "https://api.reefapi.com/redfin/v1/search",
"headers": {
"x-api-key": "$REEF_KEY",
"content-type": "application/json"
},
"body": {
"location": "Austin, TX",
"max_results": 30
}
}{
"ok": true,
"meta": {
"api": "redfin",
"endpoint": "search",
"mode": "live",
"latency_ms": 1508.5,
"record_count": 30,
"bytes": 1021029,
"cache_hit": false,
"charged_credits": 2,
"version": "1.3.0"
},
"data": {
"items": [
{
"property_id": "31230811",
"listing_id": "223775800",
"url": "https://www.redfin.com/TX/West-Lake-Hills/609-Laurel-Valley-Rd-78746/home/31230811",
"address_line": "609 Laurel Valley Rd",
"city": "West Lake Hills",
"state_code": "TX",
"postal_code": "78746",
"neighborhood": {
"value": "Stonehedge Estates",
"level": 1
},
"list_price_usd": 2375000,
"beds": 3,
"baths": 2,
"sqft": 2334,
"lot_sqft": 26571,
"year_built": 1965,
"price_per_sqft_usd": 1018,
"hoa_fee_monthly_usd": null,
"property_type": "Single Family Residential",
"property_type_code": 1,
"status": "Active",
"days_on_market": 1,
"mls_id": "5504749",
"latitude": 30.2942284,
"longitude": -97.80899,
"num_photos": 36,
"last_sold_date": "2021-10-18",
"listing_remarks": "Set on a flat 0.61-acre lot in the heart of West Lake Hills, this fully renovated 1965 mid-century modern offers a blend of architectural character and contemporary living. Located within the sought-after Eanes ISD and just minutes from downtown, it offers both convenience and privacy. This 3-bedroom, 2-bath home features a screened, heated porch off the living room for year-round enjoyment. Expansive walls of windows frame views of the mature trees and private landscape. The low-slung roofline and original redwood siding preserve the home’s authentic design. The renovated kitchen features qua",
"sashes": [
{
"sashType": "[trimmed-depth]",
"sashTypeId": "[trimmed-depth]",
"sashTypeName": "[trimmed-depth]",
"sashTypeColor": "[trimmed-depth]",
"isRedfin": "[trimmed-depth]",
"isActiveKeyListing": "[trimmed-depth]",
"openHouseText": "[trimmed-depth]",
"lastSaleDate": "[trimmed-depth]",
"lastSalePrice": "[trimmed-depth]"
}
],
"source": "redfin"
},
{
"property_id": "31752209",
"listing_id": "223332439",
"url": "https://www.redfin.com/TX/Austin/9201-La-Siesta-Bnd-78749/home/31752209",
"address_line": "9201 La Siesta Bnd",
"city": "Austin",
"state_code": "TX",
"postal_code": "78749",
"neighborhood": {
"value": "Austin",
"level": 1
},
"list_price_usd": 575000,
"beds": 4,
"baths": 2,
"sqft": 1960,
"lot_sqft": 6882,
"year_built": 1999,
"price_per_sqft_usd": 293,
"hoa_fee_monthly_usd": 23,
"property_type": "Single Family Residential",
"property_type_code": 1,
"status": "Coming Soon",
"days_on_market": 13,
"mls_id": "120109",
"latitude": 30.2088883,
"longitude": -97.8816541,
"num_photos": null,
"last_sold_date": "2017-04-13",
"listing_remarks": null,
"sashes": [
{
"sashType": "[trimmed-depth]",
"sashTypeId": "[trimmed-depth]",
"sashTypeName": "[trimmed-depth]",
"sashTypeColor": "[trimmed-depth]",
"isRedfin": "[trimmed-depth]",
"isActiveKeyListing": "[trimmed-depth]",
"openHouseText": "[trimmed-depth]",
"lastSaleDate": "[trimmed-depth]",
"lastSalePrice": "[trimmed-depth]"
},
{
"sashType": "[trimmed-depth]",
"sashTypeId": "[trimmed-depth]",
"sashTypeName": "[trimmed-depth]",
"sashTypeColor": "[trimmed-depth]",
"isRedfin": "[trimmed-depth]",
"isActiveKeyListing": "[trimmed-depth]",
"openHouseText": "[trimmed-depth]",
"lastSaleDate": "[trimmed-depth]",
"lastSalePrice": "[trimmed-depth]"
}
],
"source": "redfin"
},
{
"property_id": "31594719",
"listing_id": "223605245",
"url": "https://www.redfin.com/TX/Austin/3440-Ribbon-Reef-Ln-78728/home/31594719",
"address_line": "3440 Ribbon Reef Ln",
"city": "Austin",
"state_code": "TX",
"postal_code": "78728",
"neighborhood": {
"value": "Austin",
"level": 1
},
"list_price_usd": 475000,
"beds": 3,
"baths": 2,
"sqft": 2161,
"lot_sqft": 9757,
"year_built": 1999,
"price_per_sqft_usd": 220,
"hoa_fee_monthly_usd": 18,
"property_type": "Single Family Residential",
"property_type_code": 1,
"status": "Coming Soon",
"days_on_market": 6,
"mls_id": "120468",
"latitude": 30.4538797,
"longitude": -97.6867468,
"num_photos": null,
"last_sold_date": "2021-07-09",
"listing_remarks": null,
"sashes": [
{
"sashType": "[trimmed-depth]",
"sashTypeId": "[trimmed-depth]",
"sashTypeName": "[trimmed-depth]",
"sashTypeColor": "[trimmed-depth]",
"isRedfin": "[trimmed-depth]",
"isActiveKeyListing": "[trimmed-depth]",
"openHouseText": "[trimmed-depth]",
"lastSaleDate": "[trimmed-depth]",
"lastSalePrice": "[trimmed-depth]"
},
{
"sashType": "[trimmed-depth]",
"sashTypeId": "[trimmed-depth]",
"sashTypeName": "[trimmed-depth]",
"sashTypeColor": "[trimmed-depth]",
"isRedfin": "[trimmed-depth]",
"isActiveKeyListing": "[trimmed-depth]",
"openHouseText": "[trimmed-depth]",
"lastSaleDate": "[trimmed-depth]",
"lastSalePrice": "[trimmed-depth]"
}
],
"source": "redfin"
}
],
"count": 30,
"status": "for_sale",
"pages_fetched": 1,
"filters_applied": {},
"region": {
"region_id": 30818,
"region_type": 6,
"name": "Austin, TX",
"resolved_via": "seed"
}
}
}Why this is hard manually
We asked for status 'for_sale' in Austin and every one of the twenty results came back with status 'Coming Soon'. Nothing went wrong - Redfin's for-sale bucket includes pre-market listings, and they sort to the front because they are the newest. But a pipeline that treats 'for_sale' as 'you can buy this today' will produce an inventory count that includes homes nobody can tour yet, and a days-on-market average pulled toward 1.
The per-listing status field is the one that carries the truth: 'Coming Soon', 'Active', and the sold and pending states. Filter on it after the fact, or accept that your for-sale set is a superset.
The second thing to plan for is that Redfin's search cards omit two fields real-estate models usually want. lot_sqft and hoa_fee_monthly_usd were null on all twenty of our results. That is not a temporary gap - those live on the property page.
Why ReefAPI solves it
listing_remarks arrives in full in the search response, on 19 of our 20 results. That is the agent's own marketing copy - hundreds of words describing finishes, layout and recent work - and getting it without a per-property fetch is what makes text-based screening affordable. If you are looking for 'recently renovated' or 'motivated seller' language across a metro, one search call gives you the corpus.
Two identifiers come back and they do different jobs. property_id ('31265523') is Redfin's key and is what listing_detail and similar accept. mls_id ('2180742405609614625') is the multiple-listing-service number, populated on all twenty of our results, and it is the field that joins a Redfin record to the same property on Zillow, Realtor or an MLS feed. Keep both.
The region resolution is returned rather than assumed. Our 'Austin, TX' search came back with region {region_id: 30818, region_type: 6, name: 'Austin, TX', resolved_via: 'seed'}, so you can see exactly which geography answered and reuse the region_id later. filters_applied echoes what was actually applied, which is the fastest way to catch a filter that was ignored.
market_stats labels its own methodology, which is rarer than it should be. Austin returned active_inventory 350, median_list_price_usd 499997.5, median_price_per_sqft_usd 307, median_days_on_market 5.0, a min-max span of 99,900 to 11,499,000, and a basis string that says in plain words: 'derived from current active for-sale inventory; not a historical series'. It is a snapshot of what is on the market right now, not a home-value index, and quoting it as the latter is the mistake it exists to prevent.
neighborhood is an object with a value and a level rather than a bare string, because neighbourhood naming is hierarchical and 'Northwest Hills' at level 1 is not the same kind of thing as a sub-development name. property_type comes as both a label ('Single Family Residential') and a numeric property_type_code, so you can filter on the code and display the label.
Five actions share the engine: search, listing_detail, similar, autocomplete and market_stats. sold_within_days on search is how you build a comparable-sales set without a separate sold endpoint, and similar takes a property_id directly for one-property comps. Search answered in about 1.5 seconds - fast enough to sweep several regions in a single job.
Questions developers ask
Do I need a Redfin account or MLS access?
No. You send a ReefAPI key. There is no Redfin developer programme, and no MLS membership or IDX feed agreement is involved.
Why does a for_sale search return Coming Soon listings?
Because Redfin's for-sale bucket includes pre-market listings and they sort to the front as the newest. All twenty of our Austin results were 'Coming Soon'. Read the per-listing status field and filter after the fact.
Why are lot_sqft and hoa_fee_monthly_usd always null?
They are not on Redfin's search cards - both were null on all twenty of our results. Call listing_detail on the property_id for them.
How do I match a Redfin listing to the same home on Zillow?
Use mls_id. It was populated on all twenty of our results and is the multiple-listing-service number that portals share. property_id is Redfin-internal and does not travel.
Is market_stats a home-value index?
No, and the response says so. The basis field reads 'derived from current active for-sale inventory; not a historical series'. Austin returned active_inventory 350, median list 499,997.5 and median days-on-market 5.0 - a snapshot of what is listed now.
How do I build a comparable-sales set?
Two ways: search with sold_within_days for an area-wide set, or similar with a property_id for comps around one house.
Do I get the agent's description without a second call?
Yes. listing_remarks came back in the search response on 19 of 20 rows, in full. It is the single most useful field for screening a metro by language rather than by numbers.