# Canadian White Pages & Reverse Phone Lookup — Canada411 (`jungle_synthesizer/canada411-canadian-residential-phone-directory-scraper`) Actor

Search Canada's white pages by name and city, or run a reverse phone lookup by number, across every province. A Canadian people-search and phone-directory database returning full name, phone (E.164), address, postal code and geolocation for residential and business listings.

- **URL**: https://apify.com/jungle\_synthesizer/canada411-canadian-residential-phone-directory-scraper.md
- **Developed by:** [BowTiedRaccoon](https://apify.com/jungle_synthesizer) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.40 / 1,000 record scrapeds

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

## Canadian White Pages & Reverse Phone Lookup — Canada411

Search [Canada411](https://www.canada411.ca), the Canadian white pages, by name and city or run a reverse phone lookup by number. Returns full name, phone number (with E.164 formatting), street address, city, province, postal code, and geolocation for residential and business listings across all 13 provinces and territories.

***

### Canada411 Scraper Features

- Searches by name, optionally narrowed to a city and province
- Runs reverse phone lookups on any 10-digit Canadian number
- Returns normalised phone numbers in both display and E.164 format
- Parses full street address, city, province, and postal code per listing
- Includes latitude/longitude for every matched listing
- Covers residential and business entries in one search — no separate mode needed
- Classifies each result as residential or business based on the listing name

***

### Who Uses Canada411 Data?

- **Skip tracing and process serving** — locate a current address and phone number for a named individual before filing
- **Debt recovery** — cross-check a debtor's last known name against current Canada411 listings
- **Insurance claims** — verify a claimant's address and phone against a public directory record
- **B2C lead generation** — build contact lists by name or region for Canadian outreach campaigns
- **Reverse phone research** — identify who's calling from an unknown Canadian number
- **Data enrichment** — append name, address, and geolocation fields to an existing contact list

***

### How the Canada411 Scraper Works

1. Choose a search mode — name search or reverse phone lookup.
2. For a name search, give it a name and (optionally) a city and province. For a phone lookup, give it a 10-digit number.
3. The actor returns every matched listing with contact details, address, and geolocation, paginating automatically up to your `maxItems` limit.
4. A name search with no city/province returns matches from anywhere in Canada — narrow it if you're only after one region.

***

### Input

```json
{
  "searchMode": "name",
  "name": "Smith",
  "location": "Toronto ON",
  "maxItems": 50
}
```

| Field        | Type    | Default | Description                                                                                     |
|--------------|---------|---------|---------------------------------------------------------------------------------------------------|
| `searchMode` | String  | `name`  | `name` (search by name, optionally narrowed by city/province) or `phone` (reverse phone lookup). |
| `name`       | String  | —       | Name to search for — a surname or full name. Required for name mode.                              |
| `location`   | String  | —       | City and province to narrow a name search, e.g. `"Toronto ON"`. Optional — omit for all of Canada. |
| `phone`      | String  | —       | 10-digit Canadian phone number for a reverse lookup, e.g. `"4162430072"`. Required for phone mode. |
| `maxItems`   | Integer | `20`    | Maximum number of records to return for a name search.                                            |

Reverse phone lookup example:

```json
{
  "searchMode": "phone",
  "phone": "4162430072",
  "maxItems": 5
}
```

#### Resuming a large crawl

Every run emits a `resumeCursor` in its Output. If a large crawl stops before it finishes — because it hit `maxItems`, your spend cap (`maxTotalChargeUsd`), or was aborted — start a new run with **the same input** plus that `resumeCursor` to continue from where it left off. The crawl resumes from the queued work the previous run didn't reach.

- You are **not re-charged** for records the earlier run already delivered.
- Resume within your account's run-retention window — on the free tier, roughly your 10 most recent runs. Once the source run is pruned, its `resumeCursor` is no longer valid.
- `resumeCursor` is opaque — supply it unmodified.

***

### Canada411 Scraper Output Fields

```json
{
  "listing_id": "461547564",
  "listing_type": "residential",
  "full_name": "D Smith",
  "business_name": null,
  "phone": "(416) 239-3481",
  "phone_e164": "+14162393481",
  "street_address": "39 Jennings",
  "city": "Toronto",
  "province": "ON",
  "postal_code": "M6P 1M6",
  "latitude": 43.6607780456543,
  "longitude": -79.47310638427734,
  "listing_url": "https://www.canada411.ca/res/4162393481/D-Smith/461547564.html",
  "query_name": "Smith",
  "query_location": "Toronto ON",
  "query_phone": null,
  "result_rank": 5,
  "scraped_at": "2026-09-01T22:02:33.050Z"
}
```

| Field            | Type    | Description                                                                 |
|------------------|---------|-------------------------------------------------------------------------------|
| `listing_id`     | String  | Canada411's internal listing identifier.                                     |
| `listing_type`   | String  | `residential` or `business`, inferred from the listing name.                 |
| `full_name`      | String  | Name as listed.                                                              |
| `business_name`  | String  | Populated when `listing_type` is `business`, otherwise `null`.               |
| `phone`          | String  | Phone number as displayed, e.g. `(416) 239-3481`.                            |
| `phone_e164`     | String  | Phone number normalised to E.164, e.g. `+14162393481`.                       |
| `street_address` | String  | Street address, when listed.                                                 |
| `city`           | String  | City.                                                                        |
| `province`       | String  | Two-letter province/territory code, e.g. `ON`, `QC`, `BC`.                   |
| `postal_code`    | String  | Canadian postal code, when listed.                                           |
| `latitude`       | Number  | Listing latitude.                                                            |
| `longitude`      | Number  | Listing longitude.                                                           |
| `listing_url`    | String  | Direct URL to the listing on canada411.ca.                                   |
| `query_name`     | String  | The `name` your search requested (name mode only).                            |
| `query_location` | String  | The `location` your search requested (name mode only).                        |
| `query_phone`    | String  | The `phone` your search requested (phone mode only).                          |
| `result_rank`    | Integer | Position of this listing within its search's result set.                      |
| `scraped_at`     | String  | ISO 8601 timestamp of when the record was collected.                         |

**Data quality note:** Canada411 doesn't expose a machine-readable residential/business flag anywhere on the page, so `listing_type` and `business_name` are inferred from the listing name against a set of common business keywords. Treat them as a best-effort classification rather than a source-verified field — everything else on the record comes directly from the listing.

***

### FAQ

#### How do I scrape Canada411?

Give the Canada411 scraper a name (and optionally a city/province), or a 10-digit phone number for a reverse lookup. It returns every matched listing with contact details, address, and geolocation — no account or API key needed.

#### How much does this actor cost to run?

Pricing follows Apify's pay-per-event model — see the Pricing tab on the actor page for the current rate per record. Results are paginated, so a broad name search across all of Canada costs more than a narrow one scoped to a city.

#### Can I search for a name across the whole country?

Yes — omit `location` and a name search returns matches from anywhere in Canada. Add a city and province (e.g. `"Toronto ON"`) to narrow it.

#### Does this actor cover business listings, or just residential?

Both. A single name search returns residential and business entries together; `listing_type` on each record tells you which is which.

#### What happens if a reverse phone lookup finds no match?

The run finishes with zero records for that query — Canada411 has no listing for the number you searched.

***

### Need More Features?

Need custom fields, filters, or a different target site? [File an issue](https://console.apify.com/actors/issues) or get in touch.

### Why Use This Canada411 Scraper?

- **Full national coverage** — one actor for every province and territory, both residential and business listings.
- **More than a name lookup** — returns E.164-normalised phone numbers and a latitude/longitude for every match, plus a first-class reverse phone lookup mode, not just name search.
- **Clean, structured output** — consistent field names across every record, so you spend less time cleaning data and more time using it.

# Actor input Schema

## `sp_intended_usage` (type: `string`):

What will this data feed? E.g. lead lists, KYB checks, price tracking.

## `sp_improvement_suggestions` (type: `string`):

Provide any feedback or suggestions for improvements.

## `sp_contact` (type: `string`):

We'll personally help with your use case. No spam.

## `resumeCursor` (type: `string`):

Leave empty for a fresh crawl. To CONTINUE a previous run where it stopped — without paying again for records you already received — paste the `resumeCursor` value from that run's Output (the run's OUTPUT key). Resume promptly: the previous run's data expires with your account's retention window (free tier: your ~10 most recent runs).

## `searchMode` (type: `string`):

Search mode: "name" (search by name, optionally narrowed by city + province) or "phone" (reverse phone lookup by a 10-digit number).

## `name` (type: `string`):

Name to search for — a surname (e.g. "Smith") or full name (e.g. "John Smith"). Required for name mode.

## `location` (type: `string`):

City and province to narrow a name search (e.g. "Toronto ON"). Optional — omit to search all of Canada. Used only in name mode.

## `phone` (type: `string`):

10-digit Canadian phone number for a reverse lookup (e.g. "4162430072"). Required for phone mode.

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

Maximum number of records to return for a name search. Results are paginated 25 per page, and each page fetch is a billed request.

## Actor input object example

```json
{
  "sp_intended_usage": "Describe your intended use...",
  "sp_improvement_suggestions": "Share your suggestions here...",
  "sp_contact": "Share your email here...",
  "searchMode": "name",
  "name": "Smith",
  "location": "Toronto ON",
  "maxItems": 20
}
```

# Actor output Schema

## `results` (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 = {
    "sp_intended_usage": "Describe your intended use...",
    "sp_improvement_suggestions": "Share your suggestions here...",
    "sp_contact": "Share your email here...",
    "searchMode": "name",
    "name": "Smith",
    "location": "Toronto ON",
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("jungle_synthesizer/canada411-canadian-residential-phone-directory-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 = {
    "sp_intended_usage": "Describe your intended use...",
    "sp_improvement_suggestions": "Share your suggestions here...",
    "sp_contact": "Share your email here...",
    "searchMode": "name",
    "name": "Smith",
    "location": "Toronto ON",
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("jungle_synthesizer/canada411-canadian-residential-phone-directory-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 '{
  "sp_intended_usage": "Describe your intended use...",
  "sp_improvement_suggestions": "Share your suggestions here...",
  "sp_contact": "Share your email here...",
  "searchMode": "name",
  "name": "Smith",
  "location": "Toronto ON",
  "maxItems": 20
}' |
apify call jungle_synthesizer/canada411-canadian-residential-phone-directory-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jungle_synthesizer/canada411-canadian-residential-phone-directory-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/1iAEf6YvjPRNC59rX/builds/ZoRjjE16tQX3IFDS1/openapi.json
