# Canada Job Bank Postings (Open Data) (`jetlaunch/canada-job-bank-open-data`) Actor

Filter and compare the Government of Canada's monthly Job Bank job postings open data by NOC, NAICS sector, province, city, wage and keyword. Uses the official open data files, no website scraping.

- **URL**: https://apify.com/jetlaunch/canada-job-bank-open-data.md
- **Developed by:** [Chris O'Byrne](https://apify.com/jetlaunch) (community)
- **Categories:** Jobs, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 job posting returneds

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

## Canada Job Bank Postings (Open Data)

Filter and compare the Government of Canada's monthly Job Bank job postings. This Actor reads the official open data files published on open.canada.ca, not the Job Bank website. It returns clean, normalized records, and it can compare two months to show how posting counts and wages moved.

Contains information licensed under the Open Government Licence – Canada.

### What does it do?

Employment and Social Development Canada publishes a file every month with the job postings advertised on Canada's National Job Bank website: [Job Postings Advertised on Canada's National Job Bank Website](https://open.canada.ca/data/en/dataset/ea639e28-c0fc-48bf-b5dd-b8899bd43072). The files are large (about 46 MB each, UTF-16 text with 65 columns). This Actor finds the right file for you, reads it as a stream, applies your filters and returns tidy JSON.

It has two modes:

- **Postings**: one record per job posting, with the title, NOC occupation, NAICS sector, location, wage (as posted and as an hourly estimate), hours, start date, vacancy count and first posting date.
- **Month over month**: compares two monthly files and returns an overview, posting counts and median wage by NOC occupation and by province, and the NOC codes that appeared or disappeared.

You can filter by NOC code (2021 or 2016), NAICS sector, province or territory, city, wage range, keyword, employment type, posting source and posting date. English and French files are supported.

### Who is it for?

Labour market analysts, workforce boards, recruiters, economic development offices, journalists, researchers and anyone who tracks demand for an occupation in a region without parsing the raw files themselves.

### What is and is not in the data

In the files:

- One row per posting location, with the job title, original job title, NOC 2021 and NOC 2016 code and name, NAICS sector name, province or territory, city, economic region, first three characters of the postal code, vacancy count, employment type and term, wage as posted with its pay period, minimum and maximum, hours, start and end dates, and the first posting date.
- Only postings first advertised in the file's month. Month over month compares two sets of new postings, not the stock of open jobs.

Not in the files, and therefore not returned by this Actor:

- No employer names, so no employer filter and no "new employers" report.
- No temporary foreign worker flag.
- No contact names, phone numbers or email addresses.
- No link to the posting on the Job Bank website, and no posting end or expiry date.
- No live data: files are published monthly, and each covers one month.

Added by this Actor, and estimates only: hourly wage figures (yearly pay divided by 2,080 hours, monthly by 173.33, weekly by 40, bi-weekly by 80, daily by 8; values under $5 or over $1,000 an hour are dropped as probable data entry errors), and the 2 digit NAICS sector code.

### Why use open data instead of a scraper?

The Job Bank Terms of Use for job seekers say Job Bank prohibits "the use of any script, robot, spider, Web crawler, screen scraper, automated query program" to access its services. This Actor never requests a jobbank.gc.ca page. It downloads only the government's own published files, under a licence that allows commercial reuse with attribution. The trade-off is that you get what the file contains (see the section above): monthly data, no employer names and no live postings.

### Input

| Field | What it does |
| --- | --- |
| Mode | Postings, or Month over month |
| Month | `latest` or `YYYY-MM`. Each file holds postings first advertised in that month |
| NOC codes | 5 digit NOC 2021 (for example `21231`), 4 digit NOC 2016, or a prefix such as `2123*` |
| Provinces, Cities | Names or codes (`ON`, `BC`, `QC`), accents and case ignored |
| NAICS sector | 2 digit sector codes (`72`, `62`) or words from the sector name (`health`, `laundry`) |
| Keywords | Any word in the job title, original title or NOC occupation name |
| Minimum / maximum hourly wage | Compared with the posting's wage range, converted to an hourly estimate |
| Employment type, Posting source, Placement agencies, Posted from / to | Further filters |
| Order of results, Maximum postings | `file-order` stops reading as soon as enough postings are found |
| Compare with month, Maximum rows, Minimum postings, NOC by province rows | Month over month options |

The prefilled input returns 25 postings for NOC 21231 (Software engineers and designers) in Ontario from the latest file.

### Output

Each posting looks like this (shortened):

```json
{
  "recordType": "posting",
  "postingId": "15846549",
  "title": "cloud administrator",
  "nocCode": "21231",
  "nocTitle": "Software engineers and designers",
  "naicsSector": null,
  "listingSource": "external job board",
  "province": "Ontario",
  "city": "Richmond Hill",
  "vacancies": 1,
  "employmentTerm": "Term or contract",
  "wageText": "$18.00 to $22.00 hourly",
  "wagePer": "Hour",
  "wageMin": 18,
  "wageMax": 22,
  "hourlyWageMin": 18,
  "hourlyWageMax": 22,
  "firstPostingDate": "2026-09-03",
  "sourceMonth": "2026-09",
  "sourceUrl": "https://open.canada.ca/data/dataset/ea639e28-.../download/job-bank-open-data-all-job-postings-en-sept2026.csv",
  "attribution": "Contains information licensed under the Open Government Licence – Canada."
}
```

`postingId` is the file's "WIC Job Location Snapshot ID". It is not documented as a Job Bank posting number, so the Actor does not turn it into a link to jobbank.gc.ca. `sourceUrl` points to the open data file the record came from.

Month over month mode returns a `monthly-summary` row (totals, change, median hourly wage, new and dropped NOC codes), then `noc-change` rows (largest changes first), `province-change` rows and, if requested, `noc-province-change` rows. Every run also stores a `RUN_SUMMARY` record with the files used, the filters, the licence and the attribution statement.

### Pricing

Pay per event. You pay only for results.

| Event | Price | When it is charged |
| --- | --- | --- |
| `posting-record` | $0.001 | Once per posting returned in Postings mode |
| `monthly-summary` | $0.02 | Once per month over month summary (one overview plus its breakdown rows) |

Nothing is charged for a run that finds no matching postings, and a summary is not charged if either month has no matching postings. Set a maximum cost per run in the run options and the Actor stops when the limit is reached. Platform usage is covered by these prices.

### Data source and licence

Source: Job Postings Advertised on Canada's National Job Bank Website, Employment and Social Development Canada, on open.canada.ca, released under the [Open Government Licence – Canada](https://open.canada.ca/en/open-government-licence-canada). The licence's attribution statement, which this Actor adds to every record, is: "Contains information licensed under the Open Government Licence – Canada." If you republish the data, keep that statement and link to the licence. The licence does not cover personal information, and the Actor returns no contact names, phone numbers or email addresses. Job titles and wage text that contain an email address or phone number are returned as null, and only the first three characters of a postal code are kept.

This Actor is not affiliated with or endorsed by the Government of Canada, Employment and Social Development Canada or Job Bank.

### FAQ

**Is this live data?** No. The files are published once a month, a few days after month end. The September 2026 file was posted on 2026-10-02.

**What does one monthly file contain?** The postings first advertised in that month. In the August and September 2026 files no posting appears in both, and every first posting date falls in the file's month. Month over month mode therefore compares two sets of newly advertised postings, not the stock of open jobs.

**Why is NAICS often empty?** Postings from partner job boards ("external job board") do not carry a NAICS sector, education or experience. In the September 2026 file that is 30,108 of 52,368 postings. Filtering by NAICS keeps only postings placed directly on Job Bank.

**Are the hourly wages exact?** No. They are estimates: yearly pay divided by 2,080 hours, monthly by 173.33, weekly by 40, bi-weekly by 80, daily by 8. Hourly values below $5 or above $1,000 are treated as data entry errors and returned as null (the posted `wageMin` and `wageMax` are still returned).

**Can I filter by employer or temporary foreign worker?** No. The monthly files do not contain employer names or a temporary foreign worker flag, so the Actor cannot provide them.

**How long does a run take?** The prefilled run (25 postings) finished in about 4 seconds on the platform. A month over month summary reads two files and took about 6 seconds in testing. Runs that must read a whole file take longer, mostly for the download.

**Which months are available?** Every month listed in the dataset with a download link. The Actor reads the list from the open.canada.ca catalog at run time, so new months appear without an update.

### Limitations

- Monthly files only, with no live or expired posting status.
- No employer name, contact details, posting URL or temporary foreign worker flag in the source.
- One posting row is one job location snapshot. A posting with several vacancies is one row with a vacancy count.
- Values of "NA" and "\*No data" in the file become null.
- The file gives a NAICS sector name, not a code. This Actor adds a 2 digit code for names that are NAICS Canada 2017 sectors (checked against the Statistics Canada sector list). A few names in the file are subsectors (for example Employment services, Repair and maintenance, Private households); these are returned by name only, with `naicsCodes` null, and can be filtered by words but not by code.
- French file values are mapped to the English values for categories. Job titles stay in French.

### Support

Open the Issues tab of this Actor for questions, bugs or feature requests. Contact: chris@jetlaunch.net.

# Actor input Schema

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

Postings returns normalized job postings. Month over month compares two monthly files (posting counts by NOC and province, wage changes).

## `month` (type: `string`):

latest, or a month as YYYY-MM (for example 2026-09). The files hold postings first advertised in that month.

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

English or French edition of the file. Category values are returned in English either way; job titles stay in the file's language.

## `nocCodes` (type: `array`):

5 digit NOC 2021 codes (for example 21231 Software engineers and designers), 4 digit NOC 2016 codes, or a prefix ending in \* (2123\*). Leave empty for all occupations.

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

Full names (Ontario, British Columbia, Québec) or codes (ON, BC, QC, AB, MB, SK, NS, NB, NL, PE, YT, NT, NU).

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

City names as written in the file (Toronto, Calgary, Montréal). Accents and capital letters do not matter.

## `naicsCodes` (type: `array`):

2 digit NAICS sector codes (72, 62, 23) or words from the sector name (food, health, laundry). The file carries a sector name, not a code. The Actor maps the sector names to 2 digit codes checked against the Statistics Canada NAICS Canada 2017 sector list; subsector names (for example Employment services) have no code and match by words only. Only postings placed directly on Job Bank have a sector.

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

Match any of these words in the job title, the original job title or the NOC occupation name.

## `minHourlyWage` (type: `number`):

Keep postings whose wage range reaches at least this hourly amount. Yearly, monthly, weekly and daily pay is converted to an hourly estimate. Postings without a wage are dropped when a wage filter is set.

## `maxHourlyWage` (type: `number`):

Keep postings whose wage range starts at or below this hourly amount.

## `employmentTypes` (type: `array`):

For example Full time, Part time.

## `postingSource` (type: `string`):

Direct postings are placed by employers on Job Bank and carry more fields (sector, education, experience). External postings come from partner job boards.

## `placementAgencies` (type: `string`):

Whether to keep postings flagged as placement agency postings.

## `postedFrom` (type: `string`):

Date as YYYY-MM-DD.

## `postedTo` (type: `string`):

Date as YYYY-MM-DD.

## `sortBy` (type: `string`):

File order stops reading as soon as enough postings are found, which is fastest. The other orders read the whole file (up to 20000 results).

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

Postings mode only. Each posting returned is one billable posting-record event.

## `compareToMonth` (type: `string`):

Month over month mode only. previous means the calendar month before Month, or give YYYY-MM.

## `maxRows` (type: `integer`):

Largest NOC changes to return (by absolute change in postings).

## `minPostings` (type: `integer`):

Hide NOC rows with fewer postings than this in both months, to avoid noise.

## `includeNocProvince` (type: `boolean`):

Also return changes for each NOC and province combination.

## Actor input object example

```json
{
  "mode": "postings",
  "month": "latest",
  "language": "en",
  "nocCodes": [
    "21231"
  ],
  "provinces": [
    "Ontario"
  ],
  "postingSource": "all",
  "placementAgencies": "include",
  "sortBy": "file-order",
  "maxItems": 25,
  "compareToMonth": "previous",
  "maxRows": 50,
  "minPostings": 10,
  "includeNocProvince": false
}
```

# Actor output Schema

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

Postings or month-over-month rows from the default dataset.

## `runSummary` (type: `string`):

Source files, filters, licence and the required attribution statement.

# 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 = {
    "month": "latest",
    "nocCodes": [
        "21231"
    ],
    "provinces": [
        "Ontario"
    ],
    "maxItems": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("jetlaunch/canada-job-bank-open-data").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 = {
    "month": "latest",
    "nocCodes": ["21231"],
    "provinces": ["Ontario"],
    "maxItems": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("jetlaunch/canada-job-bank-open-data").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 '{
  "month": "latest",
  "nocCodes": [
    "21231"
  ],
  "provinces": [
    "Ontario"
  ],
  "maxItems": 25
}' |
apify call jetlaunch/canada-job-bank-open-data --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jetlaunch/canada-job-bank-open-data"
        }
    }
}
```

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/j8Nch5C3aR9lmHSQC/builds/fUYztSiNHHBVrpvIA/openapi.json
