# Canada Express Entry Draws (IRCC Rounds) Tracker (`coachable_bufflehead/ircc-express-entry-draws`) Actor

Get every Canada Express Entry round of invitations from IRCC: date, round type, invitations issued, CRS cutoff and tie-breaking rule. Filter by category (CEC, PNP, French, Healthcare, STEM) and monitor new draws.

- **URL**: https://apify.com/coachable\_bufflehead/ircc-express-entry-draws.md
- **Developed by:** [Qi Wang](https://apify.com/coachable_bufflehead) (community)
- **Categories:** News, Jobs, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.01 / actor start

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 Express Entry Draws (IRCC Rounds) Tracker

Get every **Canada Express Entry round of invitations** ("draw") as clean JSON: draw number, date, round type, category, eligible programs, invitations issued, **CRS cutoff** and the tie-breaking rule. Filter by category (CEC, PNP, French, Healthcare, STEM, Trades …) or date, get only the latest draw, and run it on a Schedule to be notified when IRCC holds a new round.

> **Unofficial tool.** This Actor is not affiliated with, endorsed by or operated by Immigration, Refugees and Citizenship Canada (IRCC) or the Government of Canada. All data comes from information IRCC publishes openly on [canada.ca](https://www.canada.ca/en/immigration-refugees-citizenship/corporate/mandate/policies-operational-instructions-agreements/ministerial-instructions/express-entry-rounds.html). It is not immigration advice. Always check the official round page before acting on it.

### What you can use it for

- **Monitor new draws**: run every few hours, get the newest round, and send it to email, Slack, Telegram or a webhook (see below).
- **Immigration consultants and newsletters**: publish draw results and CRS trends minutes after IRCC posts them.
- **AI agents**: a small, fast tool call that answers "what was the last CEC draw cutoff?" through the [Apify MCP server](https://mcp.apify.com) or the Apify API.
- **Analysis**: export all rounds since 2015 to CSV/Excel to chart CRS cutoffs and invitation volumes by category.

### How it works

The Actor downloads the JSON file IRCC uses for its "Rounds of invitations" table:

`https://www.canada.ca/content/dam/ircc/documents/json/ee_rounds_123_en.json`

It normalizes every round, filters them locally, sorts them newest first and saves them to the dataset. It is a single plain HTTP request: no browser and no scraping of HTML pages, so a run takes a few seconds. If canada.ca refuses the direct connection, the Actor retries once through Apify Proxy.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `category` | string | `all` | Only rounds of this kind. Case-insensitive. See the list below. |
| `dateFrom` | string | – | `YYYY-MM-DD`. Only rounds held on or after this date. |
| `maxResults` | integer | `50` | 1–1000. Rounds are returned newest first. |
| `latestOnly` | boolean | `false` | Return only the most recent round that matches the other filters. |

Categories (derived from IRCC's round type):

| `category` | Matches round types such as |
|---|---|
| `general` | General, No Program Specified (all-program rounds) |
| `cec` (or `CEC`) | Canadian Experience Class |
| `pnp` (or `PNP`) | Provincial Nominee Program |
| `fsw` / `fst` | Federal Skilled Worker / Federal Skilled Trades |
| `french` | French-language proficiency |
| `healthcare` | Healthcare (and social services) occupations |
| `stem` | STEM occupations |
| `trades` | Trade occupations |
| `transport`, `agriculture`, `education` | Transport, agriculture and agri-food, education occupations |
| `physicians`, `senior-managers`, `military` | Physicians / senior managers with Canadian work experience, skilled military recruits |

Example: the last 10 CEC rounds of 2026.

```json
{
    "category": "CEC",
    "dateFrom": "2026-01-01",
    "maxResults": 10
}
```

### Output

One dataset item per round:

| Field | Description |
|---|---|
| `drawNumber` | Round number as IRCC publishes it (string; a few early rounds are `91a`/`91b`). |
| `date` | Date of the round, `YYYY-MM-DD`. |
| `roundType` | Round type exactly as IRCC names it, e.g. `Canadian Experience Class`, `Healthcare and social services occupations (Version 2)`. |
| `category` | Normalized category (see above), or `other` for a new kind of round. |
| `program` | Programs whose candidates were eligible. |
| `invitationsIssued` | Number of invitations to apply. |
| `crsCutoff` | CRS score of the lowest-ranked candidate invited. |
| `tieBreakRule` | Tie-breaking rule: candidates at the cutoff score who entered the pool before this time were invited. `null` if IRCC did not publish one. |
| `url` | Official IRCC page of the round. |
| `fetchedAt` | ISO timestamp of this run. |

Example item:

```json
{
    "drawNumber": "446",
    "date": "2026-09-29",
    "roundType": "Canadian Experience Class",
    "category": "cec",
    "program": "Canadian Experience Class",
    "invitationsIssued": 2000,
    "crsCutoff": 518,
    "tieBreakRule": "February 13, 2026 at 20:48:08 UTC",
    "url": "https://www.canada.ca/en/immigration-refugees-citizenship/corporate/mandate/policies-operational-instructions-agreements/ministerial-instructions/express-entry-rounds/invitations.html?q=446",
    "fetchedAt": "2026-10-01T20:00:00.000Z"
}
```

You can download the dataset as JSON, CSV, Excel or HTML, or read it with the Apify API.

### Monitor new Express Entry draws (with an Apify Schedule)

IRCC does not announce draws in advance, and they can happen on any weekday. To be told about each new round:

1. **Save a Task** for this Actor with the input you care about, for example every new round:

   ```json
   { "latestOnly": true }
   ```

   or only new PNP rounds: `{ "category": "PNP", "latestOnly": true }`.
2. **Create a Schedule** (Apify Console > Schedules > Create new) that runs the Task, for example every 2 hours on weekdays: `0 */2 * * 1-5`, time zone `America/Toronto`.
3. **Connect an integration** to the Task (Integrations tab): email, Slack, Google Sheets, Zapier/Make, or an HTTP webhook on "Run succeeded".
4. **Only react to new rounds**: each run returns the latest round, so compare its `drawNumber` with the one you saw last (in Zapier/Make, use a "filter" or "only continue if new" step; in your own code, store the last `drawNumber`). A different `drawNumber` means IRCC has held a new round.

Each run downloads a single file and pushes one item, so scheduled monitoring is cheap.

### FAQ

**How quickly does a new draw show up?**
As soon as IRCC updates its JSON file, which usually happens the same day as the round, together with the official web page.

**Why is `drawNumber` a string?**
IRCC numbered two early rounds `91a` and `91b`. Keeping it a string keeps the column stable.

**What does "tie-breaking rule" mean?**
When several candidates have exactly the cutoff score, IRCC invites those who submitted their profile before the date and time shown.

**IRCC launched a new category and it shows as `other`. Is that a bug?**
The raw `roundType` is always returned, so no data is lost. Open an issue and the category list will be updated.

**Does it include the CRS score distribution of the pool?**
Not yet. The output is one row per round with the fields above.

**Is this immigration advice?**
No. It reports what IRCC published. For your own case, use the official IRCC pages or a licensed consultant.

### Local development

```bash
npm install
npm test           # unit tests (normalization, categories, filters, sorting)
npm run build
apify run --input '{"category":"CEC","maxResults":5}'
```

`IRCC_EE_ROUNDS_URL` overrides the source URL, for example to point at a local copy of the JSON file when canada.ca is not reachable from your network.

### Data source

Data: Immigration, Refugees and Citizenship Canada (IRCC), "Express Entry rounds of invitations", public information published on canada.ca. Use of canada.ca content is subject to the [canada.ca Terms and conditions](https://www.canada.ca/en/transparency/terms.html). This Actor only reformats the published facts and links every round back to its official page.

# Actor input Schema

## `category` (type: `string`):

Only return rounds of this kind. Leave empty for all rounds. Case-insensitive; short names such as CEC, PNP, FSW, FST, French, Healthcare, STEM, Trades also work.

## `dateFrom` (type: `string`):

Only return rounds held on or after this date (YYYY-MM-DD).

## `maxResults` (type: `integer`):

Maximum number of rounds to return, newest first.

## `latestOnly` (type: `boolean`):

Return only the most recent round that matches the filters. Useful for monitoring new draws on a Schedule.

## Actor input object example

```json
{
  "category": "all",
  "maxResults": 50,
  "latestOnly": false
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset containing the matching Express Entry rounds, newest first

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("coachable_bufflehead/ircc-express-entry-draws").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("coachable_bufflehead/ircc-express-entry-draws").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 '{}' |
apify call coachable_bufflehead/ircc-express-entry-draws --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,coachable_bufflehead/ircc-express-entry-draws"
        }
    }
}
```

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/oS9Vmmhq3iqUpZbQT/builds/kl0qFZQjukJIYzcmQ/openapi.json
