# Redfin Real-Time Data Scraper — Listings & Agent Leads (`b2b_leads/redfin-real-time-data-scraper`) Actor

Collect US property listings with listing-agent contact details — name, phone, email, brokerage, socials — across 60 metros. Filter by price, beds, baths, size, status, days on market. Structured JSON streams to your dataset in real time. Paid plans only; free accounts get a small sample.

- **URL**: https://apify.com/b2b\_leads/redfin-real-time-data-scraper.md
- **Developed by:** [Emmanuel](https://apify.com/b2b_leads) (community)
- **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/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 Real-Time Data Scraper

**Collect US residential listings and listing-agent lead details from 60 supported metros — price, beds, baths, size, lot, year built, days on market, HOA, location, status, and the agent behind each listing — as clean, structured JSON streamed to your dataset in real time.**

Built for real estate investors, wholesalers, agents, and growth teams that need fresh property data **and** the contact behind it, without slow, fragile, browser-based tooling.

> ### ⚠️ Paid plans only — please read
>
> This Actor is **paid-only**. On the Apify **free plan**, every run exports a small sample (2 results per run by default) and then finishes gracefully with an upgrade note. To get the full, unlimited output you set in the input, run it on a **paid Apify plan** (any paid tier — Bronze and up). See [Paid plans & the free-tier sample](#paid-plans--the-free-tier-sample) and the [FAQ](#faq).

***

### Why this Actor

| | Redfin Real-Time Data Scraper | Typical browser-based tool |
|---|---|---|
| **Speed** | Fast per-listing collection, results stream as they are ready | Often 5–15 s per listing |
| **Memory** | **512 MB** default | 2–4 GB+ |
| **Setup** | Organized input UI, run immediately | Fragile selectors, constant maintenance |
| **Output** | Structured JSON, one row per listing, LLM-ready | Messy exports |
| **Scale** | Large runs — up to **100,000 rows** per run | Usually capped far lower |
| **Multi-market** | Up to 60 metros in a single run | One market at a time |
| **Lead details** | Listing-agent contact block on every row | Rarely included |

***

### What you get — one row per listing

Every row includes `featureType` (`property_listing`), `source` (`redfin`), and `scrapedAt`, so records are easy to filter, join, and pipe into any workflow.

#### Property data

| Field | Description |
|-------|-------------|
| `propertyId`, `listingId` | Stable identifiers for de-duplication and joins |
| `url` | Public listing link |
| `address`, `street`, `city`, `state`, `zip` | Full location breakdown |
| `neighborhood` | Subdivision / area name when published |
| `latitude`, `longitude` | Coordinates |
| `price`, `pricePerSqft` | Current list price and computed $/sq ft |
| `beds`, `baths`, `sqft` | Core size facts |
| `lotSize`, `yearBuilt` | Lot size (sq ft) and build year |
| `daysOnMarket` | How long the listing has been listed |
| `hoa` | Monthly HOA fee when published |
| `propertyType` | House, Condo, Townhouse, Multi-family, Land, Mobile, Co-op, Other |
| `status` | Active, Coming soon, Pending, … |
| `searchLocation` | Which metro in your input produced this row |

#### Lead details (enable in the input)

| Field | Description |
|-------|-------------|
| `agentName` | Listing agent's name |
| `brokerName` | Agency / brokerage name |
| `agentPhone` | Listing agent's direct line |
| `officePhone` | Brokerage office line |
| `agentEmail` | Email address (when published) |
| `agentUrl` | Public agent profile link |
| `agentWebsite` | Agent's or brokerage's own website |
| `facebook`, `linkedin`, `instagram`, `twitter` | Social profiles |
| `hasLeadDetails` | `true` when at least one usable contact channel (phone, email, website, profile, or social) was found |
| `leadDetailsEnabled` | Whether you enabled lead details for this run |

**Rows are never filtered by lead completeness.** Every listing is exported whether or not lead details were found — rows without contacts simply have empty lead columns and `hasLeadDetails: false`. That keeps your cost and runtime per 1,000 listings predictable. Enabling lead details adds a little extra time per property.

***

### Who it's for

- **Real estate investors & wholesalers** — build motivated-seller and fresh-inventory lists with the agent's direct line attached.
- **Real estate agents & teams** — prospect FSBO-adjacent inventory, track competitors' listings, and reach listing agents for co-op deals.
- **Lead-gen agencies** — sell fresh, contactable property leads with phones, emails, and socials.
- **Property managers & iBuyers** — monitor new supply and pricing across metros daily.
- **Mortgage brokers & lenders** — reach agents active in specific price bands and neighborhoods.
- **Data teams & analysts** — a stable, well-typed JSON feed for warehouses, dashboards, and BI.
- **AI & automation builders** — LLM-ready structured output with clean field names, MCP support, and webhooks.
- **Marketers** — target owners and agents by metro, price band, property type, and days on market.

***

### Use cases

- **Fresh-listing alerts** — run on a schedule and get brand-new listings (days on market ≤ 7) pushed to Slack or your CRM in real time.
- **Agent outreach lists** — every listing carries the listing agent's name, phone, email, brokerage, and socials where available.
- **Investor deal flow** — filter by price band, property type, and days on market to spot fresh inventory first.
- **Market monitoring** — track inventory, pricing, and status changes across up to 60 metros in one scheduled run.
- **Wholesaling comps** — pull active and coming-soon inventory per metro with coordinates for mapping.
- **CRM enrichment** — stream rows straight into HubSpot, Pipedrive, Zoho, or a Google Sheet via webhook.
- **Data warehousing** — one row per listing with stable IDs makes incremental loads and de-duplication trivial.
- **AI pipelines** — feed structured listing + agent JSON into scoring, valuation summaries, or outreach draft generation.
- **Neighborhood research** — use `neighborhood`, coordinates, and price data for micro-market analysis.
- **Competitive tracking** — watch a brokerage's activity by following the agents that keep appearing on new listings.
- **Direct mail campaigns** — export addresses with ZIP codes for targeted mailings.
- **Content & research** — journalists and analysts use the clean schema for housing-market reporting.

***

### Supported metros

The Actor works across **60 US metros** (city + surrounding area). Write them as `"City, ST"`:

Austin TX · Atlanta GA · Albuquerque NM · Baltimore MD · Boise ID · Boston MA · Buffalo NY · Charleston SC · Charlotte NC · Chicago IL · Cincinnati OH · Cleveland OH · Colorado Springs CO · Columbus OH · Dallas TX · Denver CO · Des Moines IA · Detroit MI · Fresno CA · Fort Worth TX · Greenville SC · Hartford CT · Honolulu HI · Houston TX · Indianapolis IN · Jacksonville FL · Kansas City MO · Las Vegas NV · Louisville KY · Los Angeles CA · Memphis TN · Miami FL · Milwaukee WI · Minneapolis MN · Nashville TN · New Orleans LA · New York NY · Oklahoma City OK · Omaha NE · Orlando FL · Philadelphia PA · Phoenix AZ · Pittsburgh PA · Portland OR · Providence RI · Raleigh NC · Richmond VA · Riverside CA · Sacramento CA · Salt Lake City UT · San Antonio TX · San Diego CA · San Francisco CA · San Jose CA · Seattle WA · St. Louis MO · Tampa FL · Tucson AZ · Virginia Beach VA · Washington DC

Unsupported locations fail fast with a clear message listing the supported metros, instead of quietly returning the wrong area.

***

### Input reference

Every field, its type, and its default. The same reference is shown in the **Input** tab on the Apify Console.

| Input | Type | Default | Description |
|-------|------|---------|-------------|
| **Metros to collect** | | | |
| `searchLocations` | string\[] | `["Austin, TX"]` | One row per metro. Supported values are the 60 metros listed above, written as `"City, ST"`. |
| `maxResultsPerSearch` | integer | `10` | How many listings to collect for each metro, 1–500. The Actor keeps collecting for a metro until it reaches this number or runs out of matches. |
| `statusFilter` | enum\[] | `[]` (all) | Keep only listings with these statuses: `active`, `coming_soon`, `pending`. Empty = every status. |
| `propertyTypes` | enum\[] | `[]` (all) | Keep only these types: `house`, `condo`, `townhouse`, `multi_family`, `land`, `other`. |
| **Lead details** | | | |
| `enableLeadDetails` | boolean | `true` | Attach the listing agent's contact block to every listing. Every listing is exported whether or not lead details are found. Adds a little extra time per property. |
| **Refine your search** | | | |
| `minPrice` / `maxPrice` | integer | — | Price bounds in USD. Listings without a published price are dropped when a bound is set. |
| `minBeds` / `maxBeds` | integer | — | Bedroom bounds. |
| `minBaths` | number | — | Minimum bathrooms (decimals allowed, e.g. `2.5`). |
| `minSqft` / `maxSqft` | integer | — | Living-area bounds (sq ft). |
| `maxDaysOnMarket` | integer | — | Only listings listed within this many days. Great for fresh-inventory alerts. |
| **Output & limits** | | | |
| `maxItems` | integer | `100` | Hard ceiling on total rows for the whole run, across every metro (1–100,000). Main cost and runtime lever. |
| `webhookUrl` | string | `""` | Optional. Rows are always saved to the dataset — this URL additionally receives each row in real time (CRM, Slack, Zapier, Make, Sheets). See [Webhook delivery](#webhook-delivery-optional). |
| `webhookFormat` | enum | `json` | `json` = the full row object; `slack` = a Slack-friendly message payload. |

> **Free plan note:** on the Apify free plan the per-metro and total results are capped to a small free sample regardless of the values you set here. Paid plans get the full value you set. See the [FAQ](#faq).

Filters only remove listings that clearly fail the condition — they never reorder or hold back results.

***

### Output reference

#### Dataset rows

Each dataset item is one JSON object — a property listing with its lead block. Example:

```json
{
  "featureType": "property_listing",
  "source": "redfin",
  "propertyId": "31216361",
  "listingId": "223711446",
  "url": "https://www.redfin.com/TX/Austin/2308-Cypress-Pt-E-78746/home/31216361",
  "address": "2308 Cypress Pt E, Austin, TX, 78746",
  "street": "2308 Cypress Pt E",
  "city": "Austin",
  "state": "TX",
  "zip": "78746",
  "neighborhood": "Lost Creek",
  "latitude": 30.2773084,
  "longitude": -97.8426634,
  "price": 1825000,
  "pricePerSqft": 579,
  "beds": 4,
  "baths": 3,
  "sqft": 3152,
  "lotSize": null,
  "yearBuilt": 1975,
  "daysOnMarket": 2,
  "hoa": null,
  "propertyType": "House",
  "status": "Coming Soon",
  "agentName": "Jane Doe",
  "brokerName": "Example Realty",
  "agentPhone": "(512) 555-0142",
  "officePhone": "1-844-759-7732",
  "agentEmail": null,
  "agentUrl": null,
  "agentWebsite": null,
  "facebook": null,
  "linkedin": null,
  "instagram": null,
  "twitter": null,
  "hasLeadDetails": true,
  "leadDetailsEnabled": true,
  "searchLocation": "Austin, TX",
  "scrapedAt": "2026-09-23T15:05:45.123Z"
}
```

The dataset ships with three ready-made views: **Overview** (every listing at a glance), **Listings** (property data), and **Lead details** (agent contact columns surfaced for outreach).

#### Run summary (key-value store → `OUTPUT`)

Every run writes a summary describing what happened:

```json
{
  "locations": ["Austin, TX"],
  "listingsExported": 40,
  "leadDetailsFound": 31,
  "leadDetailsMissing": 9,
  "errors": [],
  "spendingLimitReached": false,
  "startedAt": "2026-09-23T15:05:30.985Z",
  "finishedAt": "2026-09-23T15:06:59.157Z",
  "paywall": {
    "detected": true,
    "isPaying": true,
    "pricingTier": "BRONZE",
    "limited": false,
    "blocked": false,
    "freeTierMaxItems": null,
    "freeTierMaxItemsPerSearch": null
  }
}
```

| Field | Description |
|-------|-------------|
| `locations` | Metros included in the run |
| `listingsExported` | Rows written to the dataset |
| `leadDetailsFound` / `leadDetailsMissing` | How many rows carried at least one contact channel |
| `errors` | Short, fixed descriptions of any non-fatal problem (never contains connection details) |
| `spendingLimitReached` | `true` when the run stopped because your maximum cost for the run was reached |
| `startedAt` / `finishedAt` | Run window |
| `paywall.detected` | Whether the platform's pay-status was available to the run |
| `paywall.isPaying` | Whether you are on a paid Apify plan |
| `paywall.pricingTier` | Your Apify plan tier, when known |
| `paywall.limited` | `true` when the free-plan sample cap was applied |
| `paywall.blocked` | `true` when the run was stopped because free-plan output is disabled by the publisher |
| `paywall.freeTierMaxItems` / `freeTierMaxItemsPerSearch` | The caps in force for a free run, when capped |

***

### Webhook delivery (optional)

Every row is **always saved to the Apify dataset** first. If you set `webhookUrl` in the **Output & limits** section, each new row is **also POSTed in real time** to your URL — useful for CRMs, Slack, Zapier, Make, Google Sheets, or custom pipelines.

| Setting | Description |
|---------|-------------|
| `webhookUrl` | Your receiving URL (`https://…`). Leave empty to use the dataset only. |
| `webhookFormat` | `json` — the full row object (identical to the dataset row above). `slack` — a compact Slack incoming-webhook message with the address, price, size, status, and agent contacts. |

**Example — fresh listings to Slack**

```json
{
  "searchLocations": ["Austin, TX"],
  "maxResultsPerSearch": 40,
  "maxDaysOnMarket": 7,
  "webhookUrl": "https://hooks.slack.com/services/YOUR/WEBHOOK/URL",
  "webhookFormat": "slack"
}
```

**Example — rows into your CRM as JSON**

```json
{
  "searchLocations": ["Miami, FL", "Tampa, FL"],
  "enableLeadDetails": true,
  "maxItems": 500,
  "webhookUrl": "https://your-crm.example.com/api/leads",
  "webhookFormat": "json"
}
```

Webhook payloads contain exactly the same fields as the dataset row — nothing else is attached. Delivery is **best-effort**: a failed webhook never stops the run and the row is still saved to the dataset.

***

### MCP usage

Output is **structured JSON** — ideal for ChatGPT, Claude, Gemini, LangChain, LlamaIndex, and custom agents.

#### Apify MCP (Model Context Protocol)

Use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) so AI assistants can:

- **Run** this Actor with natural-language instructions
- **Read** dataset results directly in the chat
- **Chain** with other Actors (e.g. enrich → score → CRM)

Typical MCP flow:

```
User: "Collect 40 fresh listings under $600k in Austin with agent contacts and
summarize the best outreach targets"
→ MCP runs the Actor with searchLocations=["Austin, TX"], maxResultsPerSearch=40,
  maxPrice=600000, maxDaysOnMarket=14, enableLeadDetails=true
→ MCP reads the dataset items
→ The assistant ranks rows by hasLeadDetails and drafts outreach
```

#### Recommended workflow outside MCP

1. Run the Actor with your metros, filters, and `enableLeadDetails: true`.
2. Fetch dataset items via the [Apify API](https://docs.apify.com/api/v2) or export JSON/CSV/Excel.
3. Pass rows to your LLM or index them into a vector store — every field is a clean, typed column.

#### API quick start

```bash
curl -X POST "https://api.apify.com/v2/acts/YOUR_ACTOR_ID/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "searchLocations": ["Austin, TX", "Dallas, TX"],
    "maxResultsPerSearch": 40,
    "enableLeadDetails": true,
    "maxItems": 80
  }'
```

Dataset items: `GET https://api.apify.com/v2/datasets/{datasetId}/items?format=json`

***

### Quick start examples

**Fresh listings with agent contacts (lead gen)**

```json
{
  "searchLocations": ["Phoenix, AZ"],
  "maxResultsPerSearch": 100,
  "maxDaysOnMarket": 14,
  "enableLeadDetails": true,
  "maxItems": 100
}
```

**Investor deal flow, filtered**

```json
{
  "searchLocations": ["Jacksonville, FL", "Cleveland, OH"],
  "maxResultsPerSearch": 200,
  "minPrice": 100000,
  "maxPrice": 400000,
  "propertyTypes": ["house", "townhouse", "multi_family"],
  "statusFilter": ["active", "coming_soon"],
  "enableLeadDetails": true,
  "maxItems": 400
}
```

**Multi-metro market monitor with webhook**

```json
{
  "searchLocations": ["Dallas, TX", "Houston, TX", "San Antonio, TX", "Austin, TX"],
  "maxResultsPerSearch": 50,
  "enableLeadDetails": false,
  "maxItems": 200,
  "webhookUrl": "https://your-pipeline.example.com/hooks/new-listings",
  "webhookFormat": "json"
}
```

**Luxury watchlist**

```json
{
  "searchLocations": ["Los Angeles, CA"],
  "maxResultsPerSearch": 100,
  "minPrice": 3000000,
  "enableLeadDetails": true,
  "maxItems": 100
}
```

***

### Performance & limits

- **Streaming output** — rows are written to the dataset one by one as they are ready, so even very long runs stay light on memory and your first results are available immediately.
- **Memory** — 512 MB default is plenty; you rarely need to change it.
- **Run length** — the default maximum run length is 10,000 seconds (~2.8 hours), sized for large multi-metro runs.
- **Your budget is respected** — if you set a maximum cost for the run in Apify, the Actor stops gracefully the moment that limit is reached instead of running past it. The run summary's `spendingLimitReached` flag tells you when that happened.
- **De-duplication** — the same listing is never exported twice within one run.

***

### Paid plans & the free-tier sample

This Actor is monetized on the Apify Store, and its policy is stated here openly:

- **Paid Apify plans (Bronze and up):** full, unlimited output — every metro, every row, no caps.
- **Apify free plan:** each run exports a small sample — **2 results per run** (and at most 2 per metro) by default — then finishes **gracefully** with a clear upgrade note. Nothing crashes; the run summary's `paywall` object always shows exactly what was applied.
- The publisher can tune the free sample (cap, per-metro cap, or a stricter block mode) via owner-only settings — `FREE_TIER_MODE`, `FREE_TIER_MAX_ITEMS`, and `FREE_TIER_MAX_ITEMS_PER_SEARCH` — without a code change. These are publisher-side environment settings, not user inputs.
- If the publisher enables block mode, free-plan runs stop right after input validation — before any collection work and before any charge.

Upgrading to any paid Apify plan unlocks the full output immediately — no code or input changes needed.

***

### FAQ

**Is this Actor usable on the free plan?**
Only as a taste: free-plan runs export a small sample (2 results per run by default) and then finish with an upgrade note. For real workloads you need a paid Apify plan — Bronze or above.

**Why did my run stop at 2 results?**
You are on the Apify free plan. The `paywall` object in the run summary (key-value store → `OUTPUT`) confirms it (`limited: true`). Upgrade to any paid Apify plan and re-run — the same input then returns everything you asked for.

**How fresh is the data?**
Every run works against live inventory at the moment it runs — there is no cache of old listings. `scrapedAt` on each row tells you exactly when it was collected.

**Which locations are supported?**
60 US metros — see the [Supported metros](#supported-metros) section. Unsupported inputs fail fast with the list of supported metros.

**Can I get only listings that have agent phone numbers?**
No — and that is deliberate. Filtering by lead completeness would make runtime and cost per 1,000 listings unpredictable. Every listing is exported; use the `hasLeadDetails` column (and the **Lead details** dataset view) to slice in your own tooling.

**What if a listing has no lead details at all?**
It is still exported, with empty lead columns and `hasLeadDetails: false`. You never lose the property row because the contact block is empty.

**Are the emails always there?**
No. Emails are included when the agent or brokerage publishes one on their own site — it is best-effort enrichment on top of the listing's contact block. Phone numbers and profile links are the most consistently available channels.

**Does it work outside the United States?**
No — the metro coverage is US-only.

**A webhook row failed to deliver. Did I lose data?**
No. The dataset is always written first; the webhook is an additional real-time push. Failed deliveries are reported in the log and the row stays safe in the dataset.

**How do I keep costs predictable?**
Set `maxItems` — it is a hard ceiling across the whole run. Also set a maximum cost for the run in Apify; the Actor honors it and stops gracefully. De-duplication means you never pay twice for the same listing in one run.

**Why do lead details make runs a bit slower?**
Attaching the agent's contact block means gathering a little extra information per property. It adds a small, steady amount of time per listing — not per field — and you can switch it off entirely with `enableLeadDetails: false`.

**Is this affiliated with Redfin?**
No. This is an independent data tool. Use it responsibly and comply with applicable laws and the source's terms.

***

### Limitations & compliance

- Coverage is limited to the supported US metros; other locations are rejected with a clear message rather than approximated.
- Lead-detail availability varies by listing — some agents publish only a name; those rows are exported with empty contact columns.
- Not affiliated with Redfin or any brokerage. Use responsibly and comply with applicable laws, regulations, and the source's terms of service.

***

### Contact & custom work

Need something beyond this Actor? I build **custom scrapers**, **data pipelines**, and **full-stack web applications** for startups and enterprises.

- **Email:** <dubem115@gmail.com>
- **GitHub:** [github.com/DrunkCodes](https://github.com/DrunkCodes)

Reach out for:

- Custom Apify Actors (any website or data source)
- Real estate data projects at scale
- LLM & MCP integrations with your data stack
- Web apps, dashboards, and automation tools

***

*Redfin Real-Time Data Scraper · by [DrunkCodes](https://github.com/DrunkCodes)*

# Actor input Schema

## `searchLocations` (type: `array`):

One row per US metro. Supported metros: Austin TX, Albuquerque NM, Atlanta GA, Baltimore MD, Boise ID, Boston MA, Buffalo NY, Charleston SC, Charlotte NC, Chicago IL, Cincinnati OH, Cleveland OH, Colorado Springs CO, Columbus OH, Dallas TX, Denver CO, Des Moines IA, Detroit MI, Fresno CA, Fort Worth TX, Greenville SC, Hartford CT, Honolulu HI, Houston TX, Indianapolis IN, Jacksonville FL, Kansas City MO, Las Vegas NV, Louisville KY, Los Angeles CA, Memphis TN, Miami FL, Milwaukee WI, Minneapolis MN, Nashville TN, New Orleans LA, New York NY, Oklahoma City OK, Omaha NE, Orlando FL, Philadelphia PA, Phoenix AZ, Pittsburgh PA, Portland OR, Providence RI, Raleigh NC, Richmond VA, Riverside CA, Sacramento CA, Salt Lake City UT, San Antonio TX, San Diego CA, San Francisco CA, San Jose CA, Seattle WA, St. Louis MO, Tampa FL, Tucson AZ, Virginia Beach VA, Washington DC. Write them as "City, ST" (e.g. "Miami, FL"). Every listing found is exported to your dataset as it is collected.

## `maxResultsPerSearch` (type: `integer`):

How many listings to collect for each metro in the list above. The Actor keeps collecting for a metro until it reaches this number or runs out of matches — whichever comes first. NOTE: on the Apify free plan each metro is capped to a small free sample; paid plans get the full value. See the README for current free-tier limits.

## `statusFilter` (type: `array`):

Keep only listings with these statuses. Leave empty (default) to keep every status. Values: active, coming\_soon, pending.

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

Keep only these property types. Leave empty (default) to keep every residential and land type.

## `enableLeadDetails` (type: `boolean`):

Attach the listing agent's contact details to every listing: agent name, direct phone, office phone, email address, agent profile link, agency/brokerage name, website, and social profiles. Every listing is exported whether or not lead details are found — results are never filtered by lead completeness, so your cost per result and runtime stay predictable. Adds a little extra time per property.

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

Leave empty for no lower bound. Listings without a published price are dropped when this is set.

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

Leave empty for no upper bound. Listings without a published price are dropped when this is set.

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

Only keep listings with at least this many bedrooms.

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

Only keep listings with at most this many bedrooms.

## `minBaths` (type: `number`):

Only keep listings with at least this many bathrooms (decimals allowed, e.g. 2.5).

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

Only keep listings at or above this living area.

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

Only keep listings at or below this living area.

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

Only keep listings that have been on the market for at most this many days. Great for spotting fresh inventory.

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

Hard ceiling on the total number of rows exported in this run, across every metro. This is the main cost lever and also the main runtime lever. NOTE: on the Apify free plan the global total is capped to a small free sample; paid plans get the full value you set here. See the README for current free-tier limits.

## `webhookUrl` (type: `string`):

Optional. Every row is always saved to the run's dataset — this webhook is an ADDITIONAL real-time push. When set, each new row is also POSTed to this URL (CRM, Slack incoming webhook, Zapier, Make, Google Sheets).

## `webhookFormat` (type: `string`):

json = the full row object; slack = a Slack-friendly message payload.

## Actor input object example

```json
{
  "searchLocations": [
    "Austin, TX"
  ],
  "maxResultsPerSearch": 10,
  "statusFilter": [],
  "propertyTypes": [],
  "enableLeadDetails": true,
  "maxItems": 100,
  "webhookUrl": "",
  "webhookFormat": "json"
}
```

# Actor output Schema

## `allResults` (type: `string`):

Complete dataset with every field from this run — one row per property listing.

## `listings` (type: `string`):

Property listings: address, price, beds, baths, size, lot, year built, days on market, HOA, coordinates, and status.

## `leads` (type: `string`):

Listings with the listing-agent contact columns surfaced for outreach.

## `runSummary` (type: `string`):

Per-run metadata: metros searched, rows exported, lead-detail coverage, spending-limit state, free-tier state, and any non-fatal errors.

# 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 = {
    "searchLocations": [
        "Austin, TX"
    ],
    "maxResultsPerSearch": 10,
    "enableLeadDetails": true,
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("b2b_leads/redfin-real-time-data-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 = {
    "searchLocations": ["Austin, TX"],
    "maxResultsPerSearch": 10,
    "enableLeadDetails": True,
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("b2b_leads/redfin-real-time-data-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 '{
  "searchLocations": [
    "Austin, TX"
  ],
  "maxResultsPerSearch": 10,
  "enableLeadDetails": true,
  "maxItems": 100
}' |
apify call b2b_leads/redfin-real-time-data-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,b2b_leads/redfin-real-time-data-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/zV8Qd70gEgNcOkt98/builds/HPNeuhMZluaN8nSmO/openapi.json
