# Job Bank Canada Scraper & LMIA Job Monitor (`getascraper/jobbank-scraper`) Actor

Scrape and monitor Job Bank Canada jobs with structured salaries, NOC and LMIA status, application routes, and meaningful job changes.

- **URL**: https://apify.com/getascraper/jobbank-scraper.md
- **Developed by:** [GetAScraper](https://apify.com/getascraper) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 48 total users, 20 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.67 / 1,000 job leads

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/platform/actors/running/actors-in-store#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

## 🇨🇦 Job Bank Canada Scraper & LMIA Job Monitor

<table width="100%">
<tr>
<td style="padding:24px;background:#FCF2F2;border:1px solid #FCF2F2;border-left:5px solid #D52B1E;border-radius:10px">
<span style="font-size:22px;font-weight:800;color:#1C1917">Turn public Canadian job listings into an organised hiring feed.</span><br>
<span style="font-size:15px;color:#57534E">Collect current Job Bank postings with salary, employer, NOC, LMIA, location, and genuine application details. Schedule it to receive only meaningful hiring changes.</span>
</td>
</tr>
</table>

<table width="100%">
<tr>
<td width="25%" style="padding:14px;vertical-align:top"><strong>🎯 Find the right roles</strong><br>Search by keyword, city, province, NOC, date, and work arrangement.</td>
<td width="25%" style="padding:14px;vertical-align:top"><strong>🛂 Focus on LMIA</strong><br>Separate requested and approved LMIA postings when Job Bank publishes that status.</td>
<td width="25%" style="padding:14px;vertical-align:top"><strong>🔔 Watch for change</strong><br>Save new, updated, and expired postings while leaving unchanged jobs out of the feed.</td>
<td width="25%" style="padding:14px;vertical-align:top"><strong>✅ Keep data genuine</strong><br>Empty source fields stay empty. This Actor never invents employer contacts or job details.</td>
</tr>
</table>

### 🔍 What does this Actor do?

Job Bank Canada Scraper & LMIA Job Monitor collects public Canadian jobs from Job Bank into a structured, ready-to-use feed. It is built for job boards, recruitment operations, immigration services, and labour-market teams that need current roles without repeatedly sorting through the same listings.

Each record keeps the source's job title, employer, location, salary, NOC classification, published application route, and other details Job Bank makes available. Give it a keyword and city, provide an existing Job Bank search, or check a specific posting.

### ✨ Why teams choose it

- Keep a Canadian jobs feed current with stable job IDs and clear source links.
- Filter precisely by province, NOC code, date, LMIA status, work schedule, workplace type, language, and source.
- Preserve the real application route, including an email only when the posting explicitly publishes one.
- Schedule a watchlist and receive only new, updated, or expired jobs in change-only mode.
- Review Job Bank and partner-board jobs separately, instead of mixing them without a source label.

### 🧭 How it works

1. Choose a keyword and optional Canadian location, or paste public Job Bank search and posting links.
2. Add the filters that matter to your audience, then set the maximum number of unique jobs to collect.
3. Run once for a current export, or schedule the same search with change-only monitoring for a focused update feed.

### ⚙️ Input

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `searchKeyword`, `location` | Text | No | Create one keyword search with an optional Canadian city or town. |
| `searches` | List of search objects | No | Run several keyword and city searches together. |
| `startUrls` | List of URLs | No | Use public Job Bank search pages or individual posting pages you already know. |
| `provinces`, `nocCodes`, `datePosted` | Lists and selection | No | Narrow the source search by territory, five-digit NOC 2021 code, and posting age. |
| `lmiaStatus`, `onlyLmiaRequested` | Selection and toggle | No | Return any job, LMIA requested jobs, approved jobs, or both LMIA categories. |
| `excludeStudent`, `sourceType` | Toggles and selection | No | Exclude student jobs and choose Job Bank, external-board, or all source postings. |
| `employmentSchedules`, `workplaceTypes`, `languages` | Lists | No | Keep matching full-time or part-time, workplace, and source-published language requirements. |
| `sortBy`, `maxItems` | Selection and number | No | Choose best match or newest first, then cap the total number of unique jobs. |
| `monitoringMode`, `stateName`, `resetState` | Selection, text, and toggle | No | Create an independent saved watchlist and decide whether to return only changes or all current jobs. |
| `proxyConfiguration` | Connection setting | No | Uses the prefilled Apify Proxy setting unless you provide another valid configuration. |

### 📦 Data you receive

Fields are created only from details that Job Bank or the linked partner posting publishes. Missing information remains empty rather than being replaced with placeholders.

| Field | Type | Description |
| --- | --- | --- |
| `stable_id`, `job_id`, `source_job_id` | Text | Stable identifiers for deduplication and monitoring. |
| `source`, `source_name`, `url` | Text and link | Whether the role is on Job Bank or an external board, plus its original posting link. |
| `title`, `original_title`, `employer` | Text | The published role and employer details. |
| `location`, `city`, `province`, `postal_code` | Text | Published Canadian location information. |
| `description`, `description_html` | Text | Job description in readable and source-markup forms when available. |
| `noc_code`, `noc_title`, `lmia_status` | Text | NOC classification and published LMIA status. |
| `date_posted`, `expiry_date`, `valid_through` | Date | Job posting and validity dates when the source provides them. |
| `salary`, `salary_min`, `salary_max`, `salary_currency`, `salary_unit` | Text and number | Published compensation details. |
| `employment_type`, `hours`, `hours_per_week`, `vacancies` | Text and number | Published work arrangement, hours, and vacancy count. |
| `workplace_type`, `languages`, `education`, `experience` | Text and list | Workplace, language, education, and experience requirements. |
| `tasks`, `skills`, `benefits`, `credentials` | Lists | Responsibilities, skills, benefits, and credentials from the listing. |
| `application_url`, `application_method`, `application_email`, `apply_instructions` | Link and text | The published application route. Email is included only when explicitly listed. |
| `change_type`, `changed_fields`, `first_seen_at`, `last_seen_at`, `expired_at` | Text and date | Change-only monitoring context for new, updated, and expired jobs. |

### 🔔 Change-only monitoring

The first run with `new_and_updated` establishes a baseline and labels current records as `NEW`. Later runs save only `NEW`, `UPDATED`, and verified `EXPIRED` records. Unchanged jobs are kept in the saved watchlist state but are not written to the dataset in this mode.

Use the same `stateName` and the same search scope for every scheduled run. A failed or capped run does not advance expiry checks, helping prevent false expired signals.

### 💰 Pricing

This Actor uses pay-per-result pricing. You pay for records saved to the dataset, with the current event rates shown on the Apify Store page. In change-only monitoring, unchanged jobs are not saved as results. There is no separate subscription required to get started.

### ⭐ Enjoying Job Bank Canada Scraper?

<table width="100%">
<tr>
<td style="padding:20px 24px 14px;background:#FCF2F2;border:1px solid #FCF2F2;border-left:5px solid #D52B1E;border-radius:10px 10px 0 0">
<span style="font-size:20px;letter-spacing:4px">⭐ ⭐ ⭐ ⭐ ⭐</span><br>
<span style="font-size:17px;font-weight:800;color:#1C1917">Source live Canadian job postings with salary, employer, and LMIA sponsorship status for immigration-ready leads.</span><br>
<span style="font-size:14px;color:#57534E">A 5-star rating takes 10 seconds and helps other immigration consultants and recruiters find it. Your feedback also tells us what to build next.</span>
</td>
</tr>
<tr>
<td style="padding:0;background:#D52B1E;border:1px solid #FCF2F2;border-top:none;border-radius:0 0 10px 10px;text-align:center">
<a href="https://apify.com/getascraper/jobbank-scraper/reviews" style="display:block;padding:13px 16px;color:#FFFFFF;text-decoration:none;font-weight:800;font-size:15px;letter-spacing:0.3px">★&nbsp;&nbsp;Rate this Actor on Apify</a>
</td>
</tr>
</table>

### ❓ Frequently asked questions

#### Can I track a single city or occupation?

Yes. Use the keyword and Canadian city fields, or create several city and keyword searches in one run. You can also target a province or NOC code.

#### What does the LMIA filter include?

Choose LMIA requested, LMIA approved, or both. The Actor keeps the source-published status on each result so you can keep those groups separate after collection.

#### How do recurring updates work?

Schedule the Actor with `new_and_updated`, retain the same state name and search scope, and use the resulting change feed in your workflow. A first monitoring run establishes the starting point; later successful runs save meaningful changes.

#### Why is an employer contact or salary empty?

Some listings do not publish every detail. Empty fields indicate the source did not make that information available. The Actor does not create generic contacts, salaries, or job attributes.

### 🔗 Other actors

- [HigherEdJobs Scraper: Academic & University Listings](https://apify.com/getascraper/higheredjobs-com-scraper)
- [CWJobs scraper: UK tech jobs, salaries & geo](https://apify.com/getascraper/cwjobs-scraper)
- [EdJoin Scraper: K-12 Teaching, Certificated and Classified Job Listings](https://apify.com/getascraper/edjoin-scraper)
- [HN Who is Hiring Scraper](https://apify.com/getascraper/hn-hiring-scraper)
- [AllJobs.co.il Scraper](https://apify.com/getascraper/alljobs-scraper)

# Actor input Schema

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

Optional public Job Bank search or individual posting URLs. They are added alongside search-builder inputs, so use this for a precise saved search or a direct job check.

## `searchKeyword` (type: `string`):

A title, employer, skill, or occupation query, such as carpenter, nurse, or Python. This original field remains supported for saved tasks.

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

A Canadian city or town, such as Toronto or Brampton. The Actor resolves it through Job Bank's official location service so the search stays city-specific.

## `searches` (type: `array`):

Optional JSON list of separate searches, for example \[{"keyword":"carpenter","location":"Toronto"}]. The single keyword and city fields are added too when supplied.

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

Optional territory-wide filter. Use this instead of the city field when you want a province or territory.

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

Optional five-digit NOC 2021 occupation codes. Each code is sent to Job Bank's source search filter.

## `datePosted` (type: `string`):

Limit the source search by Job Bank's published date facet.

## `lmiaStatus` (type: `string`):

Uses Job Bank's LMIA requested and approved facets. Select both to create two source-filtered searches and merge their unique jobs.

## `onlyLmiaRequested` (type: `boolean`):

Backward-compatible shortcut for existing tasks. When enabled, it returns both requested and approved LMIA postings unless a specific LMIA status is selected above.

## `excludeStudent` (type: `boolean`):

Applies Job Bank's source filter and checks the posting flag before a row is saved.

## `sourceType` (type: `string`):

Keep official Job Bank postings, external job-board postings, or both. The Actor verifies this from the individual posting.

## `employmentSchedules` (type: `array`):

Keep full-time, part-time, or both. The source search is narrowed first and each extracted posting is checked again.

## `workplaceTypes` (type: `array`):

Keep postings where Job Bank explicitly publishes the selected work location wording.

## `languages` (type: `array`):

Keep postings with an explicit source language requirement.

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

Choose Job Bank's best-match ordering or its most-recent ordering.

## `monitoringMode` (type: `string`):

For scheduled runs, save only new, updated, and expired jobs by default. Unchanged jobs are not written or charged in change-only mode.

## `stateName` (type: `string`):

Separates one saved watchlist, customer, or schedule from another. Keep it stable for recurring runs.

## `resetState` (type: `boolean`):

Treat the next successful monitoring run as a fresh baseline. This affects only the current state name and search scope.

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

Maximum unique job records collected across every supplied search. Monitoring expiry detection waits for an uncapped complete search.

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

The default Apify proxy configuration is suitable for Job Bank's public server-rendered pages.

## Actor input object example

```json
{
  "startUrls": [],
  "searchKeyword": "",
  "location": "",
  "searches": [],
  "provinces": [],
  "nocCodes": [],
  "datePosted": "any",
  "lmiaStatus": "any",
  "onlyLmiaRequested": false,
  "excludeStudent": false,
  "sourceType": "any",
  "employmentSchedules": [],
  "workplaceTypes": [],
  "languages": [],
  "sortBy": "relevance",
  "monitoringMode": "off",
  "stateName": "default",
  "resetState": false,
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Structured current jobs or meaningful monitoring changes.

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

Discovery, filtering, failure, and monitoring counts for the run.

# 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": [],
    "searchKeyword": "",
    "location": "",
    "searches": [],
    "provinces": [],
    "nocCodes": [],
    "datePosted": "any",
    "lmiaStatus": "any",
    "onlyLmiaRequested": false,
    "excludeStudent": false,
    "sourceType": "any",
    "employmentSchedules": [],
    "workplaceTypes": [],
    "languages": [],
    "sortBy": "relevance",
    "monitoringMode": "off",
    "stateName": "default",
    "resetState": false,
    "maxItems": 100,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("getascraper/jobbank-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": [],
    "searchKeyword": "",
    "location": "",
    "searches": [],
    "provinces": [],
    "nocCodes": [],
    "datePosted": "any",
    "lmiaStatus": "any",
    "onlyLmiaRequested": False,
    "excludeStudent": False,
    "sourceType": "any",
    "employmentSchedules": [],
    "workplaceTypes": [],
    "languages": [],
    "sortBy": "relevance",
    "monitoringMode": "off",
    "stateName": "default",
    "resetState": False,
    "maxItems": 100,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("getascraper/jobbank-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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": [],
  "searchKeyword": "",
  "location": "",
  "searches": [],
  "provinces": [],
  "nocCodes": [],
  "datePosted": "any",
  "lmiaStatus": "any",
  "onlyLmiaRequested": false,
  "excludeStudent": false,
  "sourceType": "any",
  "employmentSchedules": [],
  "workplaceTypes": [],
  "languages": [],
  "sortBy": "relevance",
  "monitoringMode": "off",
  "stateName": "default",
  "resetState": false,
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call getascraper/jobbank-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=getascraper/jobbank-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/QujUhE42pEQwAQbvR/builds/GxmyljH1b80dJXgCr/openapi.json
