Statistics Canada Data API

Narwhal reads any Statistics Canada monthly, quarterly or annual series by vector ID. For example, statcan:v41690973 is Canada all-items CPI, a monthly index with the unit label 2002=100 and observations from 1914-01.

What you can read

The Statistics Canada data API has routes for a series definition, historical observations and the latest observation. For CPI, GDP, labour or trade data, identify the vector for the measure you need, then use its ID in each request.

Responses keep the source's unit label and seasonal adjustment information. Observation values are decimal strings, and release dates appear when available. Missing periods are omitted. A live series has no revision history or vintages.

Find the vector for a table

Search the catalogue with source=statcan and a query of 2-100 characters. Each result identifies a table, with its table number in the title, such as 10-10-0106-01. The result has the ID template statcan:v{vector}.

Search Statistics Canada tables
curl --header "Authorization: Bearer $NARWHAL_API_KEY" \
  "https://api.narwhalapi.com/v1/economics/catalogue?q=consumer%20price&source=statcan&limit=2"

Find the vector number on the table's page at statcan.gc.ca, then replace {vector} with that number. Narwhal has no route yet that lists a table's vectors. Catalogue search is open on every plan and does not call Statistics Canada.

Read the series

Pass the full series ID in the id query parameter. This request reads July through September 2026, with inclusive start and end periods. Monthly ranges use YYYY-MM; quarterly ranges use YYYY-Qn, and annual ranges use YYYY.

Read monthly CPI observations
import os
import requests

response = requests.get(
    "https://api.narwhalapi.com/v1/economics/catalogue/series/observations",
    headers={"Authorization": f"Bearer {os.environ['NARWHAL_API_KEY']}"},
    params={
        "id": "statcan:v41690973",
        "start": "2026-07",
        "end": "2026-09",
        "limit": 3,
    },
    timeout=10,
)
response.raise_for_status()
print(response.json())

The captured observations from 27 October 2026 have these values and release dates:

CPI response
{
  "id": "statcan:v41690973",
  "title": "Canada;All-items",
  "frequency": "monthly",
  "unit": "extended",
  "unit_label": "2002=100",
  "seasonal_adjustment": "not_stated",
  "attribution": "Contains information licensed under the Open Government Licence - Canada. Source: Statistics Canada. Values normalised by Narwhal.",
  "licence_url": "https://open.canada.ca/en/open-government-licence-canada",
  "fetched_at": "2026-10-27T12:30:59Z",
  "observations": [
    {"period": "2026-07", "value": "169.9", "released_on": "2026-08-17"},
    {"period": "2026-08", "value": "169.8", "released_on": "2026-09-14"},
    {"period": "2026-09", "value": "170.0", "released_on": "2026-10-19"}
  ],
  "next_cursor": null
}

Read several at once

Use /v1/economics/catalogue/latest with up to 50 distinct IDs in the ids query parameter, separated by commas. The response contains the latest observations and a missing list. REST and the MCP tool economics_read_catalogue_latest_batch use the same batch operation.

A batch is charged in one step, with 1 call per series returned. Stale answers are uncharged.

What is not served

Daily, weekly, multi-year, fiscal-year and fiscal-quarter vectors return 404 not_found. A table's presence in the search index does not change those frequency limits.

Supported observations retain status flags such as provisional or estimated when supplied. Check those flags alongside the period and unit label before using a value in a calculation. The API does not fill gaps or reconstruct earlier versions of a series.

Limits by plan

LimitFreeBasicPro
Uncached fetches per account per UTC day101001,000
History windowLast 12 monthsLast 5 yearsFull history

Every plan keeps at least the latest 5 annual observations and latest 4 quarterly observations, even when they fall outside its history window. Cached series remain readable after the daily fetch allowance is used.

A request that needs an uncached fetch after the allowance is used returns 429 fetch_limit_reached, with Retry-After to 00:00 UTC. A range wholly before the permitted window returns 403 plan_upgrade_required, subject to the annual and quarterly floors. See error handling for request failures.

Licence

Statistics Canada data is under the Open Government Licence - Canada. Every series response includes attribution and licence_url; keep that licence information with the data you use.

The search index contains 1,914 current Statistics Canada tables. Search results identify tables, while vector IDs identify the individual series read through the API.

What is a Statistics Canada vector id?

A vector number identifies an individual Statistics Canada series. Narwhal writes it as statcan:v<vector>, for example statcan:v41690973. A table number identifies the table where you find the vector; it cannot replace the vector in a series request.

How often is Statistics Canada data updated here?

The cache lasts 6 hours for monthly series, 12 hours for quarterly series and 24 hours for annual series. Once the next release is due, refreshes run every 15 minutes.

If Statistics Canada is unreachable, a kept copy can be returned with stale: true. With no cached copy, the request returns 503 upstream_busy and a Retry-After header.

Published .

Next steps