# Health Canada Recalls & Safety Alerts Scraper (`crawlerbros/health-canada-recalls-scraper`) Actor

Scrape Health Canada's official Recalls and Safety Alerts database (recalls-rappels.canada.ca) - food, health product, consumer product and vehicle recalls. Search by keyword, filter by organization/category/recall class, or fetch full recall detail by ID or URL.

- **URL**: https://apify.com/crawlerbros/health-canada-recalls-scraper.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** Automation, Developer tools, Integrations
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Health Canada Recalls & Safety Alerts Scraper

Scrape [Health Canada's official Recalls and Safety Alerts database](https://recalls-rappels.canada.ca) — the single government feed covering **food recalls (CFIA)**, **health product recalls (drugs, medical devices, natural health products, vaccines, veterinary drugs)**, **consumer product recalls** and **vehicle recalls (Transport Canada)**. Search by keyword, browse the latest recalls, or pull the full detail of a specific recall by its ID or URL — hazard classification, affected products, companies, and the full issue/action text included.

No login, no API key, no cookies required. Works out of the box on the Apify free plan.

### What this actor does

- **Three modes:** `search` (keyword search or browse the latest recalls), `byIds` (exact lookup by recall ID), `byUrls` (direct fetch of recall URLs you already have)
- **Full coverage:** food recalls (CFIA), health product recalls (drugs, medical devices, natural health products, vaccines, veterinary drugs), consumer product recalls, and vehicle recalls (Transport Canada)
- **Filters:** issuing organization, category, recall class/severity, archived status, and date range
- **Bilingual:** fetch either the English or French official-language edition
- **Empty fields are omitted** — you'll never see empty strings or `null` values in the output

### Output per recall

Each dataset item is one recall/safety alert:

- `recallId` — Health Canada's numeric recall node ID
- `title` — recall/advisory title
- `alertType` — e.g. `Food recall warning`, `Vehicle recall`, `Consumer product recall`, `Health product recall`
- `product` — affected product summary
- `issueSummary` / `issueDetails` — short and full description of the hazard
- `action` / `actionDetails` — short and full "what to do" guidance for consumers
- `category` / `categoryTop` / `categorySub` — recall category and its top-level/sub-category split
- `organization` — issuing organization (e.g. `Canadian Food Inspection Agency`, `Health Canada`, `Transport Canada`)
- `recallClass` — hazard classification (`Type I-III` or `Class 1-3`)
- `audience` — who the recall is intended for
- `companies` — recalling firm(s), manufacturer(s), distributor(s)
- `brands` — brand name(s) affected
- `distributionRegions` — Canadian province(s)/region(s) where the product was distributed
- `distributionScope` — depth of distribution (e.g. retail, wholesale), populated only for older pre-migration recall pages that don't carry a structured `distributionRegions` list
- `affectedProducts` — structured table of affected SKUs (brand, product, size, UPC, lot/codes) when the source publishes one
- `affectedProductsText` — plain-text affected-products list when no structured table is published (common for vehicle recalls)
- `images` — product image URL(s)
- `identificationNumber` — Health Canada's public reference number (e.g. `RA-81929`)
- `agencyReferenceId` / `agencyReferenceIdLabel` — the issuing agency's own internal recall number (e.g. CFIA ID, Transport Canada recall number)
- `safetyRisk` / `correctiveActions` / `background` — extended sections published for some recalls (notably vehicle recalls)
- `additionalDetails` — any further named sections the source publishes beyond the standard set
- `lastUpdated` — date the recall was last updated (`YYYY-MM-DD`)
- `recallDate` — date the recall was originally issued (`YYYY-MM-DD`), when published separately from `lastUpdated`
- `originalPublishedDate` — the recall's original publish date (`YYYY-MM-DD`) from the source's revision history, distinct from both `lastUpdated` (most recent edit) and `recallDate`
- `sourceUrl` — canonical URL of the recall on recalls-rappels.canada.ca
- `language` — `en` or `fr`, the official-language edition the record was fetched from
- `recordType` — always `recall`
- `scrapedAt` — UTC timestamp of when the record was scraped

Fields that don't apply to a given recall (e.g. `affectedProducts` for a recall with no product table) are simply omitted.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | select | `search` | `search` / `byIds` / `byUrls` |
| `searchQuery` | string | `food` | Free-text keyword search (mode=search). Leave blank to browse the latest recalls. |
| `organization` | select | – | Restrict to a specific issuing organization/branch (mode=search) |
| `category` | select | – | Restrict to a curated recall category/sub-category (mode=search) |
| `categoryFreeText` | string | – | Advanced: exact numeric category ID, overrides `category` (mode=search) |
| `recallClass` | select | – | `Type I`/`Type II`/`Type III` (health products) or `Class 1`/`Class 2`/`Class 3` (food/consumer products) |
| `archived` | boolean | `false` | Include archived (closed-out) recalls in addition to active ones |
| `dateFrom` | date | – | Only recalls last updated on/after this date |
| `dateTo` | date | – | Only recalls last updated on/before this date |
| `sortBy` | select | `latest` | `latest` or `oldest` updated first (mode=search) |
| `language` | select | `en` | `en` or `fr` — official-language edition of the database to search/fetch (mode=search, mode=byIds). `byUrls` always uses whichever language the given URL points to. |
| `ids` | array | – | Recall node IDs (mode=byIds), e.g. `["82414"]` |
| `urls` | array | – | Direct recall URLs (mode=byUrls) |
| `maxItems` | integer | `20` | Hard cap on emitted records (1-500) |

#### Example: browse the latest food recalls

```json
{
  "mode": "search",
  "searchQuery": "food",
  "maxItems": 20
}
```

#### Example: search for a specific hazard, filtered by class

```json
{
  "mode": "search",
  "searchQuery": "salmonella",
  "category": "144",
  "recallClass": "Class 1",
  "maxItems": 50
}
```

#### Example: lookup by recall ID

```json
{
  "mode": "byIds",
  "ids": ["81929", "82204"]
}
```

#### Example: lookup by recall URL

```json
{
  "mode": "byUrls",
  "urls": ["https://recalls-rappels.canada.ca/en/alert-recall/heeva-fine-foods-brand-pistachio-nuts-recalled-due-salmonella"]
}
```

### Use cases

- **Product safety monitoring** — watch for recalls affecting a brand, ingredient, or product category.
- **Compliance dashboards** — track recall class (Type I-III / Class 1-3) severity trends over time.
- **Consumer safety alerts** — feed a notification pipeline for recalls matching your customers' products.
- **Research & journalism** — analyze recall volume by organization, category, or region over the years.
- **Import/export compliance** — cross-check shipments and inventory against active vehicle, food, and consumer product recalls.

### FAQ

**Does this cover food, drug, medical device, consumer product AND vehicle recalls?**
Yes — recalls-rappels.canada.ca is Health Canada's unified feed across all of these categories, and this actor scrapes all of them.

**How far back does the data go?**
The source publishes recalls going back over a decade, including archived/closed-out recalls (set `archived: true` to include them).

**Can I filter by organization (e.g. only Transport Canada recalls)?**
Yes, use the `organization` input field.

**What does `recallClass` mean?**
It's Health Canada's severity classification — `Type I` (most serious) through `Type III` for health products, and `Class 1` (most serious) through `Class 3` for food and consumer products.

**Do I need a proxy or cookies?**
No. The source is a public government website with no anti-bot protection, so this actor runs reliably on the Apify free plan with no proxy configuration required.

**Can I look up a recall I already have a link to?**
Yes — use `mode: "byUrls"` with the recall's URL, or `mode: "byIds"` if you only have its numeric ID.

**Why did I get fewer records than my `maxItems`?**
Two possible reasons: your filter combination genuinely has fewer matches than requested, or (for very broad, unfiltered/lightly-filtered searches) the source site's own search pages only let you page a few hundred results deep even though it reports a much larger total match count. Narrow the search with a keyword, `organization`, `category`, or date range to reach specific results beyond that depth.

**Is this affiliated with Health Canada?**
No, this is a third-party actor that scrapes the public recalls-rappels.canada.ca website. It is not affiliated with, endorsed by, or operated by Health Canada or the Government of Canada.

# Actor input Schema

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

What to fetch.

## `searchQuery` (type: `string`):

Free-text keyword search across the recall/safety-alert title, product, and issue. Leave blank to browse the latest recalls sorted by last-updated date.

## `organization` (type: `string`):

Restrict results to recalls published by a specific issuing organization/branch.

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

Restrict results to a curated recall category/sub-category. Use `categoryFreeText` instead to target a category not listed here.

## `categoryFreeText` (type: `string`):

Advanced: exact numeric category ID from the site's own taxonomy (overrides `category` when set).

## `recallClass` (type: `string`):

Restrict results to a specific hazard/recall classification. Health-product recalls use Type I-III; food and consumer-product recalls use Class 1-3.

## `archived` (type: `boolean`):

Include recalls/alerts that have been archived (closed out) in addition to active ones.

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

Only include recalls last updated on or after this date (YYYY-MM-DD).

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

Only include recalls last updated on or before this date (YYYY-MM-DD).

## `language` (type: `string`):

Official-language edition of recalls-rappels.canada.ca to fetch. Applies to `search` (which index to browse/search) and `byIds` (which URL to build for each ID). `byUrls` always uses whichever language the given URL itself points to.

## `sortBy` (type: `string`):

Order in which matching recalls are walked and emitted.

## `ids` (type: `array`):

Numeric Health Canada recall node IDs, e.g. `82414` (found in every recall URL / `/node/{id}` redirect).

## `urls` (type: `array`):

Direct recalls-rappels.canada.ca recall URLs, e.g. `https://recalls-rappels.canada.ca/en/alert-recall/...`.

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

Hard cap on emitted records.

## Actor input object example

```json
{
  "mode": "search",
  "searchQuery": "food",
  "organization": "",
  "category": "",
  "recallClass": "",
  "archived": false,
  "language": "en",
  "sortBy": "latest",
  "ids": [],
  "urls": [],
  "maxItems": 20
}
```

# Actor output Schema

## `recalls` (type: `string`):

Dataset containing all scraped recalls and safety alerts.

# 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 = {
    "mode": "search",
    "searchQuery": "food",
    "organization": "",
    "category": "",
    "recallClass": "",
    "archived": false,
    "language": "en",
    "sortBy": "latest",
    "ids": [],
    "urls": [],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/health-canada-recalls-scraper").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 = {
    "mode": "search",
    "searchQuery": "food",
    "organization": "",
    "category": "",
    "recallClass": "",
    "archived": False,
    "language": "en",
    "sortBy": "latest",
    "ids": [],
    "urls": [],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/health-canada-recalls-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mode": "search",
  "searchQuery": "food",
  "organization": "",
  "category": "",
  "recallClass": "",
  "archived": false,
  "language": "en",
  "sortBy": "latest",
  "ids": [],
  "urls": [],
  "maxItems": 20
}' |
apify call crawlerbros/health-canada-recalls-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=crawlerbros/health-canada-recalls-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/pdGLuwOFZE8zyn7eU/builds/pdpdYgGPItPZTnFa4/openapi.json
