Get Redfin sold prices and a full MLS price history per address
The Redfin API returns US real-estate data — for-sale, recently-sold and rental listings — as clean JSON.
5 active endpoints, on 1, 2 and 3 credit tiers.
- POST/redfin/v1/search
- POST/redfin/v1/listing_detail
- POST/redfin/v1/similar
- POST/redfin/v1/autocomplete
- POST/redfin/v1/market_stats
What Redfin endpoints does ReefAPI ship?
5 live read endpoints. Read-only data API: no writes, no account actions, no dashboard access on the target site.
Redfin API
3 of 5 endpoints, ready to run
The listing grid, and the only place the sold price lives. Set status to sold and every row carries what it went for and when.
{ "ok": true, "meta": { "api": "redfin", "endpoint": "search", "mode": "live", "latency_ms": 882.2, "record_count": 14, "cache_hit": false }, "data": { "items": [ { "property_id": "56784078", "url": "https://www.redfin.com/TX/Austin/2309-Pruett-St-78703/unit-C/home/56784078", "address_line": "2309 Pruett St Unit C", "city": "Austin", "state_code": "TX", "postal_code": "78703", "price_usd": 350000, "beds": 2, "baths": 1, "sqft": 684, "lot_sqft": 1707, "year_built": 1956, "days_on_market": null, "price_per_sqft_usd": 512, "hoa_fee_monthly_usd": 240, "property_type": "Condo/Co-op", "status": "Sold", "sold_date": "August-21-2026", "mls_id": "1262656", "latitude": 30.2812268, "longitude": -97.7719645, "source": "redfin", "is_sold": true }, { "property_id": "145453615", "url": "https://www.redfin.com/TX/Austin/1900-Barton-Springs-Rd-78704/unit-5015/home/145453615", "address_line": "1900 Barton Springs Rd #5015", "city": "Austin", "state_code": "TX", "postal_code": "78704", "price_usd": 325000, "beds": 0, "baths": 1, "sqft": 696, "lot_sqft": 309, "year_built": 2013, "days_on_market": null, "price_per_sqft_usd": 467, "hoa_fee_monthly_usd": 340, "property_type": "Condo/Co-op", "status": "Sold", "sold_date": "August-21-2026", "mls_id": "9844565", "latitude": 30.2648342, "longitude": -97.7636944, "source": "redfin", "is_sold": true }, { "property_id": "31419001", "url": "https://www.redfin.com/TX/Austin/5326-Wellington-Dr-78723/home/31419001", "address_line": "5326 Wellington Dr", "city": "Austin", "state_code": "TX", "postal_code": "78723", "price_usd": 350000, "beds": 3, "baths": 2, "sqft": 1495, "lot_sqft": 9644, "year_built": 1961, "days_on_market": null, "price_per_sqft_usd": 234, "hoa_fee_monthly_usd": null, "property_type": "Single Family Residential", "status": "Sold", "sold_date": "August-19-2026", "mls_id": "3051813", "latitude": 30.3034214, "longitude": -97.6857528, "source": "redfin", "is_sold": true } ], "count": 14, "status": "sold", "sold_within_days": 30, "filters_applied": {}, "region": { "region_id": 30818, "region_type": 6, "name": "Austin, TX", "resolved_via": "seed" }, "note": null } }
How the Redfin API works
Redfin is a normal ReefAPI surface — the same four rules that hold for every other engine on the key.
No OAuth app, no request signing, no per-site account. One key covers all 184 engines.
Every route is a POST with a JSON body. Parameters are validated against the published schema before anything is charged.
Credits, not seats. Failed and blocked calls are never charged, and cache hits cost nothing.
One envelope everywhere. meta carries latency_ms, record_count and the endpoint that answered.
Build a comp set with prices, not just addresses
Take the sold grid for the price and the date, then open the ones that matter for the event history behind them. The order matters, because the two endpoints answer different questions.
{"location": "Austin, TX", "status": "sold", "sold_within_days": 30, "max_results": 100}2 flat credits. price_usd, sold_date, price_per_sqft_usd, beds, baths, sqft, year_built and the MLS id — filled on every row in our Austin run.
{"property_id": "…"}3 credits. price_history is one row per event — Listed, Price Changed, Pending, Contingent, Sold — with the MLS that reported it. One address gave us 20 events; another 13, going back to 2012.
Two calls, five credits, and you have both the number and the story behind it. Keep the status and the current price from step one — step two is an archive, not a live listing.
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}'{
"ok": true,
"data": { … },
"meta": {
"api": "redfin",
"endpoint": "search",
"mode": "live",
"latency_ms": …,
"record_count": …
},
"error": null
}The three Redfin search statuses return three different row shapes
status is not just a filter, it changes the schema. A parser written against for_sale rows finds nothing where it expects a price on sold rows, and hits objects where it expects integers on rental rows. Measured 2026-08-27 on Austin, TX, region_id 30818. Code against the column that matches the status you pass.
| Field | status=for_sale | status=sold | status=for_rent |
|---|---|---|---|
| Price | list_price_usd, integer, e.g. 2100000 | price_usd, integer, e.g. 350000, plus sold_date "August-21-2026" | rent_price, an object {min: 999, max: 1200}, or null when nothing is available |
| beds, baths, sqft | Plain numbers: 4, 4, 4729 | Plain numbers: 2, 1, 684 | Objects: beds {min: 1, max: 3}, sqft {min: 630, max: 860} |
| Identifiers | property_id plus listing_id | property_id only | property_id plus rental_id, a UUID such as f98a8bcf-3b88-4f07-866d-3a34e2fbde61 |
| mls_id | A real MLS number on ordinary listings, a 19-digit internal id on broker-exclusive ones | Real MLS numbers: 1262656, 9844565, 3051813 | Not returned |
| status | Strings such as "Coming Soon" and "Active", not the value you passed | "Sold", alongside is_sold true | Not returned |
| days_on_market | Integer, 1 on a brand-new listing | null on every sold row measured | Not returned; last_updated carries an ISO timestamp instead |
| Extras | neighborhood object, listing_remarks, sashes[], num_photos, price_per_sqft_usd | price_per_sqft_usd, hoa_fee_monthly_usd, lot_sqft | property_name such as "Oaks on Lamar", and num_available_units |
address_line is normally a string but arrives as {"level": 5} when the address is withheld, and neighborhood is always an object, either {"value": "Northwest Hills", "level": 1} or {"level": 5}. Type-check both before formatting. lot_sqft is square feet, so 43,560 is one acre.
Where the sold price is, where the history is, and why they are different endpoints
Measured on 2026-08-28 across Austin TX and Seattle WA, with four properties opened individually. Three of these lines go against us, and the first is the one that will bite you if nobody says it.
Against us, confirmed on four properties in a row. Search said Coming Soon at 1,250,000, Coming Soon at 699,000, Active at 529,000 and Active at 385,000. listing_detail on the same four ids answered Sold, Sold, Sold and Off Market, with list prices of 452,000, 104,900, 512,500 and null. It resolves the property's MLS and public-record history, and the top of that history is the last completed transaction rather than today's listing. Read status, price and days_on_market from search; read price_history, tax and schools from listing_detail. Never read the current state from detail.
Against us. property_id and listing_id came back null on all four detail responses, so there is no field joining a detail record to the search row it came from. Keep your own mapping, or key on url, which is present on both.
This is the thing this engine has. status=sold with sold_within_days 30 returned 14 Austin rows with price_usd, sold_date, price_per_sqft_usd, hoa_fee_monthly_usd, lot_sqft and year_built all filled. A real transaction price per address, which the neighbouring US portal does not return at all.
Against us. The call that gave 14 rows in Austin returned zero in Seattle at 30 days. Widening to 365 gave 12 Seattle rows — price_usd on all 12, sold_date null on all 12, with and without sort=sold_date. Check both fields per market before you promise a customer a sold feed; do not assume Austin's behaviour is national.
price_history is one entry per event with date, event, mls_status and the reporting MLS: Listed 388,500, Price Changed 379,500, Price Changed 374,500, Pending, Contingent, Sold. The Sold and Sold (Public Records) rows carry price_usd null — every one of them, on every property we opened. So the archive tells you what happened and when, and the sold grid tells you for how much. You need both.
Against us, and the kind of thing that survives testing and dies in production. last_sold_date on a search row is ISO — 2015-03-25. sold_date on a sold row is August-21-2026. price_history dates are ISO again. Normalize on the way in.
On the for-sale grid, lot_sqft and hoa_fee_monthly_usd were null on 25 of 25 rows. On the sold grid for the same city, lot_sqft was filled on 14 of 14 and the HOA fee on 11 of 14. redfin_estimate_usd was null on all four detail responses. Sample the status you intend to ship before you decide a field exists.
Active inventory, median list price, median price per sqft, median days on market — and a basis string in the payload reading that these are derived from current active for-sale inventory and are not a historical index series. Worth reading: the same response reported a maximum list price of 698,000,000 for Austin, which is a mis-keyed listing rather than a market fact. Medians are safe here; extremes are not.
200 unique rows came back in well under a second with no cursor to manage — set max_results and the engine handles the paging. autocomplete resolves a place name to Redfin's own region ids and neighborhood urls. search, similar and market_stats are 2 flat credits, listing_detail 3, autocomplete 1. No per-row billing anywhere.
What people build with Redfin
The jobs this data is most often used for.
endpoints
credits per call
Real-estate investors call search then similar to find and compare properties in a target area.
Market dashboards use market_stats to track median price, inventory and days-on-market trends.
Lead-gen tools use listing_detail to enrich a property with price history and listing specifics.
What Redfin data costs
The cheapest call here is 1 credit, so $15/mo (Pro) buys 10,000 of them — $1.50 per 1,000 credits. Credits roll over and never expire, and failed or blocked calls are not charged.
Full pricing →- 1,000 free credits on signup, no card
- One key, all 184 APIs, one credit pool
- Failed and blocked calls are never charged
- Credits roll over and never expire
Call it in two lines
Sign up, get 1,000 credits and one key that works on every engine. Then this is the whole protocol.
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"])Have a question? We got answers.
The questions people actually ask before wiring up Redfin.
Get a free key →Is mls_id the actual MLS number?▾
Usually, but not always, and you can tell which at a glance. Recently sold Austin homes returned 1262656, 9844565 and 3051813, which are genuine seven-digit ACTRIS numbers. A broker-exclusive Coming Soon listing returned mls_id "2180742405609614625", a 19-digit Redfin internal id, and you can confirm which one you are holding because that same number prefixes every photo filename on the record. If the value is much longer than ten digits, the MLS number has not been published yet.
Is the Redfin Estimate available, and when is it null?▾
redfin_estimate_usd comes from listing_detail and it is a float. Two recently sold Austin properties returned 409,923.4 and 456,880.4. A Coming Soon listing that had not yet gone active returned null, as did its mortgage field. Expect an estimate on off-market and sold homes, and expect null on listings Redfin has not finished ingesting. There is no estimate field on search rows at all.
Why does listing_detail say "Off Market" with a null price for a listing I can see is live?▾
Because property_id alone fetches the property record, not the active listing. Calling listing_detail with property_id 31265523 returned status "Off Market", list_price_usd null, and 17 years of tax history. Adding the listing_id from the same search row returned status "Coming Soon" and list_price_usd 2,100,000, but price_history came back empty and the whole tax block came back null. The two modes are complementary: call once without listing_id for history and taxes, once with it for the live price.
Where is the actual sale price of a sold home?▾
Not in price_history, which is the intuitive place to look. On property 31419001 the price_history row for the sale itself read date "2026-08-19", event "Sold (MLS)", mls_status "Closed", price_usd null, and only the "Listed" row carried a number. The sale price is on the search row when you pass status=sold, where that property returned price_usd 350000. Note also that listing_detail returned list_price_usd 290000 for the same property, matching neither, so do not read that field as a sale price.
What is in price_history and tax_history?▾
price_history is one row per event with date, event, mls_status, source and a price that is often null. Observed event values are "Listed", "Pending", "Contingent", "Sold (MLS)" and "Sold (Public Records)"; mls_status values are "Active", "Active Under Contract", "Pending" and "Closed"; source is the originating MLS name, such as "Unlock MLS", or "Public Records". tax_history sits nested under tax rather than at the top level, and one Austin property returned 17 annual rows with taxes_due_usd, land_value_usd and improvement_value_usd, running from 31,964.09 in 2026 back through 33,413.55 in 2025.
How is this different from the zillow engine?▾
Different data lineage, and market_stats says so in its own response. The market block carries a basis field reading "derived from current active for-sale inventory (Redfin gis); not a historical ZHVI series", meaning median_list_price_usd is the median of what is listed right now rather than an index. Austin on 2026-08-27 returned active_inventory 350, median_list_price_usd 499,997.5, median_price_per_sqft_usd 307 and median_days_on_market 5.0. Redfin also carries things a Zillow record does not, notably MLS-sourced price history with mls_status, GreatSchools ratings with distance_miles, and a per-property First Street climate block.
What does the similar action return?▾
Comparable properties near a subject, but with a thinner schema than search. Property 31419001 returned 18 comps carrying property_id, listing_id, address_line, list_price_usd, beds, baths, sqft, price_per_sqft_usd, mls_id, listing_remarks and last_sold_date. latitude, longitude, status, property_type, year_built and num_photos were null on every row. Use it to establish a price band, then call listing_detail on the comps you care about.
Which property_types codes can I filter on?▾
Eight integer codes, passed as an array: 1 Single Family Residential, 2 Condo/Co-op, 3 Townhouse, 4 Multi-Family 2-4 Unit, 5 Vacant Land, 6 Other, 7 Manufactured, 8 Multi-Family 5+ Unit. They apply to for-sale and rental searches, and the response echoes them back in property_type_code alongside the human property_type string. An invalid code is rejected outright, unlike the size and year filters, which are silently dropped.
What is the Redfin API?▾
Redfin API is a ReefAPI endpoint group for us homes for sale, sold and rentals with history. It returns live JSON through POST requests under /redfin/v1.
Is the Redfin API free to try?▾
Yes. ReefAPI starts with 1,000 free credits, no card required. Redfin calls use the same shared credit balance as every other ReefAPI engine.
Do I need a Redfin login or account?▾
No login to Redfin is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.
How fresh is the Redfin data?▾
The page example is captured from a live search call, and production requests fetch live data through ReefAPI rather than a static sample.
How many credits does the Redfin API use?▾
Redfin actions currently cost 1-3 credits per successful call. Failed or blocked calls are free, and all APIs draw from one credit pool.
Can I call Redfin from an AI assistant or MCP client?▾
Yes. Connect ReefAPI once through MCP and your assistant can call redfin actions with the same key, credit pool and JSON envelope used by normal REST requests.
11 Real Estate APIs on the same key
One key, one credit pool, one response envelope. If you are pulling Redfin, you are one call away from the rest of the category — no second contract, no second integration.
Need something this API does not do?
Name the endpoint, the field, or a source we do not carry yet. We ship new APIs every week and you would be first to get the key. Real people read every message and reply the same day.
Try it on your own data before you pay anything
The call above is the real endpoint, not a recording. A free key gives you 1,000 credits, the other 183 APIs, and the same envelope everywhere.
Endpoints, parameters and credit costs on this page are read from the live catalog and cannot drift from what the API accepts. Field notes were captured on 2026-08-28.