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

Scrapes Redfin property listings from any search link (for sale, sold or rent, US and Canada) or single home links: price, beds, baths, size, lot, year built, HOA, days on market, MLS id, coordinates and photo.

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

## Pricing

$1.00 / 1,000 homes

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### What does Redfin Scraper do?

Redfin Scraper turns **any [Redfin](https://www.redfin.com) search link into a clean table of homes**: homes **for sale** in the **US and Canada** ([redfin.ca](https://www.redfin.ca)), and **sold homes** and **rentals** in the US. Paste the link from your browser's address bar and **every filter you set on Redfin is kept**: price, beds, baths, home type, size, lot, year built, HOA, days on market, sold within, sort order, the map area you zoomed to and more. Redfin's ready-made pages such as *Condos*, *Houses for rent* or *Homes for sale under $700k* work too. You can also paste **single home links** to get one row per property.

Each home comes back with its address, price, status, sold date and sold price, beds, baths, square feet, lot size, year built, price per square foot, HOA dues, days on market, property type, MLS number, coordinates and main photo.

Running it on Apify gives you API access, scheduling, integrations (Google Sheets, Zapier, Make, webhooks), run monitoring and exports to JSON, CSV or Excel.

### Why use Redfin Scraper?

- **Market research and comps**: pull every sold home in a ZIP code over the last 6 months, with sold price, date and price per square foot.
- **Lead lists for agents and investors**: track new listings that match your exact Redfin filters on a daily schedule.
- **Rental analysis**: collect rent ranges, unit sizes and available units for every apartment building in a city.
- **Price monitoring**: re-run a saved search and compare prices, statuses (pending, sold) and days on market over time.
- **No filter mapping to learn**: if you can build the search on Redfin, the Actor can scrape it.

### How to scrape Redfin listings

1. Open [redfin.com](https://www.redfin.com) (or [redfin.ca](https://www.redfin.ca)), search for a city, ZIP code, neighborhood or county, and set the filters you want. For sold homes pick **Sold** in the filters; for rentals switch to **For rent**. Moving or zooming the map limits the search to that map area.
2. Copy the link from your browser's address bar.
3. Paste it into **Redfin search links** on the Input tab. Add as many links as you like, one per line.
4. Optionally add single home links to **Single home links**, and set **Max homes per search**.
5. Click **Start**. Homes appear in the Output tab within seconds; download them as JSON, CSV, Excel or HTML.

### Input

| Field | Type | Default | What it does |
|---|---|---|---|
| `search_urls` | array of links | `[]` | Redfin search links (city, ZIP, neighborhood, county; for sale in the US or Canada, sold or rentals in the US), including Redfin's topic pages such as `…/condos` or `…/houses-for-rent`. Filters and the map area in the link are kept. |
| `property_urls` | array of links | `[]` | Single home links (`…/home/<id>`) or rental building links (`…/apartment/<id>`). One row each. |
| `max_results_per_search` | integer | `200` | Stops after this many homes per search link (1–10,000). |

Links can be pasted without `https://` (for example `redfin.com/zipcode/98103`), and API callers can send `{"url": "…"}` objects instead of plain strings.

```json
{
  "search_urls": [
    "https://www.redfin.com/city/16163/WA/Seattle/filter/property-type=house+condo+townhouse,max-price=1.5M",
    "redfin.com/zipcode/98103/filter/include=sold-6mo",
    {"url": "https://www.redfin.com/city/16163/WA/Seattle/rentals/filter/min-beds=2"},
    "https://www.redfin.com/city/16163/WA/Seattle/condos",
    "https://www.redfin.ca/on/toronto/filter/property-type=condo"
  ],
  "property_urls": [
    "https://www.redfin.com/WA/Seattle/9750-Greenwood-Ave-N-98103/unit-203/home/7560"
  ],
  "max_results_per_search": 200
}
```

### Output

One row per home. Examples from a real run (a home for sale, a sold home and a rental building):

```json
[
  {
    "id": 1787,
    "listing_id": 223960225,
    "mls_id": "2586313",
    "url": "https://www.redfin.com/WA/Seattle/1331-Harbor-Ave-SW-98116/unit-103/home/1787",
    "status": "for_sale",
    "mls_status": "Active",
    "price": 1199000,
    "currency": "USD",
    "sold_date": null,
    "street": "1331 Harbor Ave SW #103",
    "city": "Seattle",
    "state": "WA",
    "zip": "98116",
    "country": "US",
    "neighborhood": "West Seattle",
    "beds": 3,
    "baths": 2,
    "square_feet": 1591,
    "lot_size_sqft": null,
    "year_built": 2000,
    "price_per_sqft": 754,
    "hoa_monthly": 969,
    "days_on_market": null,
    "property_type": "Condo",
    "latitude": 47.591069,
    "longitude": -122.3826189,
    "photo": "https://ssl.cdn-redfin.com/photo/1/bigphoto/313/2586313_0.jpg",
    "search_url": "https://www.redfin.com/city/16163/WA/Seattle/filter/min-beds=3,max-price=2M",
    "position": 2,
    "scraped_at": "2026-10-10T14:10:44.667107+00:00"
  },
  {
    "id": 3019,
    "mls_id": "2531780",
    "url": "https://www.redfin.com/WA/Seattle/5901-Phinney-Ave-N-98103/unit-302/home/3019",
    "status": "sold",
    "mls_status": "Closed",
    "price": 390000,
    "currency": "USD",
    "sold_date": "2026-07-08",
    "street": "5901 Phinney Ave N #302",
    "city": "Seattle",
    "state": "WA",
    "zip": "98103",
    "beds": 1,
    "baths": 1,
    "square_feet": 665,
    "year_built": 1985,
    "price_per_sqft": 586,
    "hoa_monthly": 661,
    "property_type": "Condo",
    "search_url": "redfin.com/zipcode/98103/filter/include=sold-6mo",
    "position": 1
  },
  {
    "id": 196600669,
    "url": "https://www.redfin.com/WA/Seattle/4001-S-Willow-St-98118/home/196600669",
    "status": "for_rent",
    "price": 1223,
    "price_max": 2535,
    "currency": "USD",
    "street": "4001 S Willow St",
    "city": "Seattle",
    "state": "WA",
    "zip": "98118",
    "property_name": "Trace",
    "beds": 0,
    "beds_max": 2,
    "baths": 1,
    "baths_max": 2,
    "square_feet": 255,
    "square_feet_max": 634,
    "units_available": 185,
    "property_type": "Apartment",
    "photo": "https://ssl.cdn-redfin.com/photo/rent/f31f7a74-ef4d-4d0c-ada4-99e8b9a1f1db/bigphoto/0_1.jpg",
    "search_url": "https://www.redfin.com/city/16163/WA/Seattle/apartments-for-rent",
    "position": 1
  }
]
```

(The second and third rows are shortened here.) You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

### Data fields

| Field | Type | Description |
|---|---|---|
| `id` | number | Redfin property id (the number at the end of the home link). |
| `listing_id` | number | Redfin listing id (homes for sale and sold). |
| `mls_id` | text | MLS number of the listing. |
| `url` | link | The home's page on Redfin. |
| `status` | text | `for_sale`, `coming_soon`, `contingent`, `pending`, `sold`, `for_rent`, or `off_market` (single home links only). |
| `mls_status` | text | Status as the MLS words it, e.g. `Active`, `Active Under Contract`, `Pending`, `Closed`. |
| `price` | number | Asking price; the sold price for sold homes; the lowest monthly rent for rentals. |
| `currency` | text | `USD` or `CAD`. |
| `sold_date` | date | Date of sale (YYYY-MM-DD, local date), sold homes only. |
| `street`, `city`, `state`, `zip`, `country` | text | Address. `state` is the province and `zip` the postal code in Canada. |
| `neighborhood` | text | Redfin's neighborhood name. |
| `beds`, `baths` | number | Bedrooms and bathrooms (lowest unit for rentals). |
| `square_feet` | number | Living area in square feet. |
| `lot_size_sqft` | number | Lot size in square feet. |
| `year_built` | number | Year built. |
| `price_per_sqft` | number | Price per square foot. |
| `hoa_monthly` | number | HOA dues per month. |
| `days_on_market` | number | Days on market, where Redfin shows it to visitors. |
| `property_type` | text | House, Condo, Townhouse, Multi-family, Land, Manufactured, Co-op, Apartment or Other. |
| `latitude`, `longitude` | number | Coordinates. |
| `photo` | link | Main listing photo, full size. |
| `price_max`, `beds_max`, `baths_max`, `square_feet_max` | number | Rentals only: top of the range across available units. |
| `units_available`, `property_name` | number, text | Rentals only: units on offer and the building's name. |
| `search_url` | text | The link (as you gave it) that produced this row. |
| `position` | number | Order in Redfin's results for that search: the same order the site lists them in, for up to 350 homes under the default sort (above 350, Redfin's larger answer comes in a different order). 1 for single home links. |
| `scraped_at` | date | When the row was saved (UTC). |

Fields Redfin does not show for a home are `null`. Days on market, square feet and year built are hidden by some MLSs for visitors who are not signed in (for example days on market in the Seattle area, square feet in Ontario), so they stay empty there. **Sold homes in Canada** are the biggest case: Redfin shows their sold price, sale date and photo only to signed-in visitors, everywhere in Canada (its own CSV download leaves them blank too). Such rows are not saved or billed: a redfin.ca sold search, or a single Canadian home link that turns out to be sold, is listed in `FAILED_INPUTS` with the reason "Redfin doesn't show sold prices in Canada to visitors who aren't signed in". Any Canadian sold home that does carry a price is kept.

### How much does it cost to scrape Redfin?

The Actor is billed per home saved; see the **Pricing** tab for the exact price. Nothing is charged for links that give no homes. It reads Redfin's own data feed over plain HTTP, without a browser or paid proxies in normal operation, so runs are fast: in our tests a 25-home search finished in about 4 seconds, 1,600 homes from 13 links in about 6 seconds, and a 10,000-home search in about 30 seconds.

### Tips

- **Build the search on Redfin first.** Whatever you can filter on the site is applied here, including the sort order (for example `sort=lo-price`).
- **More than 10,000 homes?** Redfin returns at most 10,000 homes for one search. Split a large area into price bands (e.g. one link with `max-price=500k`, another with `min-price=500k`) or into ZIP codes.
- **Sold homes (US):** use Redfin's Sold filter (`include=sold-3mo`, `sold-1yr`, up to `sold-5yr`).
- **Monitoring:** schedule the same links daily and compare `status`, `price` and `days_on_market`.
- A home that appears in several of your searches is saved once per run (the first link that found it gets the row).

### FAQ, disclaimers and support

**Is it legal to scrape Redfin?** The Actor reads publicly visible listing data, the same as any visitor to redfin.com sees without signing in. It does not log in or bypass access controls. You are responsible for how you use the data; check Redfin's terms of use and your local laws, and consult a lawyer if unsure.

**Personal data.** Listings can name listing agents and brokers; this Actor does not collect agent names, phone numbers or emails. If you combine the output with other data, make sure you have a lawful basis under GDPR, CCPA or similar laws.

**Which links work?** City, ZIP code, neighborhood and county searches on redfin.com, Canadian city searches for homes for sale on redfin.ca (such as `redfin.ca/on/toronto`), and single home or rental building links. Redfin's topic pages after a place (`…/condos`, `…/townhouses`, `…/land`, `…/houses-for-rent`, `…/homes-for-sale-under-700000`, `…/coming-soon`, `…/new-listings`, `…/waterfront` and the others Redfin links to) are read by Redfin itself, so they give the same homes as the page. A topic page with filters added (such as `…/condos/filter/include=sold-1yr`) keeps both: the topic's own settings (home type, price, beds, sort…) are added to your filters, and where your filters set the same thing differently, your filters win. A link with a map area (`viewport=` in the filter part, added when you move or zoom the map) gives only the homes in that area. State pages, agent pages (`…/real-estate/agents`), market pages and blog pages are not searches, and a topic page Redfin does not offer for that kind of place (some exist only for cities) is not read as the plain place; they are listed in the `FAILED_INPUTS` record of the run's key-value store with the reason.

**Rentals or sold homes in Canada?** No. Redfin's rentals search covers the US only, so redfin.ca rental links are listed in `FAILED_INPUTS` instead of being run. Redfin hides Canadian sold prices from visitors who are not signed in, so redfin.ca sold searches give no billed rows either (see the note under the data fields). Homes for sale work on redfin.ca.

**Why did a link give nothing?** Every link that gave no homes is listed in `FAILED_INPUTS` with the reason (for example "no homes match this search on Redfin right now", or a place Redfin does not know). The run still succeeds when the answer is simply empty; it fails only when every link was refused or could not be loaded.

**My filters were ignored.** Redfin reads the filter part of the link itself, and one filter name it does not know (for example a hand-typed `max-hoa=500` instead of Redfin's `hoa=500`) makes it drop all of them, on the website too. Such a link is not scraped, since it would list every home in the area: it is listed in `FAILED_INPUTS` with the filters Redfin ignored. Set them on Redfin and copy the address bar again.

**Single home links for homes not on the market** return the public record (address, beds, baths, square feet, type and location) with `status` set to `off_market`.

**Found a bug or need a custom field?** Open an issue on the **Issues** tab and we will look into it. Custom real estate scrapers are available on request.

# Actor input Schema

## `search_urls` (type: `array`):

Search links copied from the address bar on redfin.com or redfin.ca, one per line: a city, ZIP code, neighborhood or county search, for sale, sold (include=sold-…, US only) or rentals (…/rentals, US only), or one of Redfin's topic pages such as …/condos or …/houses-for-rent. Every filter in the link is kept: price, beds, baths, home type, size, lot, year built, HOA, days on market, sold within, sort order and the map area. Canadian for-sale searches such as https://www.redfin.ca/on/toronto work too; Redfin hides Canadian sold prices from visitors who aren't signed in, so redfin.ca sold searches give nothing.

## `property_urls` (type: `array`):

Links to single homes or rental buildings, one per line, such as https://www.redfin.com/WA/Seattle/9750-Greenwood-Ave-N-98103/unit-203/home/7560. Each gives one row: the current listing, the latest sale (last 5 years), the rental listing, or the public record when the home is off the market.

## `max_results_per_search` (type: `integer`):

Stops after this many homes for each search link. Redfin returns at most 10,000 homes for one search; split bigger areas with price filters (for example min-price/max-price) to get more.

## Actor input object example

```json
{
  "search_urls": [
    "https://www.redfin.com/city/16163/WA/Seattle/filter/property-type=house+condo+townhouse,max-price=1.5M"
  ],
  "property_urls": [],
  "max_results_per_search": 25
}
```

# Actor output Schema

## `dataset` (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 = {
    "search_urls": [
        "https://www.redfin.com/city/16163/WA/Seattle/filter/property-type=house+condo+townhouse,max-price=1.5M"
    ],
    "max_results_per_search": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("mina_safwat/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 = {
    "search_urls": ["https://www.redfin.com/city/16163/WA/Seattle/filter/property-type=house+condo+townhouse,max-price=1.5M"],
    "max_results_per_search": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("mina_safwat/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 '{
  "search_urls": [
    "https://www.redfin.com/city/16163/WA/Seattle/filter/property-type=house+condo+townhouse,max-price=1.5M"
  ],
  "max_results_per_search": 25
}' |
apify call mina_safwat/redfin-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,mina_safwat/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/Vg80hHsPgxUYFHZL1/builds/uRrx8yC4uO4bDgYHm/openapi.json
