# Job Bank Canada Scraper (`deriverge/job-bank-canada-scraper`) Actor

Jobs from Job Bank, the Government of Canada's job board, with the wage as numbers, hours per week, vacancies, education, experience and the workplace address. Search by keyword and province, filter by date, terms and language, and flag jobs open to international candidates.

- **URL**: https://apify.com/deriverge/job-bank-canada-scraper.md
- **Developed by:** [deriverge s.r.o.](https://apify.com/deriverge) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.25 / 1,000 jobs

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?

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

## Job Bank Canada Scraper

Job Bank Canada Scraper returns jobs from Job Bank (jobbank.gc.ca), the Government of Canada's job board, one row per job: title, employer, city and province, the wage as numbers with its period, and from the job page the workplace address, hours per week, vacancies, employment terms, education, experience, language of work and whether international candidates may apply. Type a keyword such as `cook`, pick provinces and click **Start**. Job Bank asks automated visitors to wait 5 seconds between pages, so with full details a job takes about 5 seconds. It costs $0.50 per 1,000 jobs on the Free plan ($0.25 on Business), and the $5 of monthly credit in Apify's Free plan covers about 10,000 jobs.

### What data does it return?

| Field | Description |
|---|---|
| `jobId`, `jobNumber`, `url` | Job Bank's posting ID, the job number shown on the posting after `#`, and the job page. |
| `title`, `employer` | Job title and hiring employer as posted, such as `cook` at `MR MIKES Steakhouse Casual`. |
| `location`, `city`, `province`, `provinceName` | Place as Job Bank shows it (`Olds (AB)`), the city, the two-letter code and the full name of the province or territory. |
| `street`, `postalCode` | Workplace address, when the employer gives one. |
| `workLocation` | `On site`, `Hybrid`, `Remote` or `On the road`. Partner job boards usually leave it empty. |
| `salaryText` | Wage exactly as posted, such as `$18.50 hourly`. |
| `salaryMin`, `salaryMax`, `salaryPeriod`, `salaryCurrency` | The wage as numbers in CAD and its period: `hour`, `week`, `month`, `year` or `day`. A single figure fills both. |
| `hoursPerWeek` | Weekly hours as text, such as `35` or `30 to 40`. |
| `employmentTerms`, `schedule` | Terms such as `Permanent employment` and `Full time`, and shifts such as `Day`, `Night` or `Weekend`. |
| `vacancies` | Number of positions the employer wants to fill. |
| `languages`, `education`, `experience` | Language of work, required education and required experience, such as `1 year to less than 2 years`. |
| `openToInternationalCandidates` | `true` when the employer also accepts candidates from outside Canada. |
| `studentJob`, `apprenticeship`, `internship`, `greenJob` | Job Bank's flags for these kinds of jobs. |
| `directApply`, `postedOnJobBank`, `source` | `true` when Job Bank offers direct application, `true` when the employer posted the job on Job Bank itself, and the source, `Job Bank` or a partner board such as `indeed.com`. |
| `postedAt`, `expiresAt`, `updatedAt` | Date posted, date the ad runs until and date of the last change, as `YYYY-MM-DD`. |
| `description` | The posting's text: education, work setting, tasks, conditions and support programs. |
| `isNew`, `detailsIncluded`, `searchQuery` | Job Bank's "new" mark, `true` when the job page was read, and the search that found the job. |
| `key`, `scrapedAt` | The key `jobbank:<jobId>` used by new-only mode, and when the job was read in UTC. |

Fields that come from the job page (address, hours, vacancies, terms, schedule, languages, education, experience, description and the flags) are `null` or empty with **Include full details** off.

### How to scrape Job Bank Canada

1. Enter **Keywords** as you would in Job Bank's search box: a job title, occupation or skill such as `truck driver` or `registered nurse`. Each keyword is a separate search; leave the field empty for every job.
2. Pick **Provinces and territories** and, if you need them, **Cities** such as `Calgary`. A city is matched against the job's location, so combine it with its province to keep runs short.
3. Narrow with **Posted** (last 2 or 30 days), **Employment terms**, **Language of work**, **Source** and **Open to international candidates**. **Exclude keywords** drops jobs whose title or employer contains a word.
4. Keep **Include full details** on for the fields from the job page, or turn it off for a fast list. Set **Maximum jobs** (100 by default) and click **Start**.
5. The jobs appear in the **Output** tab, ready for CSV, Excel or JSON export. The `SUMMARY` record in the key-value store gives the number of matching jobs per search and how many were returned.

From the API:

```json
{
  "keywords": ["truck driver", "registered nurse"],
  "provinces": ["ON", "BC"],
  "postedWithin": "30",
  "source": "jobBank",
  "includeDetails": true,
  "maxItems": 200
}
```

### Example output

A cook job in Alberta from a run on 11 October 2026, with the description shortened after three sentences (marked ` ...`).

```json
{
  "key": "jobbank:50469130",
  "jobId": "50469130",
  "jobNumber": "3693832",
  "title": "cook",
  "url": "https://www.jobbank.gc.ca/jobsearch/jobposting/50469130",
  "employer": "MR MIKES Steakhouse Casual",
  "location": "Olds (AB)",
  "city": "Olds",
  "province": "AB",
  "provinceName": "Alberta",
  "street": "5509 46 St",
  "postalCode": "T4H 1H5",
  "workLocation": "On site",
  "salaryText": "$18.50 hourly",
  "salaryMin": 18.5,
  "salaryMax": 18.5,
  "salaryPeriod": "hour",
  "salaryCurrency": "CAD",
  "hoursPerWeek": "35",
  "employmentTerms": [
    "Permanent employment",
    "Full time"
  ],
  "schedule": [
    "Morning",
    "Day",
    "Evening",
    "Night",
    "Weekend"
  ],
  "vacancies": 2,
  "languages": "English",
  "education": "Secondary (high) school graduation certificate",
  "experience": "1 year to less than 2 years",
  "openToInternationalCandidates": false,
  "studentJob": false,
  "apprenticeship": false,
  "internship": false,
  "greenJob": false,
  "directApply": true,
  "postedOnJobBank": true,
  "source": "Job Bank",
  "isNew": true,
  "postedAt": "2026-10-10",
  "expiresAt": "2026-10-24",
  "updatedAt": "2026-08-04",
  "description": "Education: Secondary (high) school graduation certificate. Work setting: Restaurant. Tasks: Determine the size of food portions and costs. Prepare and cook complete meals or individual dishes and foods. Prepare dishes for customers with food allergies or intolerances. ...",
  "detailsIncluded": true,
  "searchQuery": "\"cook\" in AB",
  "scrapedAt": "2026-10-11T15:51:20.741Z"
}
```

### How much does it cost to scrape Job Bank?

| | Free plan | Starter | Scale | Business |
|---|---|---|---|---|
| 1,000 jobs | $0.50 | $0.40 | $0.325 | $0.25 |

You pay only for the events in the table. There is no start fee, and compute time and proxies are included.

The 444 jobs posted in British Columbia in the last 2 days cost $0.222 on the Free plan and $0.111 on Business. The price per job is the same with or without full details. Jobs dropped by **Cities** or **Exclude keywords**, duplicates across keywords and jobs a watch has already returned are not charged.

### Limits

- Job Bank's robots.txt sets a crawl delay of 5 seconds, and every request waits for it. On 11 October 2026, 20 cooks in Alberta with full details took 105 seconds, 40 jobs from two searches took 209 seconds, and the 444 British Columbia jobs of the last 2 days without details took 88 seconds, 25 jobs per page.
- A run stops after 1 hour by default, which with full details is enough for about 650 jobs. For more, raise the timeout in the run options or turn details off.
- Partner boards fill fewer fields. Their jobs have a description and the employment terms, but usually no address, hours, vacancies, education, experience or work location. In British Columbia, 231 of the 444 recent jobs were posted on Job Bank itself; the rest came from boards such as indeed.com and CivicJobs.ca. Pick **Only jobs posted on Job Bank** under **Source** when you need every field.
- The NOC occupation code and the LMIA status are not returned, and neither is how to apply: Job Bank shows the contact only behind a button, and the actor does not open it.
- Partner wages are taken from the partner's text and can be wrong at the source, for example `From $18.00 per week` for a part-time cook.
- If Job Bank answers with HTTP 429, the run pauses for 5 minutes, at most twice, and then ends with the jobs it already has. On HTTP 403 or a verification page it stops requesting at once, returns the jobs it has, and says so in the log, the `SUMMARY` record and the run status.

### Daily job alerts

Turn on **Return only jobs new since the last run**, give a **Watch name** or save the input as a task, and schedule it once a day with **Posted** set to **In the last 2 days**. Each run returns and charges only jobs that no earlier run of that watch returned. Jobs left out because of **Maximum jobs** stay new for the next run, and the watch remembers a job for 120 days.

### FAQ

#### Is it legal to scrape Job Bank?

Job Bank is a public job board run by Employment and Social Development Canada, and the actor reads the same search and job pages any visitor sees, keeping to the crawl delay in its robots.txt. Rows describe jobs and employers; the actor does not open the application contact and collects no names, emails or phone numbers of people. You are responsible for how you use the data.

#### Why do some jobs have only a few fields?

They come from partner job boards. Job Bank lists them with a short page, so the address, hours and requirements are missing even with full details on. Set **Source** to **Only jobs posted on Job Bank** to leave them out.

#### How do I get every job in a province?

Leave **Keywords** empty, pick the province and turn **Include full details** off. Each page then brings 25 jobs every 5 seconds, so an hour of run time covers about 18,000 jobs; with **Posted** set to the last 2 days, British Columbia had 444.

### Related scrapers

- [MyCareersFuture Jobs Scraper](https://apify.com/deriverge/mycareersfuture-jobs-scraper)
- [Arbeitsagentur Jobs Scraper](https://apify.com/deriverge/arbeitsagentur-jobs-scraper)
- [Career Site and ATS Jobs API](https://apify.com/deriverge/career-site-jobs-search)
- [SimplyHired Jobs Scraper](https://apify.com/deriverge/simplyhired-jobs-scraper)

### Support

This actor is built and maintained by deriverge s.r.o., a software company based in the Czech Republic. If a run fails or a field you need is missing, please open an issue in the **Issues** tab or write to us at info@deriverge.com. We respond in English and Czech. Runs can be scheduled in Apify Console or started from the **API** tab, which has examples for Python, JavaScript and cURL and works with Make, Zapier, n8n and the Apify MCP server. If the actor saves you time, a short review helps other people find it.

# Changelog

This Actor's version history is a separate document: https://apify.com/deriverge/job-bank-canada-scraper/changelog.md

# Actor input Schema

## `keywords` (type: `array`):

What to search for, as in the Job Bank search box: a job title, occupation or skill, for example "cook", "truck driver", "registered nurse" or "software developer". Each keyword is its own search. Leave empty for all jobs.

## `provinces` (type: `array`):

Only jobs in these provinces or territories. Leave empty for all of Canada.

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

Only jobs in any of these cities, for example Toronto, Calgary or Vancouver. Combine with a province for faster runs.

## `postedWithin` (type: `string`):

Only jobs posted in this window, as on the website.

## `employmentTerms` (type: `array`):

Only jobs with any of these terms. Leave empty for all.

## `language` (type: `string`):

Only jobs in this language of work.

## `source` (type: `string`):

Job Bank also lists jobs from partner job boards such as Indeed or CareerBeacon. Jobs posted on Job Bank have the most fields.

## `openToInternationalOnly` (type: `boolean`):

Only jobs where employers also accept candidates from outside Canada, as the website filter "Canadians and international candidates".

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

Reads each job page for the address, hours per week, vacancies, employment terms, schedule, languages, education, experience, description and whether international candidates can apply. The price is the same, but each job adds 5 seconds (see Maximum jobs).

## `excludeKeywords` (type: `array`):

Drop jobs whose title or employer contains any of these.

## `newOnly` (type: `boolean`):

Keeps a snapshot per watch name (or per saved task) and returns only jobs that were not there before. Schedule it daily for a job alert.

## `watchName` (type: `string`):

Name of the snapshot used by the new-only mode, for example "cooks-alberta". Runs from a saved task get one automatically.

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

Hard cap on returned jobs. Job Bank asks automated visitors to wait 5 seconds between pages, and the scraper keeps to that: 100 jobs with full details take about 9 minutes, without details about 25 seconds (25 jobs per page).

## Actor input object example

```json
{
  "keywords": [
    "cook"
  ],
  "provinces": [
    "AB"
  ],
  "postedWithin": "any",
  "language": "any",
  "source": "all",
  "openToInternationalOnly": false,
  "includeDetails": true,
  "newOnly": false,
  "maxItems": 20
}
```

# Actor output Schema

## `jobs` (type: `string`):

One row per job with salary, hours, vacancies, terms, requirements, address and description.

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

Jobs matching and returned per search, details read, dropped rows and warnings.

# 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 = {
    "keywords": [
        "cook"
    ],
    "provinces": [
        "AB"
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("deriverge/job-bank-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 = {
    "keywords": ["cook"],
    "provinces": ["AB"],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("deriverge/job-bank-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 '{
  "keywords": [
    "cook"
  ],
  "provinces": [
    "AB"
  ],
  "maxItems": 20
}' |
apify call deriverge/job-bank-canada-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,deriverge/job-bank-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/cKCMVpXyJBW9xrB8v/builds/NkgbZzSA9jGmzaK9R/openapi.json
