# Realtor.com Listings Scraper (`usestring/realtor-listings`) Actor

Scrape Realtor.com by city, state or ZIP and get up to 200 listings per location in one request: numeric price, beds, consolidated baths such as 2.5, areaSqft, lotSizeSqft, status, agentName, brokerName, detailUrl and coordinates. For sale, for rent or recently sold. No account needed.

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

## Pricing

from $0.75 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Realtor.com Scraper — for-sale, for-rent and sold listings

This Actor scrapes Realtor.com listings for any US city, state or ZIP code. Realtor.com renders its
search results in the browser, so the Realtor.com Scraper reads the same search API the page itself
calls and returns up to **200 listings per location** in one request — with **numeric** price, beds,
baths, living area, lot size and coordinates, plus the listing agent and brokerage.

No Realtor.com account, login or cookies are used — this reads what a logged-out visitor sees.

### What it returns

| Field | Type | Notes |
| --- | --- | --- |
| `propertyId` | string | Realtor.com's own property ID — stable across runs, use it to de-duplicate |
| `address` | string | Street line |
| `city`, `state`, `zipcode` | string | Split, not one blob |
| `price` | number | `675000`, not `"$675,000"` — the sold price on a sold row, otherwise the list price |
| `beds`, `baths` | number | `baths` is the consolidated count, so a half bath reads as `2.5` |
| `areaSqft` | number | Living area |
| `lotSizeSqft` | number | Lot size in square feet |
| `status` | string | `for_sale`, `ready_to_build`, `for_rent` or `sold` |
| `agentName` | string | Listing agent where Realtor.com shows one |
| `brokerName` | string | Brokerage or office as the listing displays it |
| `latitude`, `longitude` | number | Exact coordinates, ready to map |
| `detailUrl` | string | Link to the Realtor.com listing page |
| `searchLocation`, `sourceUrl`, `collectedAt` | string | Provenance for every row |

### Input

```json
{ "locations": ["Austin, TX", "78704"], "listingType": "for_sale", "maxItems": 1000 }
```

| Field | Description |
| --- | --- |
| `locations` | Cities with state, e.g. `"Austin, TX"`, or ZIP codes. Required, 1–100. |
| `listingType` | `for_sale` (default, includes `ready_to_build` new construction), `for_rent` or `sold`. |
| `maxItems` | Cap on dataset items. Default 1000. A value under 200 also narrows each request. Free plans stop at 250 requests and 250 results — see below. |
| `concurrency` | Locations fetched in parallel. Default 2, maximum 5. |

### Use cases

- Comparable-sales analysis, using `sold` rows with lot size and living area on the same record
- Rental inventory and pricing across cities, from the `for_rent` surface
- Agent and brokerage lead lists — `agentName` and `brokerName` come with every location
- Feeding a map or dashboard with geocoded for-sale inventory
- Tracking new construction, which Realtor.com files under the `ready_to_build` status

### Reliability

The Realtor.com Scraper takes its rows from Realtor.com's own search API, so prices, beds, baths,
square footage and coordinates arrive as numbers rather than card text. The served HTML carries only
eight hydrated cards and its schema.org block omits baths, lot size, status, agent, broker and
coordinates entirely — reading the API is what makes the full field set possible.

A location that cannot be read is recorded in the run's `SUMMARY` under `failures` rather than
silently returning fewer rows, and a run where every location failed exits with an error.

There are no retries by design: the String Unblocker owns proxy rotation and anti-bot solver
selection, so a retry loop here would only re-roll the same block.

### Frequently asked questions

**Do I need a Realtor.com account, API key or cookies?** No. The Realtor.com Scraper reads public
search results as a logged-out visitor, and never signs in.

**How many listings does the Realtor.com Scraper return per location?** Up to 200 — the most the
Realtor.com search accepts in one query. Five locations therefore return up to 1,000 rows for five
requests.

**Can I get sold homes and rentals?** Yes. `listingType: "sold"` reads recently sold homes and
`listingType: "for_rent"` reads the rentals surface.

**Is `price` the sold price on a sold listing?** Yes, where Realtor.com discloses it. Non-disclosure
states such as Texas withhold sold prices, and those rows fall back to the last list price.

**Which countries does it support?** The United States only. This Actor targets `realtor.com`.

**How fresh is the data?** Every row carries a `collectedAt` timestamp and reflects what Realtor.com
showed at that moment. Schedule the Actor to re-run for a time series.

### Limitations

One request per location, returning up to 200 listings — this is not a whole-market crawler, so
narrow by ZIP code to widen coverage. Photos, listing descriptions, days on market, price history,
open-house times, HOA fees and tax records are out of scope, as are agent phone numbers and email
addresses.

### Free plan limit

Runs started from an Apify **free plan** stop at **250 requests and 250 results**, and the run
reports that it reached the limit. Any paid plan runs the full input and `maxItems` you set.

The limit exists because this Actor fetches through our own infrastructure, which Apify does not
cover for free-plan runs. It binds on requests as well as results so that a large input list cannot
spend those fetches for rows the run will not return.

# Actor input Schema

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

City and state, or ZIP codes.

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

Which Realtor.com search surface to read.

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

Global cap on dataset items. Runs started from an Apify free plan stop at 250 requests and 250 results; any paid plan runs the full amount.

## `concurrency` (type: `integer`):

Targets fetched in parallel.

## Actor input object example

```json
{
  "locations": [
    "Austin, TX"
  ],
  "listingType": "for_sale",
  "maxItems": 1000,
  "concurrency": 2
}
```

# Actor output Schema

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

Collect Realtor.com for-sale and rental listings by location.

## `summary` (type: `string`):

Item count, failure count and every target that failed, with its error.

# 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("usestring/realtor-listings").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("usestring/realtor-listings").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 usestring/realtor-listings --silent --output-dataset

```

## MCP server setup

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

```

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/ZRgDq4pGxHxbt6Cus/builds/vFnMnzSYSnx9IDVR6/openapi.json
