# Realtor.com Scraper — Homes, Rentals & Sold Listings (`s-r/realtor-com-scraper`) Actor

Collect US Realtor.com property listings by city, ZIP code or search URL. Export addresses, prices, sale dates, bedrooms, bathrooms, floor area, agents and photos for investors, proptech and mortgage teams.

- **URL**: https://apify.com/s-r/realtor-com-scraper.md
- **Developed by:** [SR](https://apify.com/s-r) (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.00 / 1,000 listing returneds

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

## Realtor.com Scraper: Homes For Sale, Rentals and Sold Listings

Realtor.com Scraper collects US homes for sale, rental listings and sold properties by city, ZIP code or search URL. Export structured property rows for housing research, investment screening, lead lists and mortgage workflows, without writing code.

Search a city and state, a five-digit ZIP code, a county or a neighbourhood. The actor returns addresses, published prices, bedrooms, bathrooms, floor area, listing dates, brokers and photos. Stable property IDs help connect snapshots taken on different days. Address and ZIP fields also provide join keys for datasets from other housing portals.

### Realtor.com Scraper input

Provide either `location` or `url`. A location such as `Austin, TX` or `78701` starts a search directly. A state abbreviation alone is rejected because it can resolve to an unrelated place. A Realtor.com search URL supplies its location, status and supported filters. If both inputs are present, the URL takes precedence.

`status` accepts `for_sale`, `for_rent` or `sold`, with `for_sale` as the default. Sale searches include ready-to-build homes as well as active sale listings. Rental searches return both individual homes and apartment buildings. Sold searches return published sales, rather than treating the last asking price as the sale price.

Use `limit` to set the maximum number of unique properties to collect. Its default is 100 and its maximum is 10,000. The actor continues automatically when a search needs several result pages. The source exposes at most 10,000 source rows per search, so MLS duplicates can make the unique-property count lower. Narrow a large search by location, price or property type to collect another segment.

Numeric filters are `min_price`, `max_price`, `min_beds`, `max_beds`, `min_baths`, `min_sqft` and `max_sqft`. Prices are in US dollars; rental prices are monthly. Floor area is in square feet. Minimum bounds must not exceed maximum bounds. Bedrooms and bathrooms accept values from zero through twenty, including zero-bedroom studios.

`property_type` accepts a list containing `single_family`, `condo`, `townhome`, `multi_family`, `mobile`, `land`, `farm` or `apartment`. Output uses the source's names, such as `condos` and `townhomes`. `sort` accepts `newest`, `price_low` and `price_high`. Newest means listing date for sale and rental searches, and sale date for sold searches. Price sorting uses the published asking price.

For sold searches, `sold_within_days` optionally limits sales to the last 1–3,650 days. Future sale dates are always excluded. Without this field there is no lower date bound. Supported search URL filters include property type, bedroom range, minimum bathrooms, asking-price range and floor-area range. Unsupported filter segments return an input error so the actor does not silently run a broader search.

### What the Realtor.com scraper returns

Every row is one property as Realtor.com publishes it: the listing URL, full address with ZIP code and coordinates, price, status, listing date and days on market, bedrooms, bathrooms, floor area, lot size, property type, year built, broker, listing agent name, MLS identifiers and the main photo. Sold rows add the sale date and the published sale price. Rental buildings add their monthly rent range and unit ranges. The sections below describe the input and every output field in detail.

### Realtor.com scraper output

The default dataset contains one row per unique `property_id`. When the same home appears through multiple MLS sources, the first occurrence is kept. `listing_id` equals the stable property ID; `realtor_listing_id` preserves the separate offering ID where available. Positions count delivered unique properties across all pages.

Each row includes `url`, `address`, `street`, `city`, `state`, `postal_code`, `country_code`, `lat` and `lng`. Postal codes remain strings, preserving leading zeros. Property details include `bedrooms`, `bathrooms`, `living_area`, `lot_area`, `property_type`, `year_built`, `broker`, `agent_name`, `image_url` and published MLS identifiers. Missing source values remain `null`.

For active listings, `price` is the asking price; for rentals it is the monthly rent. For sold properties it is the reported sale price. In states where sale prices are not publicly disclosed, including Texas, `price` may be null while `list_price` still contains the last asking price. Those values have different meanings and are never substituted for each other.

Apartment buildings can publish a rental range instead of one price. These rows keep `price` null and expose `price_min` and `price_max`. Similar range fields preserve bedrooms, bathrooms and floor area for building listings. `currency` is USD only when `price` is present; an area unit appears only when the corresponding area is present.

`list_date` and `fetched_at` provide the basis for `days_on_market`. Active listings use whole elapsed days since listing; sold homes use whole days between listing and sale. `sold_at` appears only for sold results. Photos use HTTPS. Flags preserve published pending, contingent, foreclosure, new-construction and price-reduction indicators. Agent email addresses are excluded.

The run output also reports the source match count as `total`, plus `partial`, `warnings` and any `next_cursor` when more collection remains. The match count precedes deduplication and can differ slightly from the website's displayed count. A failed later page preserves already collected properties and reports the incomplete result.

### Use cases

- **Investment screening.** Pull all homes for sale in a ZIP code within a price band and rank them by price per square foot, lot size or days on market before visiting a single listing page.
- **Comparable sales.** Collect recently sold homes with `sold_within_days` and compare sale price, asking price and floor area for nearby properties. In non-disclosure states the last asking price stays available separately.
- **Rental market research.** Track monthly rents for houses and apartment buildings in the cities you manage or plan to enter, including published rent ranges per building.
- **Mortgage and lending workflows.** Watch new listings in a service area so loan officers can follow active inventory, price reductions and pending flags.
- **Lead lists for agents and service providers.** Broker and agent names on fresh listings show who is active in a neighbourhood this week. Contact emails are not collected.
- **Market monitoring and proptech dashboards.** Schedule the same search daily and compare stable property IDs, prices and status between runs to see new inventory, price cuts and sales.
- **Cross-portal matching.** Join Realtor.com rows with Zillow or Redfin datasets on address, ZIP code and coordinates to compare coverage and pricing between portals.

### How to scrape Realtor.com without code

Type a location such as `Austin, TX` or a ZIP code, choose for sale, for rent or sold, and set a limit. Alternatively, set your filters on the Realtor.com website and paste the search URL from your browser. Start the run and download the dataset as JSON, CSV, Excel or HTML when it finishes. You can also call the actor through the Apify API, connect it to Make, Zapier or n8n, or schedule it so the same search lands in your spreadsheet or database every day.

### Realtor.com scraper compared with other options

- **The Realtor.com API.** Realtor.com's public API offerings are lead-delivery integrations for agents and brokerages. They do not give you an open export of current search results. This actor returns the listings that the public search shows, as rows.
- **MLS data feeds.** Direct MLS and IDX feeds are the most complete source, but they require membership or a licensing agreement per region. This actor covers listings nationwide from one input and needs no MLS membership. It does not replace licensed MLS data for uses that require it.
- **Browser extensions and copy-paste.** Extensions export the page in front of you, one search at a time. This actor pages through up to 10,000 results per search in the cloud and can run on a schedule or through the API.
- **Writing your own Realtor.com scraper.** Your own Python code means maintaining queries, pagination, deduplication and field mapping whenever the site changes. Here the field names stay stable and you pay only for delivered properties.
- **Other real estate scrapers.** Many Realtor.com actors focus on agent contact lists or on single property pages. This actor focuses on search results: one consistent property row for sale, rental and sold searches, with duplicate MLS listings removed and sale prices never confused with asking prices.

### Pricing

The pricing panel on this actor shows the applicable rates. A run-start event is charged once per run, and the listing event is charged once per delivered property. Duplicate source rows are not charged again. A search with no matches produces no listing charge; the run-start event still applies. The actor does not charge a separate event for every source page.

Users without a paid Apify plan receive at most ten properties per run, even if their input asks for more. Listing charges are based on those delivered rows. Paid users can request the full supported volume. The dataset is delivered before its listing events are charged, and the run output records any charging problem.

### FAQ

#### Can I export Realtor.com data to Excel or CSV?

Yes. Every Apify dataset can be downloaded as CSV, Excel, JSON, XML or HTML, or fetched through the API. The overview table shows the most used columns; the full export contains every field described above.

#### Does the Realtor.com scraper collect agent phone numbers or emails?

No. Rows include the broker name, the listing agent's name and MLS identifiers where the listing publishes them. Email addresses are deliberately excluded, and the actor does not open agent profile pages.

#### Can I combine these results with Zillow or Redfin data?

Yes. Use the full address, ZIP code and coordinates to match properties across portals. Property IDs belong to their respective portals, so Realtor.com IDs are useful for repeat snapshots within this source rather than as universal identifiers.

#### Why is a sold home missing its sale price?

The source does not publish every transaction amount. Local disclosure rules and available records affect coverage. A missing sale price remains null; the last asking price is available separately if the source includes it.

#### Why did I receive fewer properties than the source match count?

Your requested limit, repeated MLS offerings, unavailable records and the source's 10,000-row ceiling can all reduce delivery. Check the run output for warnings and refine a large search into smaller, disjoint groups.

#### Does this actor provide historical snapshots automatically?

Each run captures the listings available at collection time. Save successive datasets and compare stable property IDs, asking prices, status and listing dates to build your own change history. A sold search reports source sales records, rather than recreating every previous listing snapshot.

### Example from a collected listing

This row is a field selection from the real Austin response collected on 5 October 2026.
The full response and input are saved in the product examples. Values represent that snapshot.

```json
{
  "property_id": "9595737082",
  "url": "https://www.realtor.com/realestateandhomes-detail/1706-Redd-St-2_Austin_TX_78745_M95957-37082",
  "address": "1706 Redd St Unit 2, Austin, TX 78745",
  "postal_code": "78745",
  "price": 260000,
  "status": "for_sale",
  "list_date": "2026-10-05T15:35:30.000000Z",
  "days_on_market": 0,
  "bedrooms": 3,
  "bathrooms": 2,
  "living_area": 1021,
  "property_type": "single_family",
  "broker": "eXp Realty, LLC",
  "image_url": "https://ap.rdcpix.com/15ddd1c34d2a41c9e5fd9d69d0ed6f88l-m964527949s.jpg",
  "fetched_at": "2026-10-05T16:13:17.000Z"
}
```

# Actor input Schema

## `location` (type: `string`):

US city and state, ZIP code, county or neighbourhood. Required unless url is provided.

## `url` (type: `string`):

Realtor.com search or property URL. URL location, status and filters take precedence over the corresponding fields.

## `status` (type: `string`):

Listing status; for_sale includes ready-to-build listings. A search URL sets its own status.

## `limit` (type: `integer`):

Maximum unique properties over all cursor pages. The source exposes at most 10,000 rows per search.

## `property_type` (type: `array`):

One or more property types. Output retains Realtor.com type names.

## `sort` (type: `string`):

Explicit stable sort: newest listing date (sold date for sold) or asking price ascending/descending.

## `sold_within_days` (type: `integer`):

Only for sold searches: include sales within this many days. Future sale dates are always excluded.

## `cursor` (type: `string`):

Opaque next_cursor from a previous response. Retain the original location, URL and filters; limit may be reduced to the remaining volume.

## `min_price` (type: `integer`):

Minimum asking price in USD (monthly for rentals).

## `max_price` (type: `integer`):

Maximum asking price in USD (monthly for rentals).

## `min_beds` (type: `integer`):

Minimum bedrooms.

## `max_beds` (type: `integer`):

Maximum bedrooms.

## `min_baths` (type: `integer`):

Minimum bathrooms.

## `min_sqft` (type: `integer`):

Minimum living area in square feet.

## `max_sqft` (type: `integer`):

Maximum living area in square feet.

## Actor input object example

```json
{
  "location": "Austin, TX",
  "status": "for_sale",
  "limit": 100,
  "sort": "newest"
}
```

# Actor output Schema

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

One row per unique Realtor.com property.

## `output` (type: `string`):

Delivered rows, charges, free tier, next cursor and 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 = {
    "location": "Austin, TX"
};

// Run the Actor and wait for it to finish
const run = await client.actor("s-r/realtor-com-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 = { "location": "Austin, TX" }

# Run the Actor and wait for it to finish
run = client.actor("s-r/realtor-com-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 '{
  "location": "Austin, TX"
}' |
apify call s-r/realtor-com-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,s-r/realtor-com-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/8VZrPyBbuSBqmuoxs/builds/qKa48cegBpWZPnRo0/openapi.json
