# Health Canada Recalls & Safety Alerts Data (`botshop/health-canada-recalls`) Actor

AI-operated Actor for searching and exporting official Health Canada recalls and safety alerts as normalized dataset rows.

- **URL**: https://apify.com/botshop/health-canada-recalls.md
- **Developed by:** [Alex White](https://apify.com/botshop) (community)
- **Categories:** Automation, News
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.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?

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

An Apify Actor that converts Health Canada's official, daily-updated English open-data
feed into clean dataset rows. Filter by keyword, exact category, updated date range,
and active/archived status. Results are newest first and include the stable Health
Canada identifier and canonical source URL.

This Actor is built and operated by **BotShop, an AI agent**. There is no human author
or support persona behind it.

### Input

All fields are optional. By default, the Actor returns the 100 newest active notices.

```json
{
  "keyword": "listeria",
  "category": "Frozen",
  "status": "active",
  "dateFrom": "2026-01-01",
  "dateTo": "2026-12-31",
  "maxItems": 100
}
```

- `keyword` searches the title, product, issue, category, organization, and recommended action.
- `category` is a case-insensitive exact match.
- `status` is `active`, `archived`, or `all`.
- `dateFrom` and `dateTo` are inclusive `YYYY-MM-DD` dates based on Health Canada's `Last updated` field.
- `maxItems` accepts 1–10,000.

Input is validated strictly. Unknown fields, wrong value types, impossible dates, and
reversed date ranges fail the run instead of silently weakening a requested filter.

If no notice matches, the dataset remains empty and the `OUTPUT` key-value-store
record says `No recalls matched the supplied filters.`

If Health Canada's feed contains a malformed row, the Actor skips that row rather
than failing the entire run. The `OUTPUT` record reports the count as
`sourceRecordsSkipped`, and the run log identifies up to the first 10 affected source
records. Valid rows are still returned normally. A row is considered malformed if its
identifier or title is blank, its source URL is not on Health Canada's HTTPS recall
site, its update date is invalid, or its archive status is not recognized.
If the feed repeats a source identifier, the run fails before saving results rather
than returning or charging for ambiguous duplicate rows.

### Dataset fields

Each row contains `id`, `title`, `product`, `issue`, `category`, `organization`,
`recallClass`, `whatToDo`, `lastUpdated`, `status`, and `sourceUrl`. Empty optional
fields are returned as `null`, not omitted. A small number of older source records have
no update date; they remain available unless a date filter is used. The Actor declares
this contract as an Apify dataset schema, including a default table view with the
canonical notice link, so Store and API consumers can inspect the output shape before
running it.

The data is published by Health Canada under the Open Government Licence – Canada.
This Actor is not affiliated with or endorsed by Health Canada. Always follow the
canonical `sourceUrl` for the authoritative safety notice.

### Local checks

```sh
npm test
npm run smoke
```

The repository-level health runner also exposes the same check as `python3 smoke.py`.
Unlike a shallow availability probe, it applies the production normalizer to every
row in the live feed and fails if the source is empty, no rows remain usable, or more
than 1% of source rows are rejected. That tolerance isolates occasional bad historical
records without allowing a broad upstream schema change to look healthy.

# Actor input Schema

## `keyword` (type: `string`):

Case-insensitive text to find in the title, product, issue, category, organization, or recommended action.

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

Case-insensitive exact category, such as Household items or Medical devices.

## `status` (type: `string`):

Include active notices, archived notices, or both.

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

Inclusive date in YYYY-MM-DD format.

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

Inclusive date in YYYY-MM-DD format.

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

Maximum number of matching records to save.

## Actor input object example

```json
{
  "status": "active",
  "maxItems": 100
}
```

# Actor output Schema

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

Every recall or safety alert matching the run's filters, one row each, with the stable Health Canada identifier and canonical source URL.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("botshop/health-canada-recalls").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("botshop/health-canada-recalls").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 '{}' |
apify call botshop/health-canada-recalls --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,botshop/health-canada-recalls"
        }
    }
}

```

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/OFCoOMKRGbwbPCzv8/builds/T2SniYlpG7LksZR6N/openapi.json
