Skip to content
ListingrailGet an API key

How to get Redfin listings in Python

By the end of this guide you have a CSV of Miami homes for sale under $600,000, with the listing agent, from one script you can run again tomorrow. Everything below was run on 15 October 2026; the output table is what it returned.

Why scraping Redfin yourself breaks

  • Redfin has no public or partner API for listings. Its only official data product is the Data Center: free downloads of aggregate market figures, not individual homes.
  • The website loads its results from internal endpoints (/stingray) that are undocumented and change without notice.
  • Those endpoints prefix every answer with {}&& so it cannot be read as plain JSON, and each market has its own region id that has to be looked up first.

None of that is impossible, but each point is code you then maintain. The rest of this guide uses Listingrail, which does the reading and hands back clean JSON. The Redfin API page has the official options with sources.

1. Get a key

One request with your email returns a key with 100 free listings. It is shown once, so keep it in an environment variable.

curl -X POST https://listingrail.com/v1/signup \
  -H "content-type: application/json" \
  -d '{"email": "you@example.com"}'

export LISTINGRAIL_KEY=re_...

2. Search and save to CSV

Install requests (pip install requests), then run:

import csv
import os

import requests

r = requests.post(
    "https://listingrail.com/v1/listings/search",
    headers={"Authorization": f"Bearer {os.environ['LISTINGRAIL_KEY']}"},
    json={"source":"redfin","location":"Miami, FL","maxPrice":600000,"limit":50},
    timeout=300,
)
r.raise_for_status()
listings = r.json()["listings"]

fields = ["price", "currency", "beds", "baths", "area", "address", "url"]
with open("redfin-miami-fl.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    writer.writerow(fields)
    for home in listings:
        writer.writerow([home[k] for k in fields])

print(len(listings), "listings saved to redfin-miami-fl.csv")

The request body, on its own:

{
  "source": "redfin",
  "location": "Miami, FL",
  "maxPrice": 600000,
  "limit": 50
}

Each listing returned costs one credit. A search that finds nothing, or fails at Redfin, costs nothing. A request can take up to a minute or two, because Redfin is read at that moment.

3. What comes back

The first three rows of the run on 15 October 2026:

AddressPriceSizeAgent
15420 SW 85th Ln #162, Miami, FL 33193315,000 USD2 bd · 2 ba · 948 sq ftJeffrey Izquierdo
45 SW 9th St #1005, Miami, FL 33130525,000 USD1 bd · 2 ba · 852 sq ftCecilia Cordova
1100 S Miami Ave #1609, Miami, FL 33130465,000 USD1 bd · 1 ba · 769 sq ftNadia Guro

Every listing has the same keys on all 17 portals, so the code for Redfin reads the others too. Fields Redfin does not show come back as null, and the portal's own record sits in raw. With pandas:

import pandas as pd

df = pd.DataFrame(listings)
df["agent"] = df["agent"].str.get("company")
print(df[["price", "beds", "baths", "area", "address", "agent"]].head())

4. Get new listings and price cuts every day

Running the script on a schedule works, but then you compare the files yourself. A monitor stores the search, checks it once a day, and sends only what changed: new listings and price cuts. The free key holds one monitor.

requests.post(
    "https://listingrail.com/v1/monitors",
    headers={"Authorization": f"Bearer {os.environ['LISTINGRAIL_KEY']}"},
    json={
        "source": "redfin",
        "location": "Miami, FL",
        "filters": {"maxPrice":600000},
        "webhook_url": "https://example.com/new-listings",
    },
    timeout=30,
)

Changes can also be read with GET /v1/monitors/{id}/changes or downloaded as CSV. Plans and limits are on the monitors page.

Redfin quirks worth knowing

  • "redfin" is homes for sale; "redfin-rentals" is rentals with the same location format.
  • minPrice, maxPrice and minBeds are applied by Redfin, so you only pay for matching homes.
  • agent.name is the listing agent. agent.phone is filled only when Redfin names the listing broker; otherwise it stays null rather than showing a number that is not the agent's.
  • area is in square feet; property_type uses Redfin's labels (condo, single family and so on).

Questions

Does Redfin have an API?

Not for listings. Redfin publishes aggregate market data in its Data Center; individual listings are only on the website.

Can I get Redfin rentals?

Yes, with "source": "redfin-rentals" and a city and state.

Why is agent.phone empty on some Redfin homes?

Redfin does not always name the listing broker. Without it the phone shown is not the agent's own, so the API returns null.

Get 100 free listingsAPI docsOther guides