# CanadaBuys Tender Notices (Government of Canada) (`loonieledger/canadabuys-tender-notices`) Actor

Canadian federal tenders from CanadaBuys open data: open, new today or fiscal-year history. Filter by keyword, UNSPSC, region. No personal contact data.

- **URL**: https://apify.com/loonieledger/canadabuys-tender-notices.md
- **Developed by:** [Keegan Carpentier](https://apify.com/loonieledger) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 results

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

## CanadaBuys Tender Notices – Canadian Federal Tenders (Open Data)

Turn the official **CanadaBuys** open-data files into clean, filterable tender records. CanadaBuys is published by Public Services and Procurement Canada. You can pull the tenders that are **open right now**, the notices **published today**, or a full **fiscal-year history back to 2022-2023**. Filter by keyword, goods, services or construction, UNSPSC or GSIN code, region, notice type, and publish or closing date. You can also schedule it as a "new notices and amendments only" bid alert.

- ✅ Official open data (Open Government Licence – Canada). No logins, no page scraping
- ✅ **Privacy-safe output**: buyer contact names, emails and phone numbers are *never* output, and emails and phone numbers inside descriptions are redacted. That makes the data safer to load into CRMs, AI pipelines or resold datasets
- ✅ English plus optional French title and description
- ✅ `onlyNew` mode returns only new notices **and new amendments** since the last run
- ✅ A working CanadaBuys link on every notice, including notices that came in from MERX or SAP Ariba

### Who it's for

Canadian **SMEs, contractors, consultants and IT and construction firms** that bid on federal work, **bid-alert and market-intelligence services**, and **analysts** sizing federal demand by category, region or department.

### Input

| Field | What it does | Default |
|---|---|---|
| `source` | `open` (all open tenders, refreshed daily), `new` (published today, refreshed about every 2 hours), or a fiscal-year file `2022-2023` … `2026-2027` | `open` |
| `keywords` | Title or description contains **any** of these | `["software","cloud"]` (prefill) |
| `procurementCategories` | `GD` goods, `SRV` services, `CNST` construction, `SRVTGD` services related to goods | all |
| `unspscPrefixes` / `gsinPrefixes` | Code prefixes, e.g. UNSPSC `43` (IT equipment) or `8111` (computer services) | all |
| `regions` | Region of delivery or opportunity contains, e.g. `Alberta` or `National Capital Region` | all |
| `noticeTypes` | e.g. `Request for Proposal`, `Advance Contract Award Notice` | all |
| `publishedWithinDays`, `closingAfter` | Date filters | none |
| `includeFrench`, `includeDescription`, `descriptionMaxChars` | Output shaping | EN only, description on, 2,000 characters |
| `onlyNew` | Scheduled alert mode | off |
| `maxItems` | Hard cap on results (and on cost) | 200 |

Example: Alberta construction work, bilingual, from the 2025-26 archive

```json
{ "source": "2025-2026", "regions": ["Alberta"], "procurementCategories": ["CNST"],
  "includeFrench": true, "maxItems": 500 }
```

### Output (real record, live test on 29 Sep 2026, shortened)

```json
{
  "referenceNumber": "cb-920-9790984",
  "amendmentNumber": "000",
  "solicitationNumber": "W8485-TBIPS2025-01",
  "title": "Software Developers",
  "status": "Open",
  "noticeType": "RFP against Supply Arrangement",
  "procurementMethod": "Competitive - Open bidding",
  "procurementCategory": ["Services"],
  "publicationDate": "2026-09-28",
  "closingDate": "2026-10-14T14:00:00",
  "unspsc": ["81111600", "81111704"],
  "unspscDescription": ["Computer programmers", "Database design"],
  "regionsOfDelivery": ["National Capital Region (NCR)", "Canada"],
  "contractingEntity": {"name": "Department of National Defence (DND)", "city": "Ottawa", "province": "Ontario", "country": "Canada"},
  "canadaBuysUrl": "https://canadabuys.canada.ca/en/tender-opportunities/tender-notice/cb-920-9790984",
  "description": "NOTICE OF PROPOSED PROCUREMENT\nThis requirement is only open to the below list of pre-qualified suppliers …",
  "licence": "Open Government Licence – Canada",
  "attribution": "Contains information licensed under the Open Government Licence – Canada."
}
```

The full field list is in `.actor/dataset_schema.json`, and more real rows are in `sample_output.json`. Closing dates are given exactly as CanadaBuys publishes them (Eastern time).

### Bid-alert setup

Save a Task with your filters and `onlyNew: true`. Schedule it daily after about 14:00 UTC (the *open* file is rebuilt each morning, Eastern time), or every few hours with `source: "new"`. Then connect Slack, email or Sheets on *Run succeeded*. The Actor remembers `referenceNumber` plus `amendmentNumber`, so each amendment shows up once. Its state lives in the named key-value store `canadabuys-tenders-state`.

### Pricing

**Pay per result.** You're charged once for each notice written to the dataset. `maxItems` and Apify's maximum cost per run are both honoured, and the run stops cleanly at the cap.

### Data source, licence and privacy

- Source: *CanadaBuys tender notices*, Public Services and Procurement Canada: https://open.canada.ca/data/en/dataset/6abd20d4-7a1c-4b38-baa2-9525d0bb2fd2 (CSV files on canadabuys.canada.ca/opendata/pub/).
- Licence: **Open Government Licence – Canada** (https://open.canada.ca/en/open-government-licence-canada). Attribution is included on every row.
- The OGL **does not cover personal information**, so this Actor drops the contact-name, email, phone, fax and contact-address columns and redacts emails and phone numbers found in free text. Business names (buyers and listed suppliers) are kept.
- **Unofficial tool**. It isn't affiliated with or endorsed by the Government of Canada, PSPC or CanadaBuys. Always check deadlines, amendments and bid documents on the official notice before you bid. Coverage is limited to what CanadaBuys publishes in these files (mostly federal).

# Actor input Schema

## `source` (type: `string`):

Open = all currently open tenders (refreshed daily). New = notices published today (refreshed every 2 hours). Fiscal-year files contain every notice published in that April–March year.

## `keywords` (type: `array`):

Keep notices whose title or description contains ANY of these words/phrases (case-insensitive). Leave empty for all.

## `procurementCategories` (type: `array`):

GD = goods, SRV = services, CNST = construction, SRVTGD = services related to goods. Leave empty for all.

## `unspscPrefixes` (type: `array`):

Keep notices with any UNSPSC code starting with these digits (e.g. 43 = IT equipment, 8111 = computer services).

## `gsinPrefixes` (type: `array`):

Keep notices with any GSIN code starting with these characters (e.g. N70, D302).

## `regions` (type: `array`):

Keep notices whose region of delivery or opportunity contains any of these (e.g. Alberta, National Capital Region, Canada).

## `noticeTypes` (type: `array`):

e.g. Request for Proposal, Request for Information, Request for Standing Offer, Advance Contract Award Notice. Case-insensitive exact match.

## `publishedWithinDays` (type: `integer`):

0 = no limit.

## `closingAfter` (type: `string`):

Optional. Drop notices that close before this date.

## `includeFrench` (type: `boolean`):

Adds titleFr and descriptionFr fields.

## `includeDescription` (type: `boolean`):

Plain-text tender description (HTML removed; email addresses and phone numbers are redacted).

## `descriptionMaxChars` (type: `integer`):

Truncate descriptions to this many characters (0 = no limit).

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

Remembers reference + amendment numbers across runs so scheduled runs return only new notices or new amendments.

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

Stop after this many results. Controls cost.

## Actor input object example

```json
{
  "source": "open",
  "keywords": [
    "software",
    "cloud"
  ],
  "publishedWithinDays": 0,
  "includeFrench": false,
  "includeDescription": true,
  "descriptionMaxChars": 2000,
  "onlyNew": false,
  "maxItems": 200
}
```

# Actor output Schema

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

Tender notices written to the default dataset

# 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 = {
    "keywords": [
        "software",
        "cloud"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("loonieledger/canadabuys-tender-notices").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 = { "keywords": [
        "software",
        "cloud",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("loonieledger/canadabuys-tender-notices").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 '{
  "keywords": [
    "software",
    "cloud"
  ]
}' |
apify call loonieledger/canadabuys-tender-notices --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,loonieledger/canadabuys-tender-notices"
        }
    }
}
```

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/2P9LawHpShUgd7TAH/builds/rYsko44Hu23crtoFM/openapi.json
