# Redfin Property Scraper — For Sale, Sold & Rentals (`axlymxp/redfin-property-scraper`) Actor

Scrape Redfin listings for sale, sold and rentals by city, ZIP or search URL. Get price, beds, baths, sqft, photos and coordinates — plus optional listing-agent phone, price and tax history, schools, Redfin Estimate with 60-month history and rent yield. Pay only for results.

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

## Pricing

from $1.50 / 1,000 dataset items

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

## Redfin Property Scraper — For Sale, Sold & Rentals

Turn any US city, ZIP or Redfin search URL into a clean, structured property dataset — **including the data most Redfin scrapers can't reach**: the listing agent's direct phone, real sold prices, the Redfin Estimate with 60 months of history, and a rent estimate with computed gross yield.

Built directly on Redfin's own mobile API. No browsers, no CAPTCHA solving, no proxies required.

### Who it's for

- **Investors & analysts** — sold comps with real sold prices and dates, Redfin Estimate history, rent estimate and gross rental yield in a single row.
- **Agencies & lead-gen** — the listing agent's name and **direct mobile number** on every listing.
- **PropTech & SaaS developers** — a stable, documented listing feed you can schedule and pipe straight into your product.
- **Researchers & journalists** — market-wide inventory snapshots with price history, tax and school data.

### What makes it different

| Capability | This actor |
| --- | --- |
| **Sold search** | Yes — real sold prices and sold dates, even in non-disclosure states like Texas |
| **Listing agent direct phone** | Yes, on every listing (via `includeDetails`) |
| **Redfin Estimate + 60-month history** | Yes, plus city and county comparison series |
| **Rent estimate + gross yield** | Yes, computed per property |
| **Rentals** | Yes — dedicated rental index with leasing phone numbers |
| **Input** | Plain city/ZIP names — no need to hand-craft map URLs |

### Output fields

#### Always returned

| Field | Type | Description |
| --- | --- | --- |
| `property_id` | integer | Redfin property ID |
| `listing_id` | integer | Redfin listing ID |
| `mls_id` | string | MLS identifier |
| `url` | string | Full Redfin listing URL |
| `status` | string | `ACTIVE`, `PRE_ON_MARKET`, `SOLD`, `PENDING`, … |
| `property_type` | string | `SINGLE_FAMILY`, `CONDO_COOP`, `TOWNHOUSE`, … |
| `address`, `unit_number`, `city`, `state`, `zip`, `neighborhood` | string | Location |
| `latitude`, `longitude` | number | Coordinates |
| `price` | integer | List price (or sold price for sold listings) |
| `price_per_sqft` | number | Computed |
| `beds`, `baths`, `sqft`, `lot_size`, `year_built` | number | Core attributes |
| `days_on_market`, `listed_date` | number / string | Absent on pre-market listings |
| `hoa_dues` | integer | Monthly HOA dues |
| `last_sold_date`, `last_sold_price` | string / integer | Previous sale |
| `sashes` | array | Redfin badges ("HOT HOME", "EARLY ACCESS", …) |
| `photo_count` | integer | Number of photos |
| `is_sold` | boolean | Convenience flag |
| `search_location`, `scraped_at` | string | Provenance |

#### With `includeDetails`

| Field | Type | Description |
| --- | --- | --- |
| `listing_agent_name` | string | Listing agent |
| `listing_agent_phone` | string | **Agent's direct phone** |
| `listing_broker_name` | string | Brokerage |
| `listing_broker_phone` | string | Brokerage phone |
| `is_redfin_agent` | boolean | In-house Redfin agent |
| `description` | string | Full marketing remarks |
| `total_views`, `favorite_count` | integer | Redfin popularity signals |
| `mls_status` | string | Raw MLS status |
| `property_history` | array | Listed / price-changed / sold events with prices |
| `schools` | array | Name, type, grades, GreatSchools rating, distance |
| `open_houses` | array | Upcoming open-house times |
| `stories`, `total_sqft`, `finished_sqft`, `apn`, `county` | mixed | Public records |
| `tax_year`, `taxes_due`, `taxable_land_value`, `taxable_improvement_value` | number | Tax record |

#### With `includeValuation`

| Field | Type | Description |
| --- | --- | --- |
| `redfin_estimate` | integer | Current Redfin Estimate |
| `redfin_estimate_updated` | string | ISO date the estimate was last refreshed |
| `estimate_history` | array | 60 monthly `{month, value}` points |
| `estimate_history_city`, `estimate_history_county` | array | Comparison series |
| `estimate_change_1y_pct` | number | 1-year change |
| `rent_estimate`, `rent_estimate_low`, `rent_estimate_high` | integer | Monthly rent estimate |
| `gross_rent_yield_pct` | number | `rent × 12 / price`, computed |

