# Canada Economic Calendar: StatCan CPI, GDP & Jobs Release Dates (`yadroo/statcan-release-calendar`) Actor

Canada's official statistics release schedule: every release due in the coming two weeks plus the release-date history and published future dates of the 28 major economic indicators — title, reference period, the 08:30 Eastern moment in UTC, status and the release link.

- **URL**: https://apify.com/yadroo/statcan-release-calendar.md
- **Developed by:** [Samat Makatov](https://apify.com/yadroo) (community)
- **Categories:** Business, News, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 calendar entry returneds

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

## Canada Economic Calendar: StatCan CPI, GDP & Jobs Release Dates

Canada's official statistics release schedule: every release due in the coming two weeks plus the release-date history and published future dates of the 28 major economic indicators — title, reference period, the 08:30 Eastern moment in UTC, status and the release link.

The rows come from Statistics Canada's own schedule of *The Daily* — the two-week list of upcoming releases and the machine-readable schedule of the major economic indicators, which reaches back to March 2012 and forward as far as the office has published. Each row says **what** is released, **which period the number covers**, and **the exact moment it becomes public**, already converted to UTC (08:30 Eastern is 12:30Z in summer and 13:30Z in winter). No API key, no proxy, no browser — two plain GET requests per run.

This is a calendar, not a data feed: it carries release moments and reference periods, never actual, forecast or previous figures.

### Use cases

- **Trading and risk desks**: line a Canadian macro model up with the minute the number lands — `releaseDateUtc` and `hoursUntilRelease` need no timezone arithmetic on your side.
- **Newsroom and content planning**: the two-week window lists every release, including the small surveys and the studies that never reach a market calendar.
- **Agents and chatbots**: `nextRelease` answers "when is the next Canadian CPI / GDP / jobs number" with exactly one row per topic, so a tool call always has the same shape.
- **Event studies and backtests**: pull the release dates of one indicator for any range back to 2012, each with the link to the release that was published that morning.
- **Data engineering**: schedule ingestion and refresh jobs against the published calendar instead of polling a source that is not out yet.
- **Calendar monitoring**: run it on a schedule with `onlyNew` and get a row only when something is added or moved.

### Input

Nothing is required — with default settings the run returns the next two weeks of releases.

| Field | Type | Default | Allowed values / notes |
|---|---|---|---|
| `mode` | string | `upcoming` | `upcoming`, `keyIndicators`, `nextRelease` — see [Modes](#modes) |
| `query` | string | — | Keyword kept against the release title and the reference period, case-insensitive (`price index`, `trade`, `crop`). Used in `upcoming` and `keyIndicators` |
| `indicators` | string\[] | all | Short codes from the [indicator dictionary](#the-28-major-economic-indicators). Used in `keyIndicators` |
| `topics` | string\[] | — | One keyword per question; each returns one row. Required in `nextRelease` |
| `dateFrom` | string | — | Earliest release date, `YYYY-MM-DD` (an Eastern calendar date) |
| `dateTo` | string | — | Latest release date, `YYYY-MM-DD` |
| `withinDays` | integer | 14 | 1–1095. Used **only** when `dateFrom` and `dateTo` are both empty, and never in `nextRelease` |
| `onlyUpcoming` | boolean | false | Drop releases whose 08:30 Eastern moment has passed. Always on in `nextRelease` |
| `onlyNew` | boolean | false | Output only entries missing from the previous run with the same filters |
| `sortOrder` | string | `soonest` | `soonest` or `latest` (by release moment) |
| `maxItems` | integer | 30 | 1–1000 |
| `fields` | string\[] | all | Keep only these output fields, in this order |

### Reference

#### Modes

| Mode | Reads | Covers | Answers |
|---|---|---|---|
| `upcoming` | the two-week schedule | about 14 days around today, ~50 releases | "everything Canada publishes in the coming two weeks" |
| `keyIndicators` | the major-indicator schedule **and** the two-week page | March 2012 → as far ahead as the office has published | "every CPI date since 2012", "the major indicators still ahead" |
| `nextRelease` | both lists | the whole published schedule, from now on | "when is the next GDP" — one row per topic |

`keyIndicators` keeps only releases whose title is one of the 28 dictionary titles; everything else on the two-week page is dropped in that mode. The same release printed on both lists is returned once, with the article link if one exists.

#### Date windows

- Both `dateFrom` and `dateTo` empty → the window is today up to `withinDays` days ahead (in `nextRelease`: the whole published schedule).
- Only `dateFrom` → `withinDays` days from it. Only `dateTo` → everything from 2012 up to it.
- Dates are the Eastern calendar dates the schedule prints; every row also carries the moment in UTC.
- A window that reaches past the end of the published schedule returns the releases that exist, and the run's status message says where the schedule stops. It is not an error.

#### The 28 major economic indicators

`indicatorCode` is filled by matching the release title against these printed titles, longest title first. A variant keeps the code of the title it extends: `Wholesale trade: Advance indicator` → `wholesale-trade`. A title that is not in the list gets `indicatorCode: null` and `isKeyIndicator: false` — it is never matched to the nearest neighbour.

| Code | Printed title |
|---|---|
| `cpi` | Consumer Price Index |
| `labour-force-survey` | Labour Force Survey |
| `gdp-by-industry` | Gross domestic product by industry |
| `gdp-income-expenditure` | Gross domestic product, income and expenditure |
| `gdp-by-industry-provinces` | Gross domestic product by industry: Provinces and territories |
| `retail-trade` | Retail trade |
| `wholesale-trade` | Wholesale trade |
| `merchandise-trade` | Canadian international merchandise trade |
| `manufacturing` | Monthly Survey of Manufacturing |
| `payroll-employment` | Payroll employment, earnings and hours, and job vacancies |
| `building-permits` | Building permits |
| `investment-building-construction` | Investment in building construction |
| `investment-non-residential` | Investment in non-residential building construction |
| `non-residential-capital-repair` | Non-residential capital and repair expenditures |
| `ippi-rmpi` | Industrial product and raw materials price indexes |
| `balance-of-payments` | Canada's balance of international payments |
| `international-investment-position` | Canada's international investment position |
| `securities-transactions` | Canada's international transactions in securities |
| `national-balance-sheet` | National balance sheet and financial flow accounts |
| `quarterly-financial-statistics` | Quarterly financial statistics for enterprises |
| `labour-productivity` | Labour productivity, hourly compensation and unit labour cost |
| `tourism-indicators` | National tourism indicators |
| `travel-canada` | Travel between Canada and other countries |
| `farm-income` | Farm income |
| `field-crop-estimates` | Model-based principal field crop estimates |
| `field-crop-areas` | Principal field crop areas |
| `field-crop-production` | Production of principal field crops |
| `field-crop-stocks` | Stocks of principal field crops |

A code with an obvious typo is corrected and the correction is logged (`gdp-by-industy` → `gdp-by-industry`); the printed title works in place of the code. Anything else stops the run with a message naming the value — the search is never quietly widened.

#### Source lists

| `source` | What it is | Time range | Article link |
|---|---|---|---|
| `upcoming-schedule` | the two-week list of every forthcoming release | the current window, ~14 days | no — the row links to the schedule page |
| `key-indicators` | the machine-readable schedule of the 28 indicators | March 2012 onwards | yes for releases already published |

### Examples

**Everything Canada publishes in the next two weeks** — trading desks, newsroom planning.

```json
{ "mode": "upcoming", "withinDays": 14, "sortOrder": "soonest", "maxItems": 25 }
```

**Consumer Price Index release dates of 2024 and 2025** — event studies that need the moment the number became public.

```json
{ "mode": "keyIndicators", "indicators": ["cpi"], "dateFrom": "2024-01-01", "dateTo": "2025-12-31", "maxItems": 30 }
```

**When is the next GDP, jobs and retail number** — one row per topic for an agent or a dashboard tile.

```json
{ "mode": "nextRelease", "topics": ["gross domestic product", "labour force survey", "retail trade"], "maxItems": 5 }
```

**Only the major indicators still ahead** — a Canada macro panel.

```json
{ "mode": "keyIndicators", "onlyUpcoming": true, "withinDays": 120, "sortOrder": "soonest", "maxItems": 20 }
```

**The whole 2026 schedule by indicator** — planning refresh jobs and reporting deadlines for a year.

```json
{ "mode": "keyIndicators", "dateFrom": "2026-01-01", "dateTo": "2026-12-31", "sortOrder": "soonest", "maxItems": 60 }
```

**The trade family of releases for 2025** — one keyword collects merchandise, retail and wholesale trade.

```json
{ "mode": "keyIndicators", "query": "trade", "dateFrom": "2025-01-01", "dateTo": "2025-12-31", "maxItems": 40 }
```

### Output

A real row from cloud run `AYTJWJefDsBHbGtka` (`mode: "keyIndicators"`, `indicators: ["cpi"]`, 2024–2025, 24 rows):

```json
{
  "releaseTitle": "Consumer Price Index",
  "referencePeriod": "December 2023",
  "releaseDateEastern": "2024-01-16",
  "releaseTimeEastern": "08:30",
  "releaseDateUtc": "2024-01-16T13:30:00.000Z",
  "dayOfWeek": "Tuesday",
  "hoursUntilRelease": -23576.4,
  "status": "published",
  "isKeyIndicator": true,
  "indicatorCode": "cpi",
  "dailyUrl": "https://www150.statcan.gc.ca/daily-quotidien/240116/dq240116a-eng.htm",
  "scheduleWindow": null,
  "source": "key-indicators",
  "mode": "keyIndicators",
  "url": "https://www150.statcan.gc.ca/daily-quotidien/240116/dq240116a-eng.htm",
  "fetchedAt": "2026-09-24T21:51:56.586Z"
}
```

| Field | Type | Meaning |
|---|---|---|
| `releaseTitle` | string | The release as the schedule names it; `null` only on a `found: false` topic row |
| `referencePeriod` | string | null | The period the numbers cover (`July 2026`, `second quarter 2026`, `2024/2025`); `null` when the source prints none |
| `releaseDateEastern` | string | Release date, `YYYY-MM-DD`, the Eastern calendar date the schedule prints |
| `releaseTimeEastern` | string | Always `08:30` — the moment the bulletin is published, not a per-release time |
| `releaseDateUtc` | string | The release moment in ISO-8601 UTC, daylight saving already applied |
| `dayOfWeek` | string | Weekday of the release date |
| `hoursUntilRelease` | number | Hours from the run to the release; negative once it is out |
| `status` | string | `scheduled` before the moment, `published` after it |
| `isKeyIndicator` | boolean | Whether the title is one of the 28 major economic indicators |
| `indicatorCode` | string | null | The dictionary code, or `null` for a release outside the 28 |
| `dailyUrl` | string | null | The published release article, when it exists |
| `scheduleWindow` | string | null | The two-week window the row was printed in (`upcoming-schedule` rows) |
| `source` | string | `upcoming-schedule` or `key-indicators` |
| `mode` | string | The mode that produced the row |
| `url` | string | The article when known, otherwise the schedule page the row came from |
| `fetchedAt` | string | Fetch time, ISO-8601 UTC |
| `matchedTopic` | string | `nextRelease` only: the topic this row answers |
| `found` | boolean | `nextRelease` only: `false` when nothing is scheduled for that topic yet |

Dataset views: **Release calendar** (the full calendar), **Major indicators** (indicator code, dates, article link), **Next release per topic**.

A `SUMMARY` record goes to the run's key-value store: the window, the pages read, how many entries were parsed, how many duplicates were merged, where the published schedule ends, and how many rows were written.

### Use it from code / agents

```bash
curl -X POST "https://api.apify.com/v2/acts/yadroo~statcan-release-calendar/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode":"nextRelease","topics":["consumer price index","gross domestic product"],"maxItems":5}'
```

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('yadroo/statcan-release-calendar').call({
    mode: 'upcoming',
    withinDays: 14,
    maxItems: 25,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

```python
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("yadroo/statcan-release-calendar").call(run_input={
    "mode": "keyIndicators", "indicators": ["cpi"], "dateFrom": "2024-01-01", "dateTo": "2025-12-31", "maxItems": 30,
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
```

MCP: add `https://mcp.apify.com` to Claude / Cursor / any MCP client and call the `yadroo/statcan-release-calendar` tool with the same JSON input. For an agent, `nextRelease` is the safest shape: one row per topic, `found: false` instead of a missing row, so the answer never depends on how many rows came back. `fields` trims the payload, e.g. `["releaseTitle", "referencePeriod", "releaseDateUtc", "hoursUntilRelease"]`.

### Pricing

Pay per event: **$0.001 per run start + $0.002 per dataset row**. The start event is charged on every run, including runs that return no rows.

| Run | Rows | Cost |
|---|---|---|
| The next two weeks (`upcoming`, `maxItems` 25) | 25 | 0.001 + 25 × 0.002 = **$0.051** |
| Next release for 3 topics (`nextRelease`) | 3 | 0.001 + 3 × 0.002 = **$0.007** |
| A full year of the major indicators (`keyIndicators`, 2026) | 200 | 0.001 + 200 × 0.002 = **$0.401** |

Apify plan discounts apply to both events: the row price falls to $0.0018 on Bronze, $0.0016 on Silver and $0.0014 on Gold and above. A typical run uses 256 MB for about 20 seconds, so the platform compute behind it is a fraction of a cent.

### Limits & FAQ

**How far ahead does the schedule go?** Two different distances. The two-week list covers about 14 days and is refreshed by the office; the major-indicator schedule reaches further — on 24 September 2026 it ran to 31 March 2027, roughly two quarters ahead. There is no fixed horizon: the run's status message and the `coverageEnd` field of `SUMMARY` say where the published schedule ends on the day you run it.

**Why is every time 08:30?** Because everything in *The Daily* is published at 08:30 Eastern on working days. The source prints no per-release time, so `releaseTimeEastern` is the bulletin's time and `releaseDateUtc` is that moment converted (12:30Z under daylight time, 13:30Z in winter). The actor never invents a more precise time.

**Are the dates final?** No. The source states the list is compiled for planning purposes and may be updated. Dates move, and statutory holidays shift a whole week. Use `onlyNew` on a scheduled run to be told when an entry appears or changes — a rescheduled release counts as new.

**Do I get the numbers themselves?** No. This actor returns the calendar: what is released, for which period, when. Actual, forecast and previous values are not part of the schedule and are not produced here.

**Why does a two-week run sometimes return fewer rows than `maxItems`?** Because the window only holds what it holds — around 50 releases, of which the ones from today onwards are returned by default. Set `dateFrom` to an earlier date to include the days of the window that have already passed.

**Nothing matched my filter — is that an error?** No, it is an empty result with an explanation in the status message. An input the actor cannot honour (an unknown indicator code, a malformed date, `nextRelease` without topics) fails the run instead, with a message naming the value to change.

**Rate limits and politeness.** Two GET requests per run, with the 2-second crawl delay the site's robots.txt asks for, plus bounded retries on throttling. No login, no captcha, no proxy.

**Personal data.** The two-week page prints a media contact name and phone number beside each release. They are parsed away and never written to the dataset.

**Languages.** English titles only; the French edition of the schedule is not read.

***

Made by **Yadroo**. Data source: Statistics Canada, release schedule of *The Daily*, used under the [Statistics Canada Open Licence](https://www.statcan.gc.ca/en/reference/licence). Statistics Canada does not endorse this actor.

Sibling actors: [bls-release-calendar](https://apify.com/yadroo/bls-release-calendar) · [ons-release-calendar](https://apify.com/yadroo/ons-release-calendar) · [us-treasury-yields](https://apify.com/yadroo/us-treasury-yields) · [world-bank-indicators](https://apify.com/yadroo/world-bank-indicators) · [sec-company-financials](https://apify.com/yadroo/sec-company-financials)

# Actor input Schema

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

`upcoming` reads the official two-week schedule: every release due, including the small surveys and the studies, with its reference period. `keyIndicators` reads the schedule of the 28 major economic indicators — every date back to March 2012 and the future dates already published — so a date range in the past returns a release-date history. `nextRelease` answers "when is the next one" for each entry of `topics`: one row per topic, the earliest release still ahead.

## `query` (type: `string`):

Keep only releases whose title or reference period contains this text, case-insensitive, e.g. "price index", "trade", "employment", "crop". Empty = every release in the window. Used in `upcoming` and `keyIndicators`.

## `indicators` (type: `array`):

Keep only these major economic indicators, by short code. Empty = all of them. A release whose title is not one of the 28 dictionary titles comes back with `indicatorCode: null` and `isKeyIndicator: false`; a variant such as an advance indicator keeps the code of the indicator its title starts with. Used in `keyIndicators`; ignored in the other modes. See README → Reference dictionaries for the full list.

## `topics` (type: `array`):

One keyword per topic; each returns exactly one row — the next release still ahead whose title contains it. A topic with nothing scheduled in the published horizon returns a row with `found: false` instead of disappearing, so a task keeps one row per topic. Used in `nextRelease`.

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

Earliest release date, YYYY-MM-DD. Set `dateFrom` and `dateTo` to read a fixed window — the way to get a release-date history, e.g. every Consumer Price Index date of 2024 and 2025. Leave both empty to use `withinDays`.

## `dateTo` (type: `string`):

Latest release date, YYYY-MM-DD. The major-indicator schedule starts in March 2012; how far ahead it reaches is whatever Statistics Canada has published. A window beyond that returns the rows that exist and the run says where the schedule ends.

## `withinDays` (type: `integer`):

Used only when `dateFrom` and `dateTo` are both empty: releases from today up to N days ahead. The two-week schedule of `upcoming` covers about 14 days, so a larger value simply returns everything it holds; in `keyIndicators` 120 or 365 shows the quarters ahead.

## `onlyUpcoming` (type: `boolean`):

Drop releases whose moment (08:30 Eastern of the printed date) has already passed, also inside an explicit date range. The two-week schedule starts a few days in the past, so this turns it into a pure "what is still coming" feed. `nextRelease` always applies it.

## `onlyNew` (type: `boolean`):

Remember release title plus release moment in this actor's key-value store and output only entries that were missing from the previous run. A rescheduled release counts as new, so a scheduled task emits exactly the changes to the calendar. The first run outputs everything it finds.

## `sortOrder` (type: `string`):

Order rows by the release moment. `latest` first is the useful one for a history window. `nextRelease` sorts its own matches by moment.

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

Stop after this many rows. The two-week schedule holds about 50 releases; a full year of the 28 major indicators is about 230 rows.

## `fields` (type: `array`):

Keep only these output fields, in this order, e.g. \["releaseTitle", "referencePeriod", "releaseDateUtc"]. Empty = all fields of the mode.

## Actor input object example

```json
{
  "mode": "upcoming",
  "indicators": [
    "cpi",
    "gdp-by-industry",
    "labour-force-survey"
  ],
  "topics": [
    "consumer price index",
    "gross domestic product",
    "labour force survey"
  ],
  "withinDays": 14,
  "onlyUpcoming": false,
  "onlyNew": false,
  "sortOrder": "soonest",
  "maxItems": 30
}
```

# Actor output Schema

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

No description

# 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 = {
    "indicators": [
        "cpi",
        "gdp-by-industry",
        "labour-force-survey"
    ],
    "topics": [
        "consumer price index",
        "gross domestic product",
        "labour force survey"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("yadroo/statcan-release-calendar").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 = {
    "indicators": [
        "cpi",
        "gdp-by-industry",
        "labour-force-survey",
    ],
    "topics": [
        "consumer price index",
        "gross domestic product",
        "labour force survey",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("yadroo/statcan-release-calendar").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 '{
  "indicators": [
    "cpi",
    "gdp-by-industry",
    "labour-force-survey"
  ],
  "topics": [
    "consumer price index",
    "gross domestic product",
    "labour force survey"
  ]
}' |
apify call yadroo/statcan-release-calendar --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,yadroo/statcan-release-calendar"
        }
    }
}
```

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/ftxeISxJFohWT6tK2/builds/Px4ks4axn0Cmcf2mJ/openapi.json
