# HomeLight Scraper - Top Real Estate Agents & Licenses (`scrapersdelight/homelight-scraper`) Actor

Scrape HomeLight's curated top real estate agents for any US city: name, brokerage, state license number, lifetime transaction count, years of experience, average price point, rating, review count, awards, achievements, bio and photo. No login. HomeLight publishes no agent email or phone.

- **URL**: https://apify.com/scrapersdelight/homelight-scraper.md
- **Developed by:** [Scrapers Delight](https://apify.com/scrapersdelight) (community)
- **Categories:** Automation, Lead generation, Real estate
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.00 / 1,000 per agent 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/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

## HomeLight Scraper — top real estate agents by US city

Scrape [HomeLight](https://www.homelight.com)'s curated **top real-estate agent** directory for any
US city. HomeLight ranks agents on real transaction data, so a city page is a pre-filtered list of
the highest-performing agents in that market — not a raw roster.

Every agent comes back with their **state license number**, **lifetime transaction count**, **years
of experience**, **average price point**, brokerage, star rating, review count, awards, achievements
and full bio.

### What you get

| Field | Source | Notes |
|---|---|---|
| `agent_id`, `profile_url`, `canonical_profile_url` | list + profile | stable numeric HomeLight id — used for de-duplication |
| `name`, `brokerage` | list (+ profile fallback) | brokerage is ~70% filled from the list page, ~100% after profile enrichment |
| `rating`, `review_count` | list | HomeLight star rating |
| `list_rank` | list | the agent's position in HomeLight's ranking for that city |
| `bio`, `full_bio`, `photo_url` | list / profile | |
| `city`, `state_code`, `city_slug`, `service_area`, `metro_area_slug` | list / profile | |
| `license_number` | profile | **state real-estate license number** — the join key to state license registries |
| `transaction_count`, `years_experience`, `average_price_point`, `single_family_homes` | profile | |
| `education`, `awards`, `certifications[]`, `achievements[]`, `response_time` | profile | |
| `reviews[]` | profile | optional: author, rating, relationship, date, body |
| `city_market` | list | optional: agents in city, curated agents, avg commission rate, best month to sell, top vs average days-on-market and sell-to-list ratio, top neighbourhoods |

### Input

```json
{
  "cities": ["austin-tx", "miami-fl"],
  "maxAgents": 40,
  "includeAgentDetails": true,
  "includeReviews": false,
  "includeMarketContext": false,
  "expandNearbyCities": false
}
```

`cities` accepts a HomeLight slug (`austin-tx`), a plain name (`Austin, TX`) or a full city URL.
`expandNearbyCities` fans a seed city out across the nearby cities HomeLight lists on that page.

### Honest limits — read before you buy

- **No agent email and no direct agent phone.** HomeLight does not publish either anywhere on the
  city list or the agent profile; the only phone on a profile is HomeLight's own 1-888 referral
  line, so this actor deliberately does not emit it as agent contact data. Use
  `license_number` + `name` + `brokerage` to match agents against a state license registry or your
  own contact source. If you need contact details in the row, use a Realtor.com / Zillow agent
  scraper instead.
- **City-level slugs only.** Neighbourhood sub-paths (e.g. `austin-tx/zilker/...`) load fine but
  carry no agent list; the actor warns and skips them.
- **~40 agents per city, no pagination.** HomeLight caps the published list and `?page=2` returns
  page 1. Small markets legitimately return fewer (measured: Salt Lake City 9, Kansas City 18) and
  a few real city pages curate **nobody at all** (measured: Boise, ID = 0). Those finish as a
  successful run with 0 rows and nothing charged. Use `expandNearbyCities` to widen coverage
  across a metro.
- **HomeLight's own records occasionally disagree with themselves.** Measured 1 profile in 39: the
  city list advertises one name for an agent id and that id's profile page shows a different person
  (a reassigned or renamed account). The actor never overwrites one with the other — it returns
  `name` (from the city list), `profile_name` (from the profile page) and a `name_mismatch` flag so
  you can drop or reconcile those rows. Roughly 1 profile page in 40 also 404s; that row is still
  returned, list-only, with `detail_scraped: false`.
- **`city_latitude` / `city_longitude` is the city centroid**, one point shared by every agent on
  the page — it is *not* the agent's office location. Named accordingly.
- Coverage measured 2026-07-30: 20/20 city pages usable direct, 19/20 through Apify datacenter
  proxy (the one miss was a transient proxy reset, retried automatically); 20/20 profile pages
  parsed, `license_number` and `transaction_count` 100% filled on that sample.

### Pricing

Pay per event: one charge per agent returned, billed only for rows actually delivered.

### Legal

This actor reads a **public** business directory. You are responsible for complying with
HomeLight's Terms of Service and with the privacy/data-protection law that applies to you. The
records describe real-estate professionals acting in a business capacity; how you store and use
personal data is your responsibility.

# Actor input Schema

## `cities` (type: `array`):

HomeLight city slugs, e.g. 'austin-tx', 'miami-fl', 'new-york-ny'. 'Austin, TX' and a full city URL also work. City level only — neighbourhood sub-paths (e.g. austin-tx/zilker) carry no agent list on HomeLight and are skipped.

## `startUrls` (type: `array`):

Paste HomeLight city directory URLs directly, e.g. https://www.homelight.com/denver-co/top-real-estate-agents

## `maxAgents` (type: `integer`):

Stop after this many agents in total (0 = no limit). A HomeLight city page lists up to ~40 agents and has no pagination.

## `includeAgentDetails` (type: `boolean`):

Fetch each agent's profile page for state license number, lifetime transaction count, years of experience, average price point, education, awards, achievements, certifications and full bio. One extra request per agent.

## `includeReviews` (type: `boolean`):

Attach the agent's client reviews (author, rating, relationship, date, body). Requires agent profile details.

## `maxReviewsPerAgent` (type: `integer`):

Cap on reviews attached to each agent when reviews are enabled.

## `includeMarketContext` (type: `boolean`):

Attach HomeLight's city-level market stats to every row: agents in city, curated agents, average commission rate, best month to sell, top vs average days on market and sell-to-list ratio, top neighbourhoods.

## `expandNearbyCities` (type: `boolean`):

Queue the nearby-city slugs HomeLight lists on each city page, so one seed city fans out across its metro. Combine with 'Max agents' to keep runs bounded.

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

Proxy settings. Apify auto (datacenter) proxy is the measured-good default; the actor escalates to RESIDENTIAL automatically on a blocked retry.

## `requestConcurrency` (type: `integer`):

Max parallel profile requests. Keep modest to respect the site.

## Actor input object example

```json
{
  "cities": [
    "austin-tx",
    "miami-fl"
  ],
  "startUrls": [],
  "maxAgents": 20,
  "includeAgentDetails": true,
  "includeReviews": false,
  "maxReviewsPerAgent": 20,
  "includeMarketContext": false,
  "expandNearbyCities": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "requestConcurrency": 5
}
```

# Actor output Schema

## `records` (type: `string`):

The dataset of scraped HomeLight real-estate agents (one item per agent).

# 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 = {
    "cities": [
        "austin-tx",
        "miami-fl"
    ],
    "startUrls": [],
    "maxAgents": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapersdelight/homelight-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 = {
    "cities": [
        "austin-tx",
        "miami-fl",
    ],
    "startUrls": [],
    "maxAgents": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("scrapersdelight/homelight-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 '{
  "cities": [
    "austin-tx",
    "miami-fl"
  ],
  "startUrls": [],
  "maxAgents": 20
}' |
apify call scrapersdelight/homelight-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapersdelight/homelight-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/sCuENhpNebfg2roHw/builds/ckNTLGuOM3nn2Er2t/openapi.json
