Health Canada Medical Device Licence Monitor avatar

Health Canada Medical Device Licence Monitor

Pricing

$15.00 / 1,000 conclusive target checks

Go to Apify Store
Health Canada Medical Device Licence Monitor

Health Canada Medical Device Licence Monitor

Monitor Health Canada MDALL medical device licences and exact product identifiers. Track status, risk class, company and device changes with persistent baselines, batch checks and JSON/CSV exports.

Pricing

$15.00 / 1,000 conclusive target checks

Rating

0.0

(0)

Developer

Vadim Bezrukov

Vadim Bezrukov

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

Monitor Canadian medical device licences and exact product identifiers against Health Canada's Medical Devices Active Licence Listing (MDALL). Keep a watchlist for procurement or regulatory review, then receive structured changes to licence status, risk class, company and optional device membership.

The first run returns a baseline. Repeat the same watchlist to detect changes without building your own comparison database. Export observations through Apify as JSON, CSV or Excel, or connect them to your existing review workflow. Schedule recurring medical device license checks for an existing procurement watchlist.

Health Canada explains that licences can be suspended, cancelled or discontinued and recommends verification whenever a purchase is considered. This monitor is for known Class II, III and IV licences and labelled identifiers. It does not search for suppliers, assess device safety or cover Class I, MDEL, recalls, investigational testing or Special Access.

Quickstart

Start with a saved example and replace its sample values with your own:

{
"monitorKey": "procurement-canada",
"targets": [{"licenceNumber": 102723, "reference": "supplier-001"}],
"mode": "changesOnly",
"firstRunBehavior": "emitCurrent"
}
  1. Add known licence numbers or exact identifiers from product labels.
  2. Run the Actor and inspect the first BASELINE observation.
  3. Repeat with the same monitorKey. Review CHANGE rows; an unchanged check returns outcome=NO_CHANGE.

The bounded default emits a truthful BASELINE and uses three small source requests. Repeat the same monitorKey to compare against the last successful components in the persistent health-canada-mdall-monitor-state KVS. Each input has a result: unchanged inputs emit a compact CHECK with outcome=NO_CHANGE; their full snapshot is omitted in changesOnly mode. Use snapshotAndChanges for full current observations. A CHANGE row includes the current observation and the old/new changed components. baselineOnly still emits a baseline observation and also labels a verified absent first observation BASELINE.

Illustrative change excerpt (simulated, not an actual regulatory event):

{
"record_type": "CHANGE",
"status": "SUCCESS",
"target_key": "LICENCE:102723",
"change_types": ["LICENCE_STATUS_CHANGED", "LICENCE_SUSPENDED"],
"licence_status_code": "S",
"licence_status": "Suspended"
}

Watch licences and device identifiers

{
"monitorKey": "device-membership",
"targets": [
{"licenceNumber": "102723", "includeDevices": true},
{"licenceNumber": 9538, "includeDevices": true}
],
"mode": "snapshotAndChanges"
}

9538 was archived with code O (Discontinued at Renewal) in the 2026-09-06 source probe; it is not an active demo. includeDevices defaults to false: enabling it fetches both complete device arrays once per run (about 45 MB decoded, 7.3 MB over gzip and 302,000 rows in the September 2026 probes), then retains only watched licences. Both active and archived memberships are included; active describes the membership's source state. Identifiers under every licence are not downloaded wholesale.

{
"monitorKey": "label-identifiers",
"targets": [
{"deviceIdentifier": "09P9422", "reference": "labelled-sku"},
{"deviceIdentifier": "P02-14030"}
]
}

Identifiers preserve punctuation, case and leading zeroes; only surrounding whitespace and Unicode NFC are normalized. Substring API hits must pass exact comparison. An exact identifier can map to several devices/licences: matched_devices preserves all associations; matched_device is null unless there is exactly one. A moved-licence event requires one old and one new association with the same device ID. Other association changes are explicit.

Inputs and limits

1–1,000 targets, each with exactly one identity. Licence numbers are positive 32-bit integers or ASCII digit strings. Identifiers and references are limited to 200 characters. monitorKey permits 1–80 letters, digits, underscores or hyphens. Unknown properties are rejected. includeDevices is valid only for licence targets. Identical duplicate targets receive DUPLICATE without a second check or charge; conflicting options/reference for one identity invalidate all copies. Reference changes between runs never create source changes. Enabling device monitoring creates a component baseline instead of reporting every existing device as new. The first successful observation of a new or re-enabled component is included in the Dataset, even in changesOnly mode. If enabling devices fails, its baseline remains pending until a successful check. Up to 100 exact associations are supported per identifier; larger results fail explicitly rather than truncate.

Scheduling, API, webhook and MCP

Use one scheduled run per monitorKey at a time. For daily 07:00 UTC monitoring, create an Apify Schedule with cron 0 7 * * *, timezone UTC, and the saved input above. A webhook configuration example is {"eventTypes":["ACTOR.RUN.SUCCEEDED"],"requestUrl":"https://your-service.example/mdall"}. The receiver should fetch RUN_SUMMARY and handle PARTIAL even if the platform run succeeded. Route only record_type=CHANGE rows to review/alert integrations. These examples do not create schedules, Tasks or webhooks.

Example API request:

curl -X POST 'https://api.apify.com/v2/acts/automa-flow~health-canada-medical-device-licence-monitor/runs?memory=512&timeout=1800&maxTotalChargeUsd=0.02' \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H 'Content-Type: application/json' \
--data '{"monitorKey":"procurement-canada","targets":[{"licenceNumber":102723}]}'