#### Rentals (`listingType: "rentals"`)

Rental rows describe a **building**, so `rent`, `beds`, `baths` and `sqft` are ranges, and each row carries `property_name`, `unit_count`, the leasing `phone`, `contact_email` and `feed_source`.

### Use cases

- **Daily new-listing alerts** — set `maxDaysOnMarket: 1` and schedule it hourly to catch inventory the moment it hits the market.
- **Automated comps** — `listingType: "sold"` with `soldWithinDays: 90` and a tight `minSqft`/`maxSqft`/`minBeds` band gives you a defensible comp set.
- **Rental yield screening** — enable `includeValuation` and sort your dataset by `gross_rent_yield_pct` to surface cash-flow candidates.
- **Agent outreach lists** — enable `includeDetails` and use `listing_agent_phone` / `listing_broker_name`.
- **Market trend dashboards** — `estimate_history` vs `estimate_history_city` shows whether a property is beating or lagging its market.
- **Portfolio monitoring** — schedule a run over your ZIP codes and diff `price` and `redfin_estimate` week over week.

### Input parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `locations` | array | — | Cities, ZIPs, neighborhoods or counties |
| `searchUrls` | array | — | Redfin search URLs (alternative to `locations`) |
| `listingType` | enum | `for_sale` | `for_sale`, `sold`, `rentals` |
| `maxItems` | integer | 100 | Result cap |
| `includeDetails` | boolean | `false` | Agent contact, history, schools, tax |
| `includeValuation` | boolean | `false` | Redfin Estimate, rent estimate, yield |
| `propertyTypes` | array | all | house, condo, townhouse, multifamily, land, other, manufactured, co-op |
| `minPrice`, `maxPrice` | integer | — | Price band (monthly rent for rentals) |
| `minBeds`, `maxBeds`, `minBaths` | integer | — | Room filters |
| `minSqft`, `maxSqft`, `minYearBuilt` | integer | — | Size and age filters |
| `maxDaysOnMarket` | integer | — | Only listings newer than N days |
| `soldWithinDays` | integer | `90` | For `listingType: "sold"` |
| `sortBy` | enum | `recommended` | Sort order |
| `includeRawData` | boolean | `false` | Attach the full decoded payload |
| `proxyConfiguration` | object | disabled | Optional proxy |

### Example input

```json
{
    "locations": ["Austin, TX", "78704"],
    "listingType": "for_sale",
    "maxItems": 250,
    "includeDetails": true,
    "includeValuation": true,
    "propertyTypes": ["house", "condo"],
    "minPrice": 300000,
    "maxPrice": 900000,
    "minBeds": 3,
    "sortBy": "newest"
}
```

### Example output

```json
{
    "property_id": 31286343,
    "listing_id": 223692122,
    "url": "https://www.redfin.com/TX/Austin/8000-Forest-Mesa-Dr-78759/unit-B/home/31286343",
    "status": "ACTIVE",
    "property_type": "CONDO_COOP",
    "address": "8000 Forest Mesa Dr Unit B",
    "city": "Austin",
    "state": "TX",
    "zip": "78759",
    "neighborhood": "Northwest Hills",
    "latitude": 30.3667322,
    "longitude": -97.7509303,
    "price": 525000,
    "price_per_sqft": 404.47,
    "beds": 2,
    "baths": 2.0,
    "sqft": 1298,
    "year_built": 1981,
    "days_on_market": 2,
    "listed_date": "2026-09-18T19:19:28.350Z",
    "listing_agent_name": "Lili Maliner",
    "listing_agent_phone": "512-657-1957",
    "listing_broker_name": "Coldwell Banker Realty",
    "total_views": 229,
    "favorite_count": 4,
    "schools": [
        { "name": "Hill Elementary School", "type": "Public", "grades": "K-5", "rating": 9, "distance_miles": "0.4" }
    ],
    "redfin_estimate": 452245,
    "estimate_change_1y_pct": -13.74,
    "rent_estimate": 2540,
    "gross_rent_yield_pct": 5.81,
    "scraped_at": "2026-09-21T09:14:03Z"
}
```

### Scheduling & webhooks

Use Apify **Schedules** to run this actor on a cron (e.g. every morning for new listings), and **Webhooks** to POST each finished run to your own endpoint, Zapier or Make. Results are available as JSON, CSV, Excel, XML or RSS from the dataset API.

### Use with AI assistants (MCP)

