# Canada Drug Product Database API — Health Canada DINs (`nexgensignal/ca-drug-product-records`) Actor

Health Canada's Drug Product Database as data: each DIN with brand name, company, status, active ingredients and strengths, dosage forms, routes, schedules and ATC class. Filter by ingredient, company and status. No API key. Part of NexGen Signal — official-source data products

- **URL**: https://apify.com/nexgensignal/ca-drug-product-records.md
- **Developed by:** [NexGen Signal](https://apify.com/nexgensignal) (community)
- **Categories:** News, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $33.50 / 1,000 canada drug product records

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

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

## 💊 Canada Drug Product Database API — Health Canada DINs

Get Health Canada's Drug Product Database (DPD) as clean JSON — every drug product with a Drug Identification Number (DIN): brand name, company, product class, current status and its date, first market date, active ingredients with strengths, dosage forms, routes of administration, schedules and ATC classes — straight from Health Canada's public DPD API.

Filter by DIN, brand name, active ingredient, company, status, product class, schedule, ATC code, route, dosage form or update date. Most recently updated first.

The unit of output is one **drug product** (one DPD drug code / DIN), with its ingredients and classes joined in. You pay per product delivered; a run that finds nothing costs nothing.

### Who buys this and for what job

- **Pharma market-access, competitive-intelligence and generics teams** tracking approvals and status changes by molecule and company.
- **Pharmacy, health-tech and EHR teams** keeping a DIN reference current.
- **Regulatory and compliance teams** checking product status, schedules and ATC classes.
- **Analysts and researchers** studying the Canadian drug market.

Buyers usually search for this as **"health canada drug product database"** or **"canada din lookup"**.

### 📊 Sample Output

![Table of Health Canada Drug Product Database products containing semaglutide: DIN, brand name, company and status.](https://api.apify.com/v2/key-value-stores/IXCaMKjxSmUTLHhmq/records/ca-drug-product-records.png)

| din | brand_name | company_name | status | last_update_date |
|---|---|---|---|---|
| 02571528 | SANDOZ SEMAGLUTIDE | SANDOZ CANADA INCORPORATED | Approved | 2026-10-05 |
| 02571501 | SANDOZ SEMAGLUTIDE | SANDOZ CANADA INCORPORATED | Approved | 2026-10-05 |
| 02552698 | WEGOVY | NOVO NORDISK CANADA INC | Marketed | 2026-10-05 |
| 02528541 | WEGOVY | NOVO NORDISK CANADA INC | Marketed | 2026-10-05 |
| 02528533 | WEGOVY | NOVO NORDISK CANADA INC | Marketed | 2026-10-05 |
| 02528525 | WEGOVY | NOVO NORDISK CANADA INC | Marketed | 2026-10-05 |

Rows from live run `g5oppPtddb3NQSqLM` on Apify (the Store example: active ingredient semaglutide, 10 products). Notice the most recently updated products first, with status (Approved, Marketed) on every row.

### ✅ What you get

Every field of each record:

- `record_id` — cA-DPD:<drug code>; stable, use it to upsert.
- `drug_code` — DPD internal drug code.
- `din` — drug Identification Number (DIN).
- `brand_name` — brand name.
- `descriptor` — descriptor, if any.
- `product_class` — human, Veterinary, Disinfectant or Radiopharmaceutical.
- `company_name` — company that holds the product.
- `number_of_active_ingredients` — number of active ingredients.
- `ai_group_number` — active ingredient group number.
- `active_ingredients` — list of {name, strength, strength_unit, dosage_value, dosage_unit}.
- `status` — current status, e.g. Marketed, Approved, Cancelled Post Market, Dormant.
- `status_date` — date of the current status.
- `original_market_date` — date first marketed.
- `dosage_forms` — dosage forms, e.g. Tablet.
- `routes` — routes of administration.
- `schedules` — schedules, e.g. Prescription, OTC.
- `atc` — list of {code, name} ATC classes.
- `last_update_date` — last update in the DPD.
- `source` — publisher database.
- `source_url` — dataset page.
- `licence` — licence notice.
- `attribution` — source line.
- `observed_at` — when this run read it (UTC).

### ⚙️ Sample inputs

**1. The Store example — products containing semaglutide**

```json
{
  "ingredientContains": ["semaglutide"],
  "maxRecords": 10
}
```

Joined 58,329 products with their ingredients and classes, matched 51 and returned the 10 most recently updated in run `g5oppPtddb3NQSqLM`; $0.50 on the Free plan.

**2. Marketed diabetes drugs (ATC A10)**

```json
{
  "atcPrefixes": ["A10"],
  "statuses": ["Marketed"],
  "maxRecords": 40
}
```

Matched 357 and returned 40 in run `g4RZnLZUMXI6x2Sxx`.

**3. Look up one DIN**

```json
{
  "dins": ["00326925"],
  "maxRecords": 5
}
```

Returned the one product in run `wKkuG0S2TXJla6Ja5`.

Input fields:

| Field | Meaning |
|---|---|
| `dins` | Drug Identification Numbers, e.g. 00326925. |
| `brandNameContains` | e.g. Tylenol. |
| `ingredientContains` | e.g. semaglutide, ibuprofen. |
| `companyContains` | e.g. Pfizer. |
| `statuses` | e.g. Marketed, Approved, Cancelled Post Market, Dormant. |
| `productClasses` | Human, Veterinary, Disinfectant, Radiopharmaceutical. |
| `schedulesContain` | e.g. Prescription, OTC, Narcotic. |
| `atcPrefixes` | e.g. A10 (diabetes drugs), N06A (antidepressants). |
| `routesContain` | e.g. Oral, Subcutaneous. |
| `formsContain` | e.g. Tablet, Solution. |
| `updatedFrom` | Only products updated on or after this date, e.g. 2026-01-01. |
| `order` | Sort order. |
| `maxRecords` | Stop after this many products (each is charged once). |

### 🧾 JSON sample record

```json
{
  "record_id": "CA-DPD:107356",
  "drug_code": 107356,
  "din": "02571528",
  "brand_name": "SANDOZ SEMAGLUTIDE",
  "descriptor": "DISPENSES 1 MG DOSES. MULTIDOSE PREFILLED PEN",
  "product_class": "Human",
  "company_name": "SANDOZ CANADA INCORPORATED",
  "number_of_active_ingredients": 1,
  "ai_group_number": "0159870002",
  "active_ingredients": [
    {
      "name": "SEMAGLUTIDE",
      "strength": "1.34",
      "strength_unit": "MG",
      "dosage_value": null,
      "dosage_unit": "ML"
    }
  ],
  "status": "Approved",
  "status_date": "2026-09-16",
  "original_market_date": null,
  "dosage_forms": [
    "Solution"
  ],
  "routes": [
    "Subcutaneous"
  ],
  "schedules": [
    "PRESCRIPTION"
  ],
  "atc": [
    {
      "code": "A10BJ06",
      "name": "SEMAGLUTIDE"
    }
  ],
  "last_update_date": "2026-10-05",
  "source": "Health Canada — Drug Product Database API",
  "source_url": "https://open.canada.ca/data/en/dataset/bf55e42a-63cb-4556-bfd8-44f26e5a36fe",
  "licence": "Contains information licensed under the Open Government Licence – Canada (https://open.canada.ca/en/open-government-licence-canada). Source: Health Canada, Drug Product Database.",
  "attribution": "Source: Health Canada, Drug Product Database (DPD)",
  "observed_at": "2026-10-12T04:08:52Z"
}
```

### 🔧 How it works

1. **Robots check.** `health-products.canada.ca/robots.txt` is requested on every run. It returns HTTP 404, so no robots policy is published; that is recorded. A robots file that disallowed the API would stop the run with nothing charged.

2. **Read the DPD API in bulk.** The actor reads the full lists from seven public DPD endpoints — drug products (58,329 on 12 Oct 2026), status, active ingredients (120,870), dosage forms, routes, schedules and therapeutic (ATC) classes — and joins them by drug code.

3. **Filter and sort.** Products are filtered on product fields first, then on the joined fields, and sorted most recently updated first (or by DIN).

4. **Deliver, then charge.** Records are pushed in batches, each charged after delivery, so records and charges always match.

5. **Receipt.** `RUN_RECEIPT` records the robots result, rows per endpoint, matches, and delivered and charged counts.

No login, API key, proxy or bot workaround. The company-address endpoint is not read.

### 💰 Pricing example

Per drug product delivered, no start fee, no monthly charge:

| Apify plan | Price per drug product |
|---|---|
| Free | $0.05 |
| Bronze | $0.045 |
| Silver | $0.04 |
| Gold, Platinum, Diamond | $0.0335 |

- 10 records (the Store example): $0.50 on the Free plan, $0.335 on Gold.
- 1,000 records (the default cap): $50 on Free, $45 on Bronze, $40 on Silver, $33.50 on Gold.

**Coverage and size.** All products in the DPD: human, veterinary, disinfectant and radiopharmaceutical; marketed, approved, cancelled and dormant (58,329 drug codes on 12 Oct 2026). Status is the current status from the DPD status endpoint. Strengths and units are as published.

### ⚖️ Legal & ToS

Data: Health Canada, Drug Product Database, from its public API (health-products.canada.ca); the dataset is published on open.canada.ca under the Open Government Licence – Canada. Every record carries the licence notice in `licence` and a source line in `attribution`. Not affiliated with or endorsed by Health Canada. Not medical advice.

Product records naming the companies that hold them; no personal data. The DPD robots file returns 404 (no policy), recorded on every run. One public API, declared User-Agent, no login, key, proxy or form.

### ❓ FAQ

**Do I need a Health Canada account?**
No. The DPD API is public.

**What is the drug code?**
The DPD's own key for a product; each record is one drug code, with its DIN alongside.

**How fresh is it?**
As fresh as the DPD API; `last_update_date` shows each product's last update.

**Can I filter by molecule class?**
Yes, with `atcPrefixes`, e.g. N06A for antidepressants.

### 🆘 Troubleshooting

- **0 records for a brand** — `brandNameContains` matches part of the brand name; try the active ingredient instead.
- **Slow run** — the DPD API answered one test run slowly (about three minutes); later runs took seconds. Nothing extra is charged for time.
- **Status filter returns nothing** — use the published wording, e.g. Marketed, Approved, Cancelled Post Market, Dormant.
- **SOURCE UNAVAILABLE message** — the source did not answer after four tries; nothing was charged — run again later.
- **CAPPED message** — your maximum total charge was reached; raise it in the run options.
- **Run failed with "Invalid input"** — a filter value is malformed; the message names the field. Nothing was charged.

### 🔗 Related Actors

- [Drug Label Change Records — NLM DailyMed SPL](https://apify.com/nexgensignal/drug-label-change-records) — US drug label changes (DailyMed).
- [EMA Medicine Status Records — EU Medicines](https://apify.com/nexgensignal/ema-medicine-status-records) — EU medicine status (EMA).
- [CMS Part D Drug Spending — by Drug & Maker](https://apify.com/nexgensignal/cms-part-d-drug-spending-records) — US Medicare Part D drug spending.
- [Colombia Medicine Price Benchmarks — SISMED](https://apify.com/nexgensignal/co-medicine-price-records) — Colombian medicine prices.
- [FDA Recalls API — FDA Enforcement Reports (Food, Drug, Device)](https://apify.com/nexgensignal/fda-recall-risk-records) — US FDA recalls.

🏢 **About NexGen Signal** — official-source data products from government and regulator publications. Browse the catalog: [apify.com/nexgensignal](https://apify.com/nexgensignal)

### ⭐ Found this useful?

If this actor saved you time, a rating on its Apify Store page helps other buyers find it.

Part of NexGen Signal — official-source data products.

# Actor input Schema

## `dins` (type: `array`):

Drug Identification Numbers, e.g. 00326925.

## `brandNameContains` (type: `array`):

e.g. Tylenol.

## `ingredientContains` (type: `array`):

e.g. semaglutide, ibuprofen.

## `companyContains` (type: `array`):

e.g. Pfizer.

## `statuses` (type: `array`):

e.g. Marketed, Approved, Cancelled Post Market, Dormant.

## `productClasses` (type: `array`):

Human, Veterinary, Disinfectant, Radiopharmaceutical.

## `schedulesContain` (type: `array`):

e.g. Prescription, OTC, Narcotic.

## `atcPrefixes` (type: `array`):

e.g. A10 (diabetes drugs), N06A (antidepressants).

## `routesContain` (type: `array`):

e.g. Oral, Subcutaneous.

## `formsContain` (type: `array`):

e.g. Tablet, Solution.

## `updatedFrom` (type: `string`):

Only products updated on or after this date, e.g. 2026-01-01.

## `order` (type: `string`):

Sort order.

## `maxRecords` (type: `integer`):

Stop after this many products (each is charged once).

## Actor input object example

```json
{
  "dins": [],
  "brandNameContains": [],
  "ingredientContains": [
    "semaglutide"
  ],
  "companyContains": [],
  "statuses": [],
  "productClasses": [],
  "schedulesContain": [],
  "atcPrefixes": [],
  "routesContain": [],
  "formsContain": [],
  "order": "recently_updated",
  "maxRecords": 10
}
```

# Actor output Schema

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

The delivered (and billed) records.

## `receipt` (type: `string`):

Robots result, source files, rows read, delivered and charged counts.

# 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 = {
    "ingredientContains": [
        "semaglutide"
    ],
    "maxRecords": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("nexgensignal/ca-drug-product-records").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 = {
    "ingredientContains": ["semaglutide"],
    "maxRecords": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("nexgensignal/ca-drug-product-records").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 '{
  "ingredientContains": [
    "semaglutide"
  ],
  "maxRecords": 10
}' |
apify call nexgensignal/ca-drug-product-records --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nexgensignal/ca-drug-product-records"
        }
    }
}
```

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/pZYr7XUIBv7coSr4a/builds/yTDXg3bdHn2sPEcOR/openapi.json
