Canada's governments buy over $200 billion in goods and services every year. Every tender is public — but the data is scattered across a dozen portals. Here is how to get it programmatically in 2026: every official source, their APIs and formats, and a working setup for automated monitoring.
The problem: one country, a dozen portals
If you sell to the Canadian public sector — or build tools for companies that do — you quickly discover there is no single API for Canadian tenders:
- Federal tenders live on CanadaBuys, the Government of Canada's system of record.
- Québec runs its own system, SEAO, covering ministries, municipalities, schools and hospitals.
- Nova Scotia publishes procurement data through its open-data portal.
- Ontario, BC, Alberta and Saskatchewan run separate portals (Jaggaer, Ivalua and custom systems) with no public data feeds.
- Commercial aggregators like MERX charge subscription fees for a unified view.
The good news: the three biggest open sources publish machine-readable data under open licences. Let's walk through them.
Source 1: CanadaBuys (federal) — open CSV, updated every 2 hours
CanadaBuys publishes official open data files under the Open Government Licence:
- New tender notices — refreshed every 2 hours during business hours
- Open tender notices — all tenders currently accepting bids, refreshed daily
- Award notices and contract history — who won what
The files are bilingual CSVs with a documented data dictionary. A quick look with Python:
import pandas as pd
url = "https://canadabuys.canada.ca/opendata/pub/openTenderNotice-ouvertAvisAppelOffres.csv"
df = pd.read_csv(url)
print(df.shape) # thousands of open tenders
print(df.columns[:8]) # bilingual column names like "title-titre-eng"
Watch out for three things: bilingual column names (title-titre-eng, tenderClosingDate-appelOffresdateCloture), occasional schema drift, and multi-category rows (procurementCategory can be CNST,SRV).
Source 2: SEAO (Québec) — OCDS JSON on Données Québec
Québec publishes SEAO data as weekly JSON files in the Open Contracting Data Standard (CC-BY). Each weekly file contains tender notices and awarded contracts as OCDS "releases" — with buyer, UNSPSC classification, award values in CAD.
The catch: file URLs change weekly, so you must query the CKAN catalogue API first to find the latest resources, then download and parse each file. Titles are French-only.
Source 3: Nova Scotia — awarded tenders on Socrata
Nova Scotia publishes awarded public tenders — government plus municipalities, universities, school boards and health authorities — with the winning vendor and award amount:
https://data.novascotia.ca/resource/m6ps-8j6u.json?$limit=100&$order=awarded_date DESC
This is market intelligence rather than live opportunities: who wins contracts in your category, and at what price.
What about Ontario, BC, Alberta?
As of mid-2026, none of them publish open data feeds for current tenders. Their portals are JavaScript applications that require browser-level scraping. If you only need federal + Québec + Nova Scotia, you can skip that complexity entirely.
The DIY reality check
Building this yourself means: three different formats (CSV, OCDS JSON, Socrata), bilingual normalization, weekly-changing URLs, schema drift, deduplication across sources, and a scheduler with failure alerts. It's a fun weekend project — and then an unpaid maintenance job forever, because government portals change things without notice.
The 5-minute alternative: a ready-made API
I maintain an Apify Actor that does all of the above and returns one normalized feed:
Canada Tenders Scraper — Federal, Quebec, Nova Scotia
One schema across all three sources: title (EN/FR), buyer, category, UNSPSC, closing date, contact, notice URL, award value where applicable. Example input:
{
"sources": ["canadabuys", "seao"],
"keywords": ["software", "cloud", "informatique"],
"closingWithinDays": 30,
"onlyNewSinceLastRun": true,
"maxResults": 500
}
The onlyNewSinceLastRun flag is the key feature for monitoring: schedule the Actor daily, and each run returns only tenders you haven't seen before. Connect it to email or Slack through Apify integrations and you have a tender-alert system for a few dollars a month — no subscription, you pay per record ($4 per 1,000).
Calling it from your own code:
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("truenorthdata/canada-tenders-scraper").call(run_input={
"keywords": ["construction", "roofing"],
"closingWithinDays": 21,
"maxResults": 200,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["titleEn"] or item["titleFr"], "|", item["closingDate"], "|", item["buyerOrg"])
Everything runs on official open data — no proxies, no scraping grey zones, no logins.
FAQ
Is scraping Canadian government tenders legal? The sources above are official open-data programs published for reuse (Open Government Licence – Canada, CC-BY Québec). Yes.
How fresh is the data? Federal: every 2 hours for new tenders. Québec: weekly files. Nova Scotia: monthly award updates.
Can I get tenders for a specific province only? Yes — filter by region (e.g. "Ontario") on federal data, or select the Québec/Nova Scotia sources directly.
What's the cheapest way to try it? Apify's free tier includes $5 of credit — enough for ~1,000 tender records to see if the data fits your use case.
Questions or a source you'd like covered (Ontario? BC? municipal portals?) — open an issue on the Actor page and I'll take a look.
Top comments (0)