# Redfin Scraper (`lorify/redfin-scraper`) Actor

Scrape Redfin US property listings for sale, sold, or for rent, by city.

- **URL**: https://apify.com/lorify/redfin-scraper.md
- **Developed by:** [Lorenzo Atzeni](https://apify.com/lorify) (community)
- **Categories:** Real estate
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

**Redfin Scraper extracts property listings straight from [Redfin](https://www.redfin.com)**, the US real estate marketplace, for any city in the United States. Pick one of three listing types per run — **homes for sale, homes sold recently, or homes for rent** — and get back clean, structured data: address, price, beds/baths, square footage, coordinates, and more, ready to download or pipe into your own tools.

The scraper talks to Redfin's own listing data directly over HTTP, without opening a browser. Most cities finish in a few seconds; the largest metros at high result counts can take closer to a minute. No proxy is needed to get complete results. Run it on demand from the Apify Console, call it through the [Apify API](https://docs.apify.com/api/v2), schedule it to refresh daily or weekly, or connect it to Zapier, Make, Google Sheets and other apps through [Apify integrations](https://apify.com/integrations).

### Why use Redfin Scraper?

- **Market research and investment analysis.** Track inventory, pricing, and how fast homes move across any US city, or several at once.
- **Sold-price comps.** Pull recent sales from the last 7 to 365 days to estimate what a property in a given neighborhood is really worth.
- **Rental market analysis.** Rent ranges, unit availability, and property details for build-to-rent research, landlord pricing, or market comparisons.
- **A location check most scrapers skip.** Every batch of results is checked against the coordinates Redfin itself reports for the requested city before delivery. If something doesn't genuinely match the place you asked for, you're told why instead of silently receiving — and paying for — the wrong city.

### How to use Redfin Scraper

1. Open the **Input** tab and add one or more US cities under **Locations**, written as `City, ST` (for example `Austin, TX`) — the two-letter state code is required, since many city names exist in more than one state.
2. Choose a **Listing type**: For sale, Sold, or For rent.
3. If you chose Sold, pick **Sold within** — how many days back to look (7, 30, 90, 180, or 365).
4. Set **Maximum results per location** to control how much data (and cost) each city can produce.
5. Click **Start**. Results land in the run's dataset as they're scraped — export them as JSON, CSV, Excel, or connect them to an integration once the run finishes.

If a city name matches more than one place in the same state, the run skips that line and tells you the exact Redfin region IDs to use instead, with nearby towns named for each one so you can tell them apart.

#### Input

| Field | What it does |
|---|---|
| `locations` | One US city per line (`City, ST`), or a Redfin region ID if you already have one. Up to 50 lines per run. |
| `maxResults` | Upper limit of listings returned per location, from 1 to 20,000. Large cities can return several thousand listings. |
| `listingType` | `For sale` (default), `Sold`, or `For rent`. |
| `soldWithin` | Only used when Listing type is Sold: `7`, `30`, `90`, `180`, or `365` days. |

### Output

Each result is one property listing. Example, from the **For sale** channel:

```json
{
    "searchedLocation": "Austin, TX",
    "propertyId": 31227638,
    "mlsId": "2169229665800376521",
    "url": "https://www.redfin.com/TX/Austin/1102-Heritage-Way-78703/home/31227638",
    "address": "1102 Heritage Way",
    "city": "Austin",
    "state": "TX",
    "zipCode": "78703",
    "latitude": 30.2856382,
    "longitude": -97.7715548,
    "price": 3995000,
    "pricePerSqFt": 982,
    "propertyType": "Single Family Residential",
    "beds": 5,
    "baths": 5,
    "sqFt": 4070,
    "yearBuilt": 2024,
    "listingStatus": "Coming Soon",
    "daysOnMarket": 1,
    "descriptionPreview": "This timeless transitional-modern residence by Mosier Luxury Homes is ideally tucked into a quiet cul-de-sac in the heart of Deep Eddy...",
    "highlights": ["FLOOR-TO-CEILING WINDOWS", "COVERED PATIO", "PRIVATE BACKYARD"],
    "photoCount": 70
}
```

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

### Data output fields

Field names differ slightly by listing type, since Redfin returns different data for each. No agent or owner contact details (phone, email) are collected on any channel — only property and listing data.

#### For sale

`searchedLocation`, `propertyId`, `mlsId`, `url`, `address`, `unitNumber`, `city`, `state`, `zipCode`, `latitude`, `longitude`, `price`, `pricePerSqFt`, `hoaFeeMonthly`, `propertyType`, `beds`, `baths`, `fullBaths`, `partialBaths`, `sqFt`, `lotSizeSqFt`, `stories`, `yearBuilt`, `listingStatus`, `daysOnMarket`, `previouslySoldOn`, `descriptionPreview`, `highlights`, `photoCount`, `virtualTourUrl`, `openHouseStart`, `openHouseEnd`

#### Sold

`searchedLocation`, `propertyId`, `mlsId`, `url`, `address`, `city`, `state`, `zipCode`, `latitude`, `longitude`, `price`, `pricePerSqFt`, `hoaFeeMonthly`, `propertyType`, `beds`, `baths`, `sqFt`, `lotSizeSqFt`, `yearBuilt`, `daysOnMarket`, `listingStatus`, `soldOn`, `saleType`, `neighborhood`, `mlsSource`

#### For rent

`searchedLocation`, `propertyId`, `url`, `buildingName`, `address`, `city`, `state`, `zipCode`, `latitude`, `longitude`, `rentMin`, `rentMax`, `bedsMin`, `bedsMax`, `bathsMin`, `bathsMax`, `sqFtMin`, `sqFtMax`, `availableUnits`, `propertyType`, `descriptionPreview`, `lastUpdated`

A field is left empty rather than guessed whenever Redfin doesn't provide it for a given listing — for example, single-family rentals don't have a `buildingName` the way apartment complexes do.

### Pricing

Redfin Scraper uses Apify's [Pay-Per-Event pricing](https://docs.apify.com/platform/actors/publishing/monetize#pay-per-event-pricing-model): **$1.00 for every 1,000 listings extracted**, plus a small flat fee to start each run. There's no charge for a location that returns no results or fails the geographic accuracy check.

Scraping a mid-sized city (around 1,000-2,000 listings) typically costs $1-2. Large metro areas can return several thousand listings for a given search, so use **Maximum results per location** to keep runs within your budget.

### Tips and advanced options

- Keep **Maximum results per location** proportional to what you need. A large city can easily return 5,000+ listings, and cost scales with how many results you actually receive.
- For the **Sold** channel, shorter windows (7-30 days) are best for tracking recent market activity; longer windows (180-365 days) are best for building a larger comps dataset.
- Coverage on the **Sold** and **For rent** channels is very high in testing (98.5%+ of what Redfin itself reports as available) but not guaranteed to be a literal 100% for every city, since Redfin's own listing count occasionally includes a small number of entries its public results don't expose.
- If you already know a place's Redfin region ID (for example from a previous run's warning about an ambiguous city name), you can put the number directly in Locations instead of a city name.

### FAQ, limitations, and support

**Is this legal?** Redfin Scraper only reads publicly available listing data, the same data any visitor to redfin.com can see. It does not access any account, login-protected, or private data.

**Does it work for every US city?** It covers cities in Redfin's own city database, tens of thousands of them across all 51 states/territories represented. A handful of very small or unincorporated places may not have listings on Redfin at all for a given listing type — you'll get a clear message in the run log rather than a silent empty result.

**What if my results look off?** Every result is checked against the coordinates Redfin reports for the city you asked for before delivery. If a location fails that check, nothing is delivered or charged for it, and the run log explains why.

**Found a bug or want a feature?** Use the Issues tab on this Actor's page. Custom scraping solutions for other real estate sites or additional data fields are also available on request.

# Actor input Schema

## `locations` (type: `array`):

One US city per line, written as City, State — for example Austin, TX. The two-letter state code is required: 4,296 city names exist in more than one state (there are 32 different towns called Franklin), so without the state we would have to guess, and a wrong guess means you pay for the wrong city. A few names match two different towns within the same state; when that happens the run tells you which Redfin region ids they are, and you can paste a region id here instead of a name.

## `maxResults` (type: `integer`):

Upper limit of listings returned for each location, so you stay in control of what you spend. Large cities can return several thousand listings each.

## `listingType` (type: `string`):

What kind of listings to scrape: homes currently for sale, homes sold recently, or homes for rent.

## `soldWithin` (type: `string`):

Only used when Listing type is "Sold": how far back to look for sales. Redfin only honors these five values.

## Actor input object example

```json
{
  "locations": [
    "Austin, TX"
  ],
  "maxResults": 1000,
  "listingType": "for-sale",
  "soldWithin": "30"
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "locations": [
        "Austin, TX"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("lorify/redfin-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "locations": ["Austin, TX"] }

# Run the Actor and wait for it to finish
run = client.actor("lorify/redfin-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "locations": [
    "Austin, TX"
  ]
}' |
apify call lorify/redfin-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lorify/redfin-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/OGQp9dJUZv0IrG76o/builds/OlD8cdcm0Of2QaYkG/openapi.json
