# Zillow Agent Leads — Emails, Phones & Sales History (`afanasenko/zillow-agent-leads-scraper`) Actor

Zillow real-estate agent leads by area or name: email, phone, brokerage, licences, live listing counts, recent sales and reviews. Filter by production, review count, Premier Agent status, and team vs solo. Export to CSV, JSON or Excel.

- **URL**: https://apify.com/afanasenko/zillow-agent-leads-scraper.md
- **Developed by:** [Andrey Afanasenko](https://apify.com/afanasenko) (community)
- **Categories:** Lead generation, Real estate
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $35.00 / 1,000 agents

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/actors/running/actors-in-store.md#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

## Zillow Agent Leads — Emails, Phones & Sales History

[![Apify Actor](https://img.shields.io/badge/Apify-Actor-blue)](https://apify.com/afanasenko/zillow-agent-leads-scraper)

> **Give it a ZIP code or a city and get back the real-estate agents working there — with their email address, phone number, brokerage, and how much they actually sell.**

Most agent lists tell you who exists. This one tells you who is worth calling: how many homes each agent closed in the last twelve months, what price band they work in, how many listings they have live right now, and how many reviews they have earned.

Every agent is returned as one flat row, ready to paste into a CRM or a mail-merge.

***

### 🎯 What it does

You give the Actor areas (`78704`, `Austin, TX`) or names (`Eric Bramlett`). For each agent it finds, it returns three layers of information in a single row:

| Layer | What you get |
|---|---|
| **Contact** | Name, brokerage, email, cell and business phone, business address, profile photo, profile link |
| **Production** | Sales in the last 12 months, sales in the area you searched, lifetime sales, price band handled, live listing count, rental listing count, and a sample of the five most recent sales with dates and addresses |
| **Standing** | Review count and average, reviews split by what the client hired them for, Premier Agent status, Top Agent badge, years in the industry, specialities, languages, licences, service areas |

Zillow lists both individual agents and teams. Every row says which it is (`isTeam`), and a team row also carries the roster of its named members with their own review counts — so you can decide whether to approach the brand or the person.

***

### 📦 Output sample

One real row, trimmed for length:

```json
{
  "agentName": "Eric Bramlett",
  "brokerageName": "Bramlett Partners",
  "email": "eric+1@bramlett.me",
  "phoneCell": "(512) 872-3272",
  "businessStreet": "6850 Austin Center Blvd, Bldg II | Ste 180",
  "businessCity": "Austin",
  "businessState": "TX",
  "businessZip": "78731",
  "isTeam": true,
  "teamMemberCount": 106,
  "teamMembers": [
    { "name": "Will Mackintosh", "screenName": "willmackintosh", "reviewCount": 165, "reviewAverage": 5 },
    { "name": "Kasey Gilliam", "screenName": "kaseyg16", "reviewCount": 114, "reviewAverage": 5 }
  ],
  "salesLast12Months": 801,
  "salesInSearchArea": 3316,
  "salesAllTime": 5771,
  "priceRange": "$100K - $9.9M",
  "activeListingCount": 156,
  "rentalListingCount": 24,
  "recentSoldSample": [
    { "zpid": 29492948, "soldDate": "8/21/2026", "price": "--", "address": "1100 S Trace Dr, Austin, TX, 78745", "represented": "Seller" }
  ],
  "reviewCount": 2191,
  "reviewAverage": 5,
  "reviewBreakdown": {
    "All reviews": 2191,
    "Helped me buy": 1198,
    "Helped me sell": 414,
    "Helped me buy and sell": 215
  },
  "isPremierAgent": false,
  "yearsInIndustry": 23,
  "specialties": ["Buyer's Agent", "Listing Agent", "Relocation", "Property Management"],
  "serviceAreas": ["Austin, TX", "Round Rock, TX", "Cedar Park, TX", "Lakeway, TX"],
  "profileUrl": "https://www.zillow.com/profile/ericbramlett",
  "enrichmentStatus": "enriched"
}
```

A field is `null` when the agent's profile does not publish it. Nothing is padded with a placeholder.

***

### ⚡ Quick start

1. Open the **Input** tab.
2. Put one area per line under **Areas to search** — a ZIP code like `78704` or a city like `Austin, TX` both work.
3. Leave **Max agents to return** at 25 for a first look.
4. Press **Start**.
5. Open the **Storage → Dataset** tab and switch the view to **Contacts** for a clean outreach list, or **Full details** for everything.

Minimal input:

```json
{
  "agentLocations": ["78704"],
  "maxAgentsPerSearch": 25
}
```

***

### 🧭 When to use it

- **Mortgage brokers and lenders** — find the agents who actually close deals in your lending area, ranked by sales in the last twelve months rather than by who paid for placement.
- **Title, escrow, insurance and home-service vendors** — build a territory list of agents with live listings, so you approach people who have business to refer this month.
- **Brokerage recruiters** — see a competitor's roster, each member's review count, and how long they have been in the industry, before you make an approach.
- **Real-estate SaaS and marketing agencies** — filter to Premier Agents, the segment already spending money on lead generation.
- **Investors and wholesalers** — find the listing agents who move the most property in a ZIP, and reach them directly rather than through a form.
- **Market researchers** — measure how many agents compete in an area, what price bands they work in, and how concentrated production is.

***

### 🛠 Input

#### 🎯 Search agents

| Field | What it does |
|---|---|
| `agentLocations` | One area per line. ZIP code or `City, State`. |
| `agentNames` | One name per line. Partial names match broadly. |
| `maxAgentsPerSearch` | Hard ceiling on agents returned and charged. `0` = no ceiling. |

You can combine areas and names in one run. Results are deduplicated, so an agent found by both is returned once and charged once.

#### 🔬 Narrow the list

| Field | What it does |
|---|---|
| `minSalesLast12Months` | Skip agents below this recent production. |
| `minReviewCount` | Skip agents with fewer published reviews. |
| `teamFilter` | Both, solo agents only, or teams only. |
| `onlyWithEmail` | Skip agents whose profile publishes no email. |
| `onlyPremierAgents` | Keep only agents who pay Zillow for placement. |

**Every filter runs before the agent is charged.** An agent you filter out costs you nothing — the run only bills for rows that reach your dataset.

***

### 💰 Pricing

This Actor uses **pay per event**. One event, `Agent`, fires once per agent that lands in your dataset.

| Your Apify plan | Price per agent |
|---|---|
| Free | $0.05 |
| Bronze | $0.045 |
| Silver | $0.04 |
| Gold | $0.035 |
| Platinum | $0.032 |
| Diamond | $0.03 |

A run that returns nothing costs nothing. Agents removed by your filters are not charged. There is no per-request fee and no subscription on top.

***

### 🆓 Free vs paid plan

| | Free plan | Paid plan |
|---|---|---|
| Agents per run | 10 | Unlimited (or your own ceiling) |
| Contact details | ✓ | ✓ |
| Production and listing data | ✓ | ✓ |
| Filters | ✓ | ✓ |

On the free plan the agents the cap held back are still delivered as rows, with every looked-up column empty and a `whyNotEnriched` note — so you can always see how many more the search matched.

***

### 🧪 Filter recipes

**Top producers in a ZIP, contactable by email**

```json
{ "agentLocations": ["78704"], "minSalesLast12Months": 20, "onlyWithEmail": true }
```

**Solo agents to recruit, established but not enormous**

```json
{ "agentLocations": ["Austin, TX"], "teamFilter": "solo", "minReviewCount": 15 }
```

**Agents already buying leads**

```json
{ "agentLocations": ["Phoenix, AZ"], "onlyPremierAgents": true }
```

***

### 📡 Live status & storage records

While a run is going, the **Live Status** link on the run page shows agents found, agents saved, spend so far and the free-plan ceiling. Three records are written to the run's key-value store:

| Record | What it holds |
|---|---|
| `RUN_SUMMARY` | How the run ended, agents saved, paid events fired, wall-clock seconds |
| `USER_MESSAGE` | A plain-language note when a run needs explaining — an empty result, a free-plan cap, a demo run |
| `FREE_LIMITS_APPLIED` | Which free-plan ceilings changed this run's output |

***

### 🤖 Programmatic / API use

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('afanasenko/zillow-agent-leads-scraper').call({
    agentLocations: ['78704', 'Austin, TX'],
    maxAgentsPerSearch: 50,
    minSalesLast12Months: 10,
    onlyWithEmail: true,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0].email, items[0].salesLast12Months);
```

***

### ❓ FAQ

#### Is it legal to scrape this data?

The Actor reads agent profile pages that Zillow publishes openly, with no login. It collects business contact details that agents choose to publish so clients can reach them. How you use those details is your responsibility — outreach in the US is governed by CAN-SPAM, the TCPA and state law.

#### Do I get an email address for every agent?

Most agents publish one, but not all. Set `onlyWithEmail` to `true` and rows without an email are skipped before they are charged.

#### What is the difference between a team row and an agent row?

Zillow lists teams and brokerages alongside individuals. On a team row, `isTeam` is `true` and the sales figures belong to the whole team, not to one person. The `teamMembers` array names the individuals, so you can search them by name afterwards if you need per-person numbers.

#### Why does one agent show a huge lifetime sales number?

Because that row is a brokerage. Check `isTeam` before comparing production between rows.

#### What does `price` = `--` mean in the recent-sales sample?

The sale is recorded but its price is not published. The date, address and which side the agent represented are still there.

#### Can I get every listing an agent has ever sold?

Not in one run, by design. A large brokerage has tens of thousands of sold listings and pulling them all would cost far more than the agent row is worth. You get the counts, plus the five most recent sales.

#### How do I search a whole metro area?

Put several ZIP codes on separate lines under **Areas to search**. Results are deduplicated across all of them.

#### Why did my run return no agents?

Either the area matched nobody, or every agent found was removed by your filters. The `USER_MESSAGE` record in the run's storage says which. An empty run is never charged.

#### Can I schedule this?

Yes. Use Apify's scheduler to re-run a territory list weekly and diff the results to see who is new.

***

### 🔗 Related actors

| Actor | What it does |
|---|---|
| [Zillow Property & Agent Data Scraper](https://apify.com/afanasenko/zillow-property-agent-data-scraper) | Property listings by ZIP, ZPID or URL, with the listing agent's contact details |
| [Zillow Search by ZIP](https://apify.com/afanasenko/zillow-zip-search) | Focused ZIP-code property search |
| [Zillow Search by URL](https://apify.com/afanasenko/zillow-url-search) | Paste a Zillow search URL and get the listings behind it |
| [Zillow MCP Server](https://apify.com/afanasenko/zillow-mcp-server) | The same Zillow property data as tools for an AI agent |

***

### 🛟 Support & feedback

Something missing, wrong, or slow? Open an issue on the **Issues** tab of this Actor. Every one is read, and a short note tends to ship a fix within a few days.

***

### ⚖️ Disclaimer

This Actor collects publicly available information from agent profile pages. It is not affiliated with, endorsed by, or connected to Zillow Group, Inc. Use the data in line with applicable law and with the terms of the sites involved.

# Actor input Schema

## `agentLocations` (type: `array`):

One area per line. Both a ZIP code and a "City, State" pair work — for example 78704 or Austin, TX. Agents are returned in the order Zillow ranks them for that area.

## `agentNames` (type: `array`):

One name per line. Partial names work and return everyone who matches, so "Smith" returns many agents while a full name narrows it to a few.

## `maxAgentsPerSearch` (type: `integer`):

Hard ceiling on how many agents this run returns and charges for. 0 means no ceiling. On the free plan the ceiling is 10 agents per run whatever you set here.

## `minSalesLast12Months` (type: `integer`):

Skip agents who closed fewer sales than this over the past year. 0 means no minimum. Agents who publish no recent-sales figure are skipped when this is above 0.

## `minReviewCount` (type: `integer`):

Skip agents with fewer published reviews than this. 0 means no minimum.

## `teamFilter` (type: `string`):

Zillow lists both individuals and teams. A team's sales figures belong to the whole team, so choose Solo agents only when you need per-person numbers.

## `onlyWithEmail` (type: `boolean`):

Skip agents whose profile publishes no email address.

## `onlyPremierAgents` (type: `boolean`):

Premier Agents pay Zillow for placement, which makes them the segment most likely to buy marketing services.

## Actor input object example

```json
{
  "agentLocations": [],
  "agentNames": [],
  "maxAgentsPerSearch": 25,
  "minSalesLast12Months": 0,
  "minReviewCount": 0,
  "teamFilter": "any",
  "onlyWithEmail": false,
  "onlyPremierAgents": false
}
```

# Actor output Schema

## `liveStatus` (type: `string`):

No description

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

No description

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

Aggregate run statistics — counts, mode, paid events fired, wall-clock time.

## `userMessage` (type: `string`):

Onboarding tip, paid-plan welcome, or diagnostic message — only present when the run has something to surface.

## `freeLimitsApplied` (type: `string`):

Free-tier caps that affected this run. Empty if no caps applied or user is on a paid plan.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("afanasenko/zillow-agent-leads-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("afanasenko/zillow-agent-leads-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 '{}' |
apify call afanasenko/zillow-agent-leads-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,afanasenko/zillow-agent-leads-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/QBJFFPlvkFp5qy2Sf/builds/xZpgRk3gdeoFwHzVX/openapi.json