This actor works with the [Apify MCP server](https://apify.com/apify/actors-mcp-server), so Claude, ChatGPT and other MCP-capable assistants can call it directly — for example "find 3-bed houses under $600k in Austin that sold in the last 30 days and show me the listing agents". Add the actor to your MCP server configuration and it becomes a callable tool.

### FAQ

**Do I need a proxy?**
No. The actor talks to Redfin's mobile API, which does not require proxies, cookies or CAPTCHA solving. A proxy option is available if you want geo control or higher parallelism.

**How fresh is the data?**
It is fetched live from Redfin on every run — there is no cached database behind this actor.

**How many results can I get?**
Redfin returns up to 350 listings per request and the actor paginates automatically. Pass multiple `locations` (or tighter price bands) to cover large metros exhaustively.

**Why is `days_on_market` empty on some rows?**
Pre-market ("Coming Soon" / "Early Access") listings have not started their market clock yet, so Redfin does not publish the value. Those rows are flagged `status: "PRE_ON_MARKET"`.

**Why are tax and last-sold values missing for some properties?**
Texas and other *non-disclosure* states do not publish sale prices or tax detail. This is a limitation of the public record, not of the scraper.

**Is every property covered by the Redfin Estimate?**
No — Redfin does not publish an estimate for every property. When absent, `redfin_estimate` is `null` rather than guessed.

**Is scraping Redfin legal?**
This actor collects publicly available listing information. You are responsible for how you use the data, including compliance with Redfin's terms, MLS rules, and applicable privacy and marketing laws (e.g. TCPA when contacting agents).

**Something broke — what now?**
Open an issue on the actor's Issues tab. Runtime errors are reported automatically to the maintainer, so regressions are usually noticed quickly.

# Actor input Schema

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

US cities, ZIP codes, neighborhoods or counties to scrape. Examples: "Austin, TX", "78704", "Brooklyn, NY". Each entry is resolved through Redfin's own location search.

## `searchUrls` (type: `array`):

Paste Redfin search URLs instead of (or alongside) locations, e.g. https://www.redfin.com/city/30818/TX/Austin. Filters below are applied on top of the URL's region.

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

What to scrape. 'sold' uses Redfin's mobile sold-search (the website silently ignores this filter), 'rentals' uses the dedicated rentals index with leasing phone numbers.

## `maxItems` (type: `integer`):

Maximum number of listings to push to the dataset across all locations. You are charged per result, so this is also your cost cap.

## `includeDetails` (type: `boolean`):

Fetches each property's detail pages to add the listing agent's name and direct phone, the brokerage and its phone, full description, price & tax history, schools, open houses and view/favorite counts. Adds roughly 0.8s per listing.

## `includeValuation` (type: `boolean`):

Adds the Redfin Estimate, its 60-month monthly history (plus city and county comparison series), the 1-year change, the rent estimate and a computed gross rental yield. Ignored for rentals.

## `propertyTypes` (type: `array`):

Limit results to these property types. Leave empty for all.

## `minPrice` (type: `integer`):

Minimum list price. For rentals this is the monthly rent.

## `maxPrice` (type: `integer`):

Maximum list price. For rentals this is the monthly rent.

## `minBeds` (type: `integer`):

Minimum number of bedrooms.

## `maxBeds` (type: `integer`):

Maximum number of bedrooms.

## `minBaths` (type: `integer`):

Minimum number of bathrooms.

## `minSqft` (type: `integer`):

Minimum living area in square feet.

## `maxSqft` (type: `integer`):

Maximum living area in square feet.

## `minYearBuilt` (type: `integer`):

Only return properties built in or after this year.

## `maxDaysOnMarket` (type: `integer`):

Only return listings that have been on Redfin for at most this many days. Useful for daily new-listing alerts.

## `soldWithinDays` (type: `integer`):

Only used when listing type is 'sold'. Defaults to 90.

## `sortBy` (type: `string`):

Sort by.

## `includeRawData` (type: `boolean`):

Adds a 'raw' field with the complete decoded API response for each listing. Useful for debugging or accessing fields this actor does not surface.

## `proxyConfiguration` (type: `object`):

Optional. The Redfin mobile API does not require a proxy, but you can route traffic through one for higher parallelism or geo control.

## Actor input object example

```json
{
  "locations": [
    "Austin, TX",
    "78704"
  ],
  "listingType": "for_sale",
  "maxItems": 100,
  "includeDetails": false,
  "includeValuation": false,
  "propertyTypes": [],
  "soldWithinDays": 90,
  "sortBy": "recommended",
  "includeRawData": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `overview` (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("axlymxp/redfin-property-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("axlymxp/redfin-property-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 axlymxp/redfin-property-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,axlymxp/redfin-property-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/Ikv9lFkz0e7VU34eu/builds/4F53dmtDChPWyKbBT/openapi.json
