# YellowPages.ca Scraper & API - Canada Business Leads, Phones (`rel8ble/yellowpages-ca-scraper`) Actor

YellowPages.ca scraper and API: Canadian business leads by search term and city (plumber, Toronto ON) or yellowpages.ca URLs. One result = one business: name, phones, website, address, rating, hours, services, social links. No login, no start fee. $0.70 per 1,000, lowest paid YellowPages.ca price.

- **URL**: https://apify.com/rel8ble/yellowpages-ca-scraper.md
- **Developed by:** [Giovanni Rich](https://apify.com/rel8ble) (community)
- **Categories:** Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.70 / 1,000 results

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## YellowPages.ca Scraper & API - Canada Business Leads, Phones

This **YellowPages.ca scraper** turns yellowpages.ca, Canada's biggest business directory, into clean **B2B lead lists**: give it search terms like `plumber`, `dentist` or `restaurants` and Canadian cities like `Toronto ON` or `Montreal QC`, and get one row per business with **name, all phone numbers, website, full address, categories, rating and reviews, opening hours, social links, services, service areas, languages, payment methods and coordinates**, as JSON, CSV or Excel.
Use it as a **YellowPages Canada API**, a **Canadian business directory scraper**, a **Canada lead generation** tool for cold outreach and sales prospecting, or a **Pages Jaunes Canada extractor** from your own code, Make, Zapier or n8n.

It reads the public search and business pages over plain HTTP, with **no headless browser and no login**. 300 businesses with hours, coordinates and social links take about 20 seconds.

### How to use

1. Type **Search terms**, one per line: `plumber`, `dentist`, `restaurants`, `Electricians & Electrical Contractors`, `avocat` ... (English or French, categories or business names).
2. Type **Locations** as `City PROVINCE`, one per line: `Toronto ON`, `Montreal QC`, `Vancouver BC`, `Calgary AB`. Every term is searched in every location.
3. Or paste **YellowPages.ca URLs**: search pages (`https://www.yellowpages.ca/search/si/1/plumber/Ottawa+ON`) and single business pages (`https://www.yellowpages.ca/bus/Ontario/Toronto/<name>/<id>.html`).
4. Set **Max businesses per search term + location** (0 = every listing), keep **Open each business page** on for hours, coordinates and social links, and add filters if you only want businesses with a website, a phone number or a minimum rating.
5. Click **Start** and download the leads from the **Output** tab, or fetch them through the Apify API.

### What you get

- **Contact**: business name, every phone number on the listing (plus the main one in +1 format), website (the real URL, not YellowPages' redirect), Facebook / Instagram / X / LinkedIn links.
- **Address**: street with unit, city, province, postal code, one-line address, latitude and longitude.
- **Reputation**: average YellowPages rating and number of reviews.
- **Business profile**: main category and all categories, products and services, specialties, features, service areas, languages spoken, rates, brands, professional memberships (BBB ...), payment methods, opening hours per day, open-now text, description, logo.
- **Ad signals**: `sponsored` (paid top placement) and `listingTier` (YellowPages advertising tier), handy for spotting businesses that already pay for marketing.
- **Search context**: the search term and location that found it, its position in the results and how many results that search has.

### Sample output

Real rows from the Store demo (`electrician` in `Toronto ON`, from `sample-output.json`), a few of the 42 fields:

| name | category | phone | website | city | rating |
|---|---|---|---|---|---|
| Expert GTA Electric | Electricians & Electrical Contractors | 647-846-8903 | expertgta.com | East York, ON | 5 (11) |
| Safe Electrical Solutions | Electricians & Electrical Contractors | 647-846-2663 | safeelectricalsolutions.ca | Toronto, ON | 5 (2) |
| Argon Electric Ltd | Electricians & Electrical Contractors | 416-213-1516 | argonelectric.ca | Etobicoke, ON | - |
| Easy Electric Inc | Electricians & Electrical Contractors | 416-300-1030 | easyelectricinc.ca | North York, ON | - |
| Plaza Electric Ltd | Electricians & Electrical Contractors | 905-789-9655 | plazaelectric.ca | Brampton, ON | - |

Fill rates in a 301-business test run (`plumber` and `restaurants` in Calgary AB and Montreal QC, `dentist` in Vancouver BC, website filter on): phone, website, categories, province 100%, postal code 91%, coordinates 89%, opening hours 77%, services 74%, payment methods 70%, description 69%, languages 68%, social links 67%, rating 39%.

### Why this one

- **$0.70 per 1,000 businesses, no start fee**, business-page details (hours, coordinates, social links, services) included at the same price: the lowest price of the paid YellowPages.ca scrapers.
- **English and French Canada**: search `plombier` in `Laval QC` as easily as `plumber` in `Calgary AB`.
- **Real website URLs** (not YellowPages redirects) and the main phone in +1 format, ready for a dialer or CRM.
- **Ad signals** (`sponsored`, `listingTier`) show which businesses already pay for marketing.

### Use cases

- **B2B lead generation in Canada**: build call lists of contractors, clinics, law firms, restaurants or any other trade, city by city, in English or French Canada
- **Local SEO and marketing agencies**: find businesses with few reviews, a low rating or no social profiles, and pitch them; `listingTier` shows who already buys ads
- **Sales territory planning**: count and map every business of a type across your cities (coordinates and service areas included)
- **Market research**: compare how many providers a trade has across Canadian cities and what services they offer
- **CRM enrichment**: add phones, website, hours, address and social links to the companies you already track

### Pricing

**Pay per result: $0.70 per 1,000 results** (one result = one business saved to the dataset).

| Run | Results | Cost |
|---|---|---|
| Store demo (electrician, Toronto ON) | 20 | $0.014 |
| One term in one city, default | 100 | $0.07 |
| One term in 10 cities | 1,000 | $0.70 |
| Every listing of a big search (100 pages) | about 2,500 | about $1.75 |

No start fee, and the same price with or without the business-page details. Businesses skipped by your filters, duplicates (YellowPages repeats its sponsored placements on every page), searches with no results, removed listings and failed requests are never charged. Platform usage is small because no browser runs. If you set a maximum cost per run, the scraper stops cleanly when it reaches it. Apify's free plan ($5 of monthly credit) covers about 7,100 businesses.

Other paid YellowPages.ca actors on the Store charge $0.72 plus a $0.01 start fee (blackfalcondata), $1.00 (steadyscrape), $2.00 (yugenox), $3.00 plus a start fee (automation-lab) and $4.99 plus $0.09 per run (easyapi) per 1,000 results.

### Input

| Field | Default | Description |
|---|---|---|
| `searchTerms` | - | What to search, e.g. `plumber`, `dentist`, `restaurants` |
| `locations` | - | `City PROVINCE`, e.g. `Toronto ON`, `Montreal QC` |
| `startUrls` | - | Search pages (`/search/si/1/<what>/<where>`) or business pages (`/bus/.../<id>.html`) |
| `maxResultsPerSearch` | 100 | Businesses per term-location pair. 0 = all (up to 100 result pages) |
| `scrapeDetails` | true | Open each business page for hours, geo, social links, service areas |
| `includeSponsored` | true | Keep the paid placements at the top of each page |
| `requireWebsite` / `requirePhone` | false | Only keep businesses with that contact field |
| `minRating` | - | Only keep businesses rated at least this (0-5) |

With no input at all, a 20-business demo (electrician in Toronto ON) runs.

### Input example

```json
{
    "searchTerms": ["plumber", "restaurants"],
    "locations": ["Calgary AB", "Montreal QC"],
    "startUrls": ["https://www.yellowpages.ca/search/si/1/dentist/Vancouver+BC"],
    "maxResultsPerSearch": 100,
    "scrapeDetails": true,
    "requireWebsite": true
}
```

### Example inputs for common jobs

Copy one into the JSON tab of the input form.

**Contractor leads with a website in four Ontario cities**

```json
{
    "searchTerms": ["roofing contractors", "hvac contractors"],
    "locations": ["Toronto ON", "Ottawa ON", "Mississauga ON", "Hamilton ON"],
    "maxResultsPerSearch": 200,
    "requireWebsite": true,
    "requirePhone": true
}
```

**French-language search across Quebec**

```json
{
    "searchTerms": ["plombier", "avocat"],
    "locations": ["Montreal QC", "Quebec QC", "Laval QC", "Gatineau QC"],
    "maxResultsPerSearch": 100
}
```

**Well-rated dentists for a local SEO pitch**

```json
{
    "searchTerms": ["dentist"],
    "locations": ["Vancouver BC", "Calgary AB", "Edmonton AB"],
    "maxResultsPerSearch": 0,
    "minRating": 4
}
```

**Fast listing-only export of every restaurant in a city**

```json
{
    "searchTerms": ["restaurants"],
    "locations": ["Winnipeg MB"],
    "maxResultsPerSearch": 0,
    "scrapeDetails": false,
    "includeSponsored": false
}
```

### Output example

```json
{
    "id": "8045023",
    "name": "Plumteck Déblocage Drain",
    "category": "Plumbers & Plumbing Contractors",
    "categories": ["Plumbers & Plumbing Contractors", "Drain & Sewer Cleaning"],
    "phone": "438-604-5815",
    "phones": ["438-604-5815", "514-336-0382"],
    "phoneE164": "+14386045815",
    "website": "http://plumteckdeblocagedrain.ca/",
    "socialLinks": ["https://www.facebook.com/pages/Plumteck-D%C3%A9blocage-Drain/278402595939259"],
    "street": "2700 Av Chicoutimi",
    "city": "Laval",
    "province": "QC",
    "postalCode": "H7E 1B1",
    "country": "CA",
    "address": "2700 Av Chicoutimi, Laval, QC H7E 1B1",
    "latitude": 45.5979736,
    "longitude": -73.677322,
    "rating": 4.8,
    "reviewCount": 34,
    "openingHours": ["Monday 07:00-23:00", "Tuesday 07:00-23:00", "Wednesday 07:00-23:00", "Thursday 07:00-23:00", "Friday 07:00-23:00", "Saturday 07:00-23:00", "Sunday 07:00-23:00"],
    "openNowText": "Open until 11:00 pm",
    "services": ["Drain Clogged With Tree Roots", "Bathroom Sink Repair", "Clogged Drain", "Drain Pipe Repair"],
    "specialties": ["Drain Unclogging", "Camera Inspection", "Sewer Cleaning"],
    "serviceAreas": ["Notre-Dame-de-Grâce", "Côte-des-Neiges", "Ville-Marie", "Outremont", "Anjou"],
    "languages": ["French", "English", "Italian"],
    "paymentMethods": ["Cash"],
    "sponsored": true,
    "listingTier": "GSP",
    "url": "https://www.yellowpages.ca/bus/Quebec/Laval/Plumteck-Deblocage-Drain/8045023.html",
    "searchKeyword": "plumber",
    "searchLocation": "Montreal QC",
    "position": 1,
    "totalInSearch": 657,
    "detailsScraped": true,
    "scrapedAt": "2026-10-27T17:22:11.819Z"
}
```

(Shortened: rows also carry description, features, rates, brands, professional organizations and logo; lists are cut here.)

The dataset has three views: **Leads**, **Details** and **Search order**. The `RUN_SUMMARY` record lists per search term and location how many results YellowPages has, how many were saved, how many your filters skipped and why each search stopped, plus any search that returned nothing.

### Integrations

- **Our Website Contact Extractor**: YellowPages.ca rarely shows emails, so pass the `website` column to collect emails and social profiles from each company site.
- **Our Website Tech Stack Detector**: see which CMS, shop system or analytics each lead's website runs.
- **Our YellowPages (US) and Gelbe Seiten (Germany) scrapers**: the same lead format for the United States and Germany.
- **Make, Zapier and n8n**: run the actor and push the leads to your CRM, a mailing tool or Slack.
- **Google Sheets**: export the dataset straight to a spreadsheet.
- **Apify API**: start runs and download results over REST, or with the JavaScript and Python clients.
- **Webhooks**: get notified when a run finishes.
- **MCP for AI agents**: the Apify MCP server (https://mcp.apify.com) lets Claude, ChatGPT, Cursor and other agents call this YellowPages.ca scraper as a tool.

### Limits

- **Canada only.** For US businesses use our YellowPages (yellowpages.com) scraper.
- **No emails**: YellowPages.ca does not publish email addresses; chain the Website Contact Extractor for those.
- **Up to 100 result pages per term-location pair** (about 2,500 unique businesses). For big cities, split by neighbourhood or postal code, or use narrower terms.
- Opening hours, social links, service areas, languages and payment methods are only there when the business listed them, and need `scrapeDetails` on.
- YellowPages widens a search to nearby cities when the city has few matches, so some rows can sit outside the city you typed (`city` shows where each one is).
- Results come in YellowPages' own relevance order.

### FAQ

**Does it need a browser, cookies or a YellowPages account?**
No. Plain HTTPS requests to the public pages, no login.

**Which proxy should I use?**
None: leave the default. The actor connects directly and retries any blocked request through Apify Proxy automatically (datacenter, then Canadian residential).

**Is scraping YellowPages.ca legal?**
The actor only reads public business listings on pages robots.txt allows (search result pages and the main business page; review, map and redirect pages are never requested). You are responsible for how you use the data: Canada's anti-spam law (CASL) restricts commercial electronic messages, and PIPEDA applies to sole traders' personal data, so check your outreach before sending.

**Why did my search return nothing?**
Check the spelling, and write the location as `City PROVINCE` (e.g. `Saskatoon SK`). Searches with no results are listed in `RUN_SUMMARY` and cost nothing.

**Is there a cheaper mode without business pages?**
The price per business is the same; turning `scrapeDetails` off only makes the run faster (about 25 businesses per request instead of one request per business) and drops hours, coordinates and social links.

# Actor input Schema

## `searchTerms` (type: `array`):

What to search: business types, categories or names in English or French, one per line, e.g. "plumber", "dentist", "restaurants", "Electricians & Electrical Contractors", "avocat". Every term is searched in every location below.

## `locations` (type: `array`):

Where to search: Canadian cities as "City PROVINCE", one per line, e.g. "Toronto ON", "Montreal QC", "Vancouver BC", "Calgary AB". A postal code (e.g. "M5V 2T6") also works.

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

Optional. Search result pages (https://www.yellowpages.ca/search/si/1/plumber/Ottawa+ON) and/or single business pages (https://www.yellowpages.ca/bus/Ontario/Toronto/<name>/<id>.html), one per line. Use these instead of, or on top of, search terms x locations.

## `maxResultsPerSearch` (type: `integer`):

Optional. Businesses saved per search-location pair, integer >= 0. Default 100; 0 = every listing (up to 100 result pages, about 2,500 unique businesses). You pay per business, so start small.

## `scrapeDetails` (type: `boolean`):

Optional boolean. true (default) = also open every business page for full opening hours, coordinates, social links, international phone, specialties, service areas, languages, payment methods and the full description. false = result-list data only (name, phones, website, address, categories, services, rating): about 25x fewer requests. Same price either way.

## `includeSponsored` (type: `boolean`):

Optional boolean. true (default) = keep the paid placements YellowPages shows at the top of each page (they are real businesses, flagged sponsored: true; duplicates are removed). false = organic results only.

## `requireWebsite` (type: `boolean`):

Optional filter. Skip businesses without a website. Skipped businesses are not charged.

## `requirePhone` (type: `boolean`):

Optional filter. Skip businesses without a phone number. Skipped businesses are not charged.

## `minRating` (type: `number`):

Optional filter, 0-5. Skip businesses rated below this (unrated businesses are skipped too). Skipped businesses are not charged.

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

Optional, advanced. Parallel requests, integer 1-20. Default 8. Leave unset.

## `maxRequestRetries` (type: `integer`):

Optional, advanced. Retries per failed or blocked request, integer 0-20; each retry uses a new session. Default 6.

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

Optional, advanced. Leave as is. Default {"useApifyProxy": false} = automatic: direct connection first, and only requests that get blocked are retried through Apify Proxy (datacenter, then Canadian residential). Set your own Apify Proxy groups or proxy URLs to force them for every request.

## Actor input object example

```json
{
  "searchTerms": [
    "electrician"
  ],
  "locations": [
    "Toronto ON"
  ],
  "maxResultsPerSearch": 20,
  "scrapeDetails": true,
  "includeSponsored": true,
  "requireWebsite": false,
  "requirePhone": false,
  "maxConcurrency": 8,
  "maxRequestRetries": 6,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `businesses` (type: `string`):

One row per business: name, phone, website, address, categories, rating, opening hours, services and social links.

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

Counts per search term and location, filtered businesses and any search that returned nothing.

# 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 = {
    "searchTerms": [
        "electrician"
    ],
    "locations": [
        "Toronto ON"
    ],
    "maxResultsPerSearch": 20,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("rel8ble/yellowpages-ca-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 = {
    "searchTerms": ["electrician"],
    "locations": ["Toronto ON"],
    "maxResultsPerSearch": 20,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("rel8ble/yellowpages-ca-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 '{
  "searchTerms": [
    "electrician"
  ],
  "locations": [
    "Toronto ON"
  ],
  "maxResultsPerSearch": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call rel8ble/yellowpages-ca-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,rel8ble/yellowpages-ca-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/mgy0yJiyvKBnj1Xxa/builds/qQ5udEkE9GuFVD1qb/openapi.json
