# Realtor Email Scraper (Cheap) (`data_api/realtor-email-scraper-cheap`) Actor

Realtor contact email extractor that fetches agent names, emails, phones, and office details from Realtor.com listings using property IDs or US addresses, returning one flat row per agent.

- **URL**: https://apify.com/data\_api/realtor-email-scraper-cheap.md
- **Developed by:** [Data API](https://apify.com/data_api) (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

from $1.99 / 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 Email Scraper

![Realtor Email Scraper](cover.jpg)

Realtor.com shows you the listing agent's name and a contact button, but pulling the actual email, phone, and brokerage for a list of properties means clicking through every page by hand. This scraper skips that. Give it a US address or a Realtor.com listing ID and it returns the listing agent's email, phone, name, license, and brokerage details next to the property's price, beds, baths, and address — one flat row per agent. Mix addresses and IDs in the same run, feed it one property or a few thousand, and pay only for what you scrape.

### What you get

Every agent on a listing becomes its own row, with the property details repeated on each row so the dataset stands on its own. A listing with two agents gives you two rows; a listing with no agent still writes a row so nothing is quietly dropped. Three groups of data:

- **Agent contact** — `agentFullName`, `agentEmailAddress`, `agentPhoneNumber`, `agentRole`, `agentWebsite`, `agentLicenseId`
- **Brokerage** — `brokerageName`, `brokerageEmail`, `brokeragePhone`, `brokerageCity`, `brokerageState`
- **Property** — `lookupValue`, `listingId`, `streetAddress`, `cityName`, `stateCode`, `postalCode`, `askingPrice`, `bedroomCount`, `bathroomCount`, `floorAreaSqft`, `propertyCategory`

### Quick start

1. Hit **Try for free** and open the input form.
2. Paste your US addresses or numeric listing IDs into **Addresses or listing IDs**, one per line. Both kinds work together.
3. Pick a proxy type and set a **Results limit** if you want to cap the run.
4. Press **Start**, then export the results as JSON, CSV, Excel, or XML when it finishes.

![How it works](how-it-works.jpg)

### Use cases

- **Listing agent outreach** — build mailing lists of agents tied to specific properties for new-listing announcements or open-house invites
- **Mortgage and lender prospecting** — reach agents on fresh or price-reduced listings to introduce lending and referral programs
- **CRM enrichment** — append verified agent emails and phones to property records, keyed on an address or a listing ID
- **Brokerage research** — see which offices list what, where, and at what price across a market
- **Investor sourcing** — find the agents behind distressed or reduced listings to open acquisition conversations
- **Vendor and partner marketing** — collect agent contacts to pitch software, inspection, staging, or photography services

### Input

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `lookupList` | array of strings | Yes | US property addresses or numeric Realtor.com listing IDs, one per line. Mix both in the same run. |
| `resultsLimit` | integer | No | How many properties to handle per run. Use `0` for no cap. Default `0`. |
| `requestTimeoutSeconds` | integer | No | Seconds to wait on each HTTP request before moving on. Default `45`. |
| `proxyConfiguration` | object | No | Proxies that route your requests. Defaults to US; switch to Residential if you hit repeated failures. |

#### Example input

```json
{
    "lookupList": [
        "1200 Brickell Bay Dr, Miami, FL 33131",
        "742 Evergreen Ter, Springfield, IL",
        "9087654321"
    ],
    "resultsLimit": 0,
    "requestTimeoutSeconds": 45,
    "proxyConfiguration": { "useApifyProxy": true, "apifyProxyCountry": "US" }
}
```

### Output

You get one row per listing agent. The property fields repeat on every agent row, so a listing with two agents produces two rows that share the same property details. A property that resolves but lists no agent still writes a row with the property data and blank agent fields, and anything that fails to resolve writes a row carrying your original lookup plus an `errorMessage`.

#### Example output

```json
{
    "lookupValue": "1200 Brickell Bay Dr, Miami, FL 33131",
    "listingId": "3055678901",
    "streetAddress": "1200 Brickell Bay Dr",
    "cityName": "Miami",
    "stateCode": "FL",
    "postalCode": "33131",
    "askingPrice": 1250000,
    "bedroomCount": 3,
    "bathroomCount": 2,
    "floorAreaSqft": 1900,
    "propertyCategory": "condo",
    "agentFullName": "Carlos Mendez",
    "agentEmailAddress": "carlos@miamiproperty.com",
    "agentRole": "seller",
    "agentPhoneNumber": "3055551234",
    "agentWebsite": "https://www.miamiproperty.com",
    "agentLicenseId": "FL-334512",
    "brokerageName": "Miami Property Group",
    "brokerageEmail": "info@miamiproperty.com",
    "brokeragePhone": "3055550000",
    "brokerageCity": "Miami",
    "brokerageState": "FL",
    "errorMessage": ""
}
```

#### Output fields

| Field | Type | Description |
|-------|------|-------------|
| `lookupValue` | string | The address or listing ID exactly as you entered it. |
| `listingId` | string | The numeric Realtor.com listing ID your input resolved to. |
| `streetAddress` | string | Full street address of the property. |
| `cityName` | string | City the property sits in. |
| `stateCode` | string | Two-letter state code, such as TX, FL, or CA. |
| `postalCode` | string | ZIP or postal code of the property. |
| `askingPrice` | number | Price the property is currently listed at. |
| `bedroomCount` | number | Number of bedrooms. |
| `bathroomCount` | number | Number of bathrooms. |
| `floorAreaSqft` | number | Interior floor area in square feet. |
| `propertyCategory` | string | Property kind, such as single\_family, condo, or multi\_family. |
| `agentFullName` | string | Full name of the listing agent. |
| `agentEmailAddress` | string | Public email address for the agent. |
| `agentRole` | string | The agent's role on this listing, such as seller or buyer. |
| `agentPhoneNumber` | string | Direct phone number for the agent. |
| `agentWebsite` | string | Website URL for the agent or brokerage. |
| `agentLicenseId` | string | State license number held by the agent. |
| `brokerageName` | string | Name of the brokerage office. |
| `brokerageEmail` | string | Public email address for the brokerage office. |
| `brokeragePhone` | string | Phone number for the brokerage office. |
| `brokerageCity` | string | City the brokerage office is based in. |
| `brokerageState` | string | State code of the brokerage office. |
| `errorMessage` | string | Set when a property could not be fetched; empty on success. |

### Tips for best results

- **Keep proxies on US.** Realtor.com leans heavily toward US traffic, so the input ships with `apifyProxyCountry: "US"`. If a large batch throws frequent failures, switch the proxy to Residential.
- **Mix addresses and IDs freely.** A plain address like `"123 Main St, Austin TX"` and a numeric ID like `"9087654321"` both work in the same `lookupList`. The actor decides which is which on its own.
- **Watch the `errorMessage` field.** Any row with a non-empty `errorMessage` means that input did not resolve. Filter those out, then re-run them in a smaller batch.
- **Cap test runs.** Set `resultsLimit` to a small number while you confirm the output fits your pipeline, then drop it back to `0` for the full list.
- **Pipe it straight into your tools.** When a run finishes, the Apify Google Sheets integration or a webhook can push agent contacts into HubSpot, Mailchimp, Airtable, or your outreach platform.

### How can I use Realtor.com agent data?

**How can I use the Realtor Email Scraper to build a list of listing agents in a market?**
Paste a batch of addresses or Realtor.com listing IDs for the area you care about and each one comes back with the listing agent's email, phone, name, and brokerage next to the property's price and location. Group the rows by city or ZIP to see which agents and offices are active where, and you have a ready contact list for outreach.

**How can I find a real estate agent's email from a property address?**
Drop a single US address into `lookupList`. The scraper resolves it to a Realtor.com listing, reads the advertiser data, and returns the agent's public email, direct phone, license, and brokerage in one row — no Realtor.com login or API key needed.

**How can I enrich my CRM with Realtor.com agent contacts at scale?**
Already have a list of addresses or listing IDs? Set `resultsLimit` to `0` and feed the whole list. Every property returns one row per agent with verified contact fields, so you can match results back to your records on the `lookupValue` and append fresh agent emails and phone numbers in bulk.

**How do I export the scraped Realtor.com data to CSV or Google Sheets?**
After a run finishes, open the dataset and export to CSV, JSON, or Excel in one click, or connect the Apify Google Sheets integration to send agent contacts straight into a sheet your team already works from.

### Is it legal to scrape data?

Our actors are ethical and do not extract any private user data, such as email addresses or private contact information. They only extract what the user has chosen to share publicly. We therefore believe that our actors, when used for ethical purposes by Apify users, are safe.

However, you should be aware that your results could contain personal data. Personal data is protected by the GDPR in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

You can also read Apify's blog post on the [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

### Support

Questions, feature requests, or a field you'd like added? Reach out at <data.apify@proton.me> and we'll get back to you.

# Actor input Schema

## `searchQueries` (type: `array`):

List of US property addresses or numeric Realtor.com property IDs. Mix both in the same run. Enter one per line.

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

Maximum number of properties to process per run. Set to 0 for no limit.

## `timeoutSecs` (type: `integer`):

Maximum total run time in seconds. Increase for large batches.

## `requestTimeoutSecs` (type: `integer`):

How long to wait for each individual HTTP request before moving on.

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

Select proxies to use for requests. Helps avoid IP blocking and rate limits. Datacenter proxies are fastest; Residential proxies are harder to detect.

## Actor input object example

```json
{
  "searchQueries": [
    "890 Brickell Ave, Miami, FL 33131",
    "4660981796",
    "39 Post Ln, Staten Island"
  ],
  "maxItems": 0,
  "timeoutSecs": 30000,
  "requestTimeoutSecs": 30,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyCountry": "US"
  }
}
```

# 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 = {
    "searchQueries": [
        "890 Brickell Ave, Miami, FL 33131",
        "4660981796",
        "39 Post Ln, Staten Island"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("data_api/realtor-email-scraper-cheap").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 = {
    "searchQueries": [
        "890 Brickell Ave, Miami, FL 33131",
        "4660981796",
        "39 Post Ln, Staten Island",
    ],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("data_api/realtor-email-scraper-cheap").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQueries": [
    "890 Brickell Ave, Miami, FL 33131",
    "4660981796",
    "39 Post Ln, Staten Island"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyCountry": "US"
  }
}' |
apify call data_api/realtor-email-scraper-cheap --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=data_api/realtor-email-scraper-cheap",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/bUECQvoNErbXI5Qxp/builds/pH5VtU2n9sepeJkMr/openapi.json
