# Realtor.ca Scraper — Canada Real Estate Agent Leads & Phones (`juramoshkov/realtor-ca-agent-scraper`) Actor

Realtor.ca scraper for Canadian real estate leads — listing agent phone, office, and brokerage plus full property data (price, beds, baths, taxes, MLS®). Search by city, postal code, MLS® number, or URL. Lead generation ready. No API key, no run-start fee.

- **URL**: https://apify.com/juramoshkov/realtor-ca-agent-scraper.md
- **Developed by:** [Jura Moshkov](https://apify.com/juramoshkov) (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 $45.00 / 1,000 enriched listings

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.ca Scraper — Canada Real Estate Agent Leads & Phones

**Realtor.ca scraper for Canadian real estate leads.** Extract Realtor.ca (MLS®) property listings **plus the listing agent's name, phone, office, and brokerage** in one enriched row per property — ready for real estate lead generation, agent prospecting, and CRM enrichment across Canada. Search any Canadian city (2,600+ supported), coordinates, MLS® number, or a Realtor.ca URL. No browser automation, **no run-start fee**, and you pay only for successfully enriched results.

This Canadian real estate scraper turns Realtor.ca into a clean leads database: property data (price, beds, baths, MLS® number, photos) **and** contactable REALTORS® (agent phone, office, brokerage) in the same export — CSV, JSON, or Excel.

Looking for a **Realtor.ca agent leads scraper**, a **Canada MLS listing scraper**, or **REALTOR® phone numbers by city**? This actor does all three in one run.

### ✨ Why this Realtor.ca scraper

- 📇 **Agent contact in every row** — agent name, phone, office, and brokerage — not just property data.
- 🏠 **40+ property fields** — price, beds/baths, sqft, lot, year built, condo fees, taxes, MLS® number, days on market, photos, geo.
- 🔎 **4 input modes** — city (or coordinates) search, postal-code search, MLS®-number enrichment, or paste a Realtor.ca URL.
- 🍁 **2,600+ Canadian cities & 1,600+ postal (FSA) areas** resolved offline — or pass exact `latitude,longitude` for any location.
- 🇨🇦 **Canada-wide** — every province and territory, English and French listings.
- 💸 **Pay only for results** — no run-start fee; charged per successfully enriched property.
- 📤 **CRM-ready export** — flat rows to CSV / JSON / Excel, or straight into your workflow via Apify integrations.

### Input modes

| Mode | Use it to | Requires |
|---|---|---|
| `citySearch` | Discover all listings + agents in a city, or by `latitude,longitude` (main mode) | `cities` |
| `postalSearch` | Discover listings + agents by postal code (or bare FSA, e.g. `M5V`) | `postalCodes` |
| `mlsNumbers` | Enrich a known list of MLS® numbers | `mlsNumbers` |
| `url` | Scrape any Realtor.ca search/listing URL you paste | `startUrls` |

### Use cases

- **Canadian real estate lead generation** — build lists of contactable REALTORS® by city or area.
- **Agent prospecting & recruiting** — reach agents with their phone, office, brokerage, and live listing context.
- **Real estate market research** — price, location, property type, and days-on-market analysis across Canada.
- **CRM & spreadsheet enrichment** — push Realtor.ca property and agent data into your sales stack.

### Input

**Search by city** (main mode). You can list several cities, and each entry can be a city name or exact `latitude,longitude`:

```json
{
  "mode": "citySearch",
  "cities": ["Toronto", "Vancouver", "43.65,-79.38"],
  "listingStatus": "forSale",
  "minPrice": 400000,
  "maxPrice": 1200000,
  "beds": 2,
  "maxResults": 100
}
```

**Enrich known MLS® numbers:**

```json
{
  "mode": "mlsNumbers",
  "mlsNumbers": ["W1234567", "C9876543"],
  "maxResults": 2
}
```

**Scrape a Realtor.ca URL:**

```json
{
  "mode": "url",
  "startUrls": ["https://www.realtor.ca/map#view=list&Sort=6-D&GeoName=Toronto%2C+ON"],
  "listingStatus": "forSale",
  "maxResults": 100
}
```

### Output

One flat row per property. **Property fields:**

| Field | Type | Description |
|---|---|---|
| `mlsNumber` | string | MLS® listing number. |
| `url` | string | Listing URL on Realtor.ca. |
| `status` | string | Listing status (e.g. `for_sale`). |
| `price` | number | Listing price. |
| `currency` | string | Currency, usually CAD. |
| `beds` | number | Bedrooms. |
| `baths` | number | Bathrooms. |
| `sqft` | number | Interior square footage. |
| `lotSize` | string | Lot size when available. |
| `yearBuilt` | number | Year built. |
| `propertyType` | string | Property type (house, condo, etc.). |
| `streetAddress` / `city` / `province` / `postalCode` | string | Address parts. |
| `latitude` / `longitude` | number | Coordinates. |
| `condoFee` | number | Condo/maintenance fee when available. |
| `propertyTax` | number | Annual property tax when available. |
| `daysOnMarket` | number | Days on market. |
| `photoUrls` | array | Listing photo URLs. |
| `listedDate` | string | Listing date (ISO). |

**Agent / lead fields:**

| Field | Type | Description |
|---|---|---|
| `agentName` | string | Listing REALTOR® name. |
| `agentEmail` | string | Not published by Realtor.ca — always `null`. |
| `agentEmailMasked` | boolean | Always `false` (no email to mask). |
| `agentPhone` | string | Agent office phone. |
| `agentCellPhone` | string | Agent cell phone. |
| `officeName` | string | Real estate office. |
| `brokerName` | string | Brokerage name. |
| `agentProfileUrl` | string | Agent profile URL. |

**Meta:** `mode`, `searchCity`, `sourceUrl`, `scrapedAt` (ISO), `error` (null on success).

### Pricing

**No run-start fee. You are charged only for successfully enriched properties.**

| Apify plan | Price per enriched property |
|---|---|
| Free | $0.07 |
| Bronze | $0.06 |
| Silver | $0.05 |
| Gold | $0.045 |
| Platinum | $0.04 |
| Diamond | $0.04 |

Free runs are capped at 15 enriched properties. Agent name, phone, office, brokerage, and all property data are returned on every plan. Upgrade your Apify plan for uncapped runs.

### FAQ

#### Does it include the REALTOR® email?

No — Realtor.ca does not publish agent email addresses (`agentEmail` is always `null`). The contactable lead is the agent's **name, phone, office, and brokerage**, which are returned on every listing.

#### How do I get Canadian real estate agent leads by city?

Use `citySearch` mode with one or more `cities` (e.g. `Toronto`, `Vancouver`, `Calgary`) — 2,600+ Canadian cities are supported. You can also pass exact `latitude,longitude`. Each search returns listings with the agent's name, phone, office, and brokerage attached.

#### Can I search by postal code?

Yes. Use `postalSearch` mode with one or more `postalCodes` (a full code like `M5V 2T6` or a bare FSA like `M5V`). 1,600+ Canadian FSAs are supported offline.

#### Can I get REALTOR® contact details in bulk?

Yes. Run `citySearch` or `postalSearch` across multiple areas and export `agentName`, `agentPhone`, `agentCellPhone`, `officeName`, and `brokerName` to CSV or Google Sheets.

#### Do I need an API key?

No. Just set your input and run — the actor handles everything.

#### Is scraping Realtor.ca legal?

The actor returns publicly available listing data. You are responsible for using exported data in compliance with applicable laws (including Canadian privacy law such as PIPEDA and Canada's Anti-Spam Legislation / CASL), platform terms, MLS® rules, and outreach/marketing consent requirements.

### Coverage

Canada listings only (all provinces and territories).

# Actor input Schema

## `mode` (type: `string`):

What to scrape.

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

Canadian cities to search in citySearch mode (e.g. Toronto, Vancouver, Calgary). You can also pass exact coordinates as "latitude,longitude" (e.g. 43.65,-79.38).

## `postalCodes` (type: `array`):

Canadian postal codes (or bare FSA prefixes like M5V) to search in postalSearch mode.

## `mlsNumbers` (type: `array`):

MLS listing numbers for mlsNumbers mode.

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

Realtor.ca search or listing URLs for url mode.

## `listingStatus` (type: `string`):

Which listings to return: for sale, for rent, or sold.

## `maxResults` (type: `integer`):

Max enriched properties per run. Each property costs ~1 upstream API request.

## `minPrice` (type: `integer`):

Only return listings priced at or above this amount (CAD).

## `maxPrice` (type: `integer`):

Only return listings priced at or below this amount (CAD).

## `beds` (type: `integer`):

Only return listings with at least this many bedrooms.

## `baths` (type: `integer`):

Only return listings with at least this many bathrooms.

## `requestDelayMs` (type: `integer`):

Delay in milliseconds between requests. Increase for very large runs.

## Actor input object example

```json
{
  "mode": "citySearch",
  "cities": [
    "Toronto, ON"
  ],
  "postalCodes": [
    "M5V"
  ],
  "listingStatus": "forSale",
  "maxResults": 5,
  "requestDelayMs": 400
}
```

# Actor output Schema

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

No description

## `resultsCsv` (type: `string`):

No description

# 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": [
        "Toronto, ON"
    ],
    "postalCodes": [
        "M5V"
    ],
    "maxResults": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("juramoshkov/realtor-ca-agent-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": ["Toronto, ON"],
    "postalCodes": ["M5V"],
    "maxResults": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("juramoshkov/realtor-ca-agent-scraper").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 '{
  "cities": [
    "Toronto, ON"
  ],
  "postalCodes": [
    "M5V"
  ],
  "maxResults": 5
}' |
apify call juramoshkov/realtor-ca-agent-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

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