Direct MCP endpoint: https://mcp.apify.com?tools=automa-flow/health-canada-medical-device-licence-monitor. Agent intent: “Check licence 102723 for my procurement watchlist, compare the baseline and return changes or explicit failed components.” Execution requires the customer's authenticated Apify account. Limited permissions allow access to Actor-created persistent storage across runs. Authenticated initialize and tools/list exposed the Actor during validation on 2026-09-07. REST cloud checks verified repeat-run baseline access; execution and payment through MCP remain unverified. The observed direct tool does not expose maxTotalChargeUsd. Use the REST API example above when you need a specific $0.02 cap; the configured run default is $15 for up to 1,000 checks. Read RUN_SUMMARY first, then follow the Dataset link. No source credentials are needed.

Pricing and spending limits

Pay per event: target-checked $0.015 per unique conclusive SUCCESS or NOT_FOUND check, with no fixed start or completion fee. An unchanged verified check is billable; changes never add a second charge. Failures, partial targets, invalid inputs, duplicates and skipped targets are free. Apify synthetic start and Dataset events are disabled. Platform usage is included in the check price. All prices are USD; no subscription is required.

Conclusive targets in one completed runEvent total
1$0.015
10$0.150
100$1.500
1,000$15.000

Thirty daily 10-target runs cost $4.50; four weekly 100-target runs cost $6.00. These are event totals, not measured platform costs or revenue forecasts. One rate applies to all plans. Volume discounts require evidence of paid repeat use and adequate margins across source conditions. The Actor uses effective SDK prices when applying maxTotalChargeUsd. At the limit, unprocessed targets receive SKIPPED and retain their baseline. Completed observations remain available. Failed and partial checks do not consume the allowance for conclusive checks; the Actor continues with the next target while that allowance remains available.

Dataset output is saved before baseline advancement and charging. A durable delivery checkpoint refuses to replay a run interrupted during delivery: start a new run for fresh observations. This avoids duplicate charges at the cost of automatic same-run recovery. KVS write errors fail the run. It is not an atomic transaction across Dataset, KVS and billing; already delivered checks remain valid if a later storage operation fails.

Failure semantics and source freshness

SUCCESS, NOT_FOUND, PARTIAL, SOURCE_FAILED, INVALID_INPUT, DUPLICATE and SKIPPED are separate statuses. Licence NOT_FOUND requires both active and archived lookups to return the validated empty sentinel. Identifier NOT_FOUND requires both valid arrays with no exact hit. HTML 200, malformed JSON, unknown status codes, missing identities, contradictory states, timeouts and exhausted retries are source failures. Retry limits: three attempts and twenty retries across the run; long Retry-After values stop work instead of retrying too early.

Licence, company and device components update independently. An unavailable component is null in the observation and marked SOURCE_FAILED in component_status; its previous successful state and timestamp survive in KVS. Only freshly verified components create changes. Refresh dates are stored but excluded from hashes; a regressed refresh quarantines the affected observation. Simultaneous loss of all previously found licences (at least two) is quarantined as an anomaly.

The API provides no pagination or completeness token. We validate entire bulk arrays and require exact global-absence corroboration before DEVICE_REMOVED. If a missing membership's device still exists under any licence, membership is PARTIAL and no removal event is emitted. This conservative rule can delay a real removal. Device active-to-archived transitions are supported directly from bulk membership evidence. The exact device endpoint ignores state and returns one association, so it is not used to decide membership status.

The active/archive filter means absence/presence of cancellation/removal dates, not a safety determination. Licence status labels use the official code table. Dates describe the public database refresh, which may lag real-world events. Devices use (licence_number, device_id) membership identity; device_id alone is not unique across licences. Do not overlap runs using the same monitorKey: KVS has no atomic compare-and-swap; the stale-write check is not a distributed lock.

Views “Changes”, “Current observations”, and “Not found / partial” expose relevant columns; use record_type/status filters to select rows. Output schemas are static. Records include source, stable source_id, scraped_at, schema_version and a deterministic fingerprint for downstream append-only history.

Privacy and limitations

Only company ID, name and status are retained. No addresses, contacts, personal names, cookies or credentials are copied into output or logs. Compact last-good state remains in the customer's persistent KVS until they delete it; Dataset history follows their Apify retention settings.

This Actor reports observations from Health Canada's public Medical Devices Active Licence Listing (MDALL). It is an independent tool and is not affiliated with or endorsed by Health Canada. Output should not be treated as legal advice, a product safety determination, or a guarantee of regulatory compliance.

Sources: API guide, MDALL overview, open-data catalogue. Contains information licensed under the Open Government Licence – Canada. The endpoints are licence/, company/, device/ and deviceidentifier/ under https://health-products.canada.ca/api/medical-devices/. Requests are plain HTTPS, with a single HTTP client, three requests in flight, no browser and no proxy.

Local development

Run repository pytest, Ruff and mypy checks. Sanitized fixtures never contact the source in CI. scripts/local_run.py runs a manual local SDK invocation with persistent local storage; scripts/benchmark.py measures the source client without calling a paid Apify service. See the source investigation and benchmark report under experiments/health-canada-medical-device-licence-monitor/.

Version 0.1: initial exact-watchlist implementation, component baselines, typed changes, conservative removals, bounded PPE and static schemas. Cloud publication and permission/cost verification remain separate release gates.