# Royal LePage Canada Scraper (`muhammadafzal/royal-lepage-canada-scraper`) Actor

Scrape public Royal LePage Canada property listings with prices, MLS numbers, addresses, photos, features, and rooms.

- **URL**: https://apify.com/muhammadafzal/royal-lepage-canada-scraper.md
- **Developed by:** [Muhammad Afzal](https://apify.com/muhammadafzal) (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 $1.00 / 1,000 royal lepage property records

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## Royal LePage Canada Scraper

Extract public Canadian real estate listings from Royal LePage into structured, agent-ready records for market research, lead qualification, property monitoring, and data analysis.

The Actor accepts Royal LePage city, province, filtered collection, pagination, and individual property URLs. It follows public result pages, deduplicates properties by Royal LePage listing ID, and can enrich each result from its detail page. The default input returns up to 25 current Toronto listings and normally completes well inside Apify’s automated health-test window.

### What it extracts

| Field | Description |
| --- | --- |
| `listingId`, `mlsNumber` | Royal LePage and public MLS identifiers |
| `title`, `url`, `status` | Listing title, canonical URL, and flags such as Open House |
| `price`, `priceCurrency` | Numeric asking price in CAD |
| `propertyType`, `transactionType` | House, condo, townhouse, land, sale, or rent when available |
| `streetAddress`, `city`, `province`, `postalCode` | Public listing location |
| `latitude`, `longitude` | Public embedded coordinates when available |
| `bedrooms`, `bathrooms` | Public bedroom and bathroom counts |
| `description`, `datePosted` | Property remarks and normalized posting date |
| `imageUrl`, `imageUrls` | Primary photo and up to 100 public photo URLs |
| `features` | Building/property label-to-value map such as heating, lot, parking, and ownership |
| `rooms` | Room names, levels, and metric/imperial dimensions |
| `brokerage` | Brokerage credited by the source |
| `sourceUrl`, `scrapedAt`, `detailLevel` | Provenance and extraction metadata |

The default dataset remains homogeneous: it contains only property records. Run diagnostics and warnings are stored separately in the `SUMMARY` key-value-store record.

### When to use it

Use this Actor to collect current public listings for Canadian housing research, compare asking prices across locations, monitor new inventory, assemble property prospect lists, or feed structured listing data to an AI agent or database.

Do not use it for authenticated sold or historical VOW data, personal account data, automated contact submissions, valuation guarantees, or redistribution that conflicts with Royal LePage, CREA DDF®, brokerage, privacy, or applicable legal terms. Public listing information can change and is not guaranteed accurate; independently verify any property before making a financial decision.

### Input

| Field | Default | Purpose |
| --- | --- | --- |
| `startUrls` | Toronto properties | One or more public Royal LePage collection/detail URLs |
| `maxResults` | `25` | Hard cap of delivered records and result events (1–1000) |
| `maxPages` | `5` | Collection-page pagination cap (1–100) |
| `includeDetails` | `true` | Fetch full descriptions, photos, features, rooms, and brokerage |
| `maxConcurrency` | `3` | Simultaneous request cap (1–10) |
| `proxyConfiguration` | disabled | Optional Apify Proxy configuration; Canada is the runtime default country |

Example input for full Vancouver property details:

```json
{
  "startUrls": [
    { "url": "https://www.royallepage.ca/en/bc/vancouver/properties/" }
  ],
  "maxResults": 50,
  "maxPages": 3,
  "includeDetails": true,
  "maxConcurrency": 3,
  "proxyConfiguration": { "useApifyProxy": false }
}
```

For the fastest price-and-address scan, set `includeDetails` to `false`. Summary-only records retain their canonical URL, asking price, visible property type, beds/baths, location, coordinates, and primary image, but fields available only on a detail page are `null`, empty arrays, or empty objects.

You can run it through the Apify API after replacing `ACTOR_ID` and your authentication method:

```bash
curl -X POST "https://api.apify.com/v2/acts/ACTOR_ID/runs?waitForFinish=300" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"startUrls":[{"url":"https://www.royallepage.ca/en/on/ottawa/properties/"}],"maxResults":10}'
```

Keep tokens in headers or Apify secrets rather than URLs, source files, or logs.

### Output example

```json
{
  "listingId": "29055207",
  "mlsNumber": "C13712690",
  "title": "137 BANNOCKBURN AVENUE, Toronto, Ontario, M5M 2N4",
  "url": "https://www.royallepage.ca/en/property/ontario/toronto/137-bannockburn-avenue/29055207/mlsc13712690/",
  "transactionType": "SALE",
  "propertyType": "House",
  "price": 3549000,
  "priceCurrency": "CAD",
  "city": "Toronto",
  "province": "ON",
  "postalCode": "M5M 2N4",
  "bedrooms": 6,
  "bathrooms": 7,
  "features": { "Heating Type": "Forced air", "Parking Type": "Garage" },
  "imageUrls": ["https://rlp.jumplisting.com/photos/example.jpg"],
  "detailLevel": "full"
}
```

### Pay per event pricing

| Event | Price | Charged when |
| --- | ---: | --- |
| Actor start | `$0.00005` | A run starts |
| Royal LePage property record | `$0.001` | One validated record is written to the default dataset |

A 25-record default run costs up to `$0.02505` in events. A 100-record run costs up to `$0.10005`. Empty, rejected, or fully blocked runs have no result events; the start event still applies. Apify automatically charges the synthetic dataset-item event, and the Actor does not add a duplicate manual charge. Your platform plan may separately govern infrastructure or proxy availability.

### Reliability and limits

The scraper starts with server-rendered HTML and JSON-LD because those public pages currently contain the advertised fields without browser execution. It uses realistic Canadian headers, cookie-preserving sessions, bounded retries, conservative concurrency, pagination/result caps, and deduplication. Optional Apify Proxy can be enabled if direct requests are challenged or rate-limited.

The Actor distinguishes four outcomes in `SUMMARY`: `DATA`, `EMPTY`, `BLOCKED`, and `REJECTED`. It preserves partial valid records when individual requests fail, records warnings outside the dataset, and stops systemic zero-result failure after a bounded number of errors. A zero-record result is not fabricated into a property row.

Royal LePage may change its markup, listing availability, access policy, or public fields. Some properties omit photos, coordinates, room dimensions, brokerage, or features, so those values are explicitly nullable. `maxResults` is an upper bound rather than a promise that the source has that many matching public properties.

### Legal and responsible use

Scrape only information you are authorized to collect and use. Respect Royal LePage’s terms, robots/access controls, CREA DDF® rights, listing brokerage rights, privacy law, and reasonable request rates. Do not use the Actor to access account-gated sold data, bypass CAPTCHAs or authentication, submit messages to agents, make eligibility or lending decisions, or republish protected listing content without permission. Property information is informational and should be independently verified.

For support, include the run ID, redacted input, expected outcome, and the affected public URL. Never include passwords, cookies, proxy credentials, or API tokens.

# Actor input Schema

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

Use this to scrape Royal LePage collection pages or individual property pages. Enter HTTPS royallepage.ca URLs, for example https://www.royallepage.ca/en/on/toronto/properties/. Defaults to Toronto listings; authenticated sold-data pages are not supported.

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

Use this to cap delivered property records and PPE result events. Enter 1–1000; the default is 25. This is not the number of collection pages.

## `maxPages` (type: `integer`):

Use this to limit pagination for each crawl. Enter 1–100; the default is 5. Direct property URLs do not consume this collection-page allowance.

## `includeDetails` (type: `boolean`):

Use this when you need descriptions, all photo URLs, feature tables, rooms, brokerage, coordinates, and posting dates. Enabled by default; disable it for faster summary-only collection scraping.

## `maxConcurrency` (type: `integer`):

Use this to control simultaneous page requests. Enter 1–10; the conservative default is 3 to reduce target load and rate-limit risk.

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

Use this if direct Royal LePage requests are blocked or rate-limited. The default makes direct requests; enable Apify Proxy and prefer Canada geography only when needed.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.royallepage.ca/en/on/toronto/properties/"
    }
  ],
  "maxResults": 25,
  "maxPages": 5,
  "includeDetails": true,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Royal LePage listing records in the default dataset.

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

Outcome, counts, warnings, access diagnostics, and estimated event cost.

# 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 = {
    "startUrls": [
        {
            "url": "https://www.royallepage.ca/en/on/toronto/properties/"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("muhammadafzal/royal-lepage-canada-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 = { "startUrls": [{ "url": "https://www.royallepage.ca/en/on/toronto/properties/" }] }

# Run the Actor and wait for it to finish
run = client.actor("muhammadafzal/royal-lepage-canada-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 '{
  "startUrls": [
    {
      "url": "https://www.royallepage.ca/en/on/toronto/properties/"
    }
  ]
}' |
apify call muhammadafzal/royal-lepage-canada-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,muhammadafzal/royal-lepage-canada-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/fHATSKNjSQoREftps/builds/OVfV8vXSPv461R4j8/openapi.json
