# EUDAMED Scraper - EU Medical Devices, UDI & Certificates (`eu_open_data/eudamed-medical-devices`) Actor

Search the EU's official EUDAMED database: 3.5 million medical devices by trade name, manufacturer SRN, risk class, EMDN code or MDR/IVDR, notified-body certificates with expiry monitoring, and economic operators. Clean schema, change detection, no personal data.

- **URL**: https://apify.com/eu\_open\_data/eudamed-medical-devices.md
- **Developed by:** [joeri munsterman](https://apify.com/eu_open_data) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $25.00 / 1,000 device returneds

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

## EUDAMED Scraper - EU Medical Devices, UDI & Certificates

Search the European Commission's official **EUDAMED** database from one Actor: **3.5 million medical devices**, the **certificates** issued by notified bodies, and the **economic operators** behind them — returned in a clean, consistent schema, with change detection between runs and no personal data.

Registration of devices in EUDAMED's UDI/device module has been mandatory since 28 May 2026. Manufacturers, importers and distributors now have to check that the devices they place on the market are registered. This Actor makes that check, and much more, scriptable.

### Three modes

| Mode | What you get | Typical filters |
|---|---|---|
| **Medical devices** | Trade name, Basic UDI-DI, UDI-DI, risk class, legislation, market status, manufacturer and authorised representative | Trade name, manufacturer SRN, risk class, EMDN code, MDR/IVDR, exact UDI |
| **Certificates** | Certificate number, type, status, issue and expiry date, days left, notified body, holder | Holder SRN or name, notified body, status, *expiring within N days* |
| **Economic operators** | Name, SRN, operator type, status, country, city, registration date | Country, type, name, SRN |

Optionally add **device details** per device: intended purpose, legislation, implantable/active/reusable flags and linked certificates.

### Why this one

**Fast, because it asks EUDAMED the right way.** The public API silently returns 20 records per request unless you use the right page-size parameter; this Actor fetches 300 per request. In testing, 1,500 devices came back in about 5 seconds.

**Expiry monitoring without false alarms.** A certificate can appear twice in EUDAMED: an old revision and the reissued one that replaced it. A naive "expiring soon" list flags the old revision even though the successor is valid for years. This Actor marks superseded revisions (`vervangenDoorNieuwereRevisie`) and leaves them out of the expiry filter.

**Change detection.** Run it on a schedule with *Only changes since the previous run* and you get just the records that are new or whose status, version or expiry date changed. The first run builds the baseline.

**No personal data.** EUDAMED publishes e-mail addresses, phone numbers and street addresses of economic operators. For a one-person company those are personal data under the GDPR, so this Actor leaves them out: it is a registry lookup, not a contact list.

### Example output

A device:

```json
{
  "type": "hulpmiddel",
  "handelsnaam": "Pacemaker sæt",
  "basicUdi": "...",
  "udiDi": "...",
  "risicoklasse": "class-iii",
  "risicoklasseNaam": "Class III",
  "wetgeving": "MDR",
  "status": "on-the-market",
  "fabrikant": { "naam": "Sengewald Klinikprodukte GmbH", "srn": "DE-PR-000020748", "status": "active" },
  "details": {
    "medischDoel": "Sterile, disposable procedure pack, combination of devices for disease treatment related to pacemaker.",
    "implanteerbaar": null,
    "certificaten": []
  },
  "bronApiUrl": "https://ec.europa.eu/tools/eudamed/api/devices/udiDiData/..."
}
```

A certificate:

```json
{
  "type": "certificaat",
  "certificaatnummer": "V76 129992 0003",
  "wetgeving": "IVDR",
  "soort": "technical-documentation",
  "status": "issued",
  "verlooptOp": "2031-09-09",
  "dagenTotVerval": 1814,
  "aangemeldeInstantie": "0123",
  "houder": { "naam": "...", "srn": "..." },
  "vervangenDoorNieuwereRevisie": false
}
```

### Typical uses

- **Regulatory and quality teams**: verify that every device you import or distribute is registered, and watch your suppliers' certificates for upcoming expiry.
- **Distributors and hospitals' procurement**: check a supplier's full device portfolio by manufacturer SRN.
- **Market intelligence**: count devices per risk class, EMDN category or manufacturer; follow a competitor's new registrations.
- **Notified bodies and consultants**: monitor certificates by notified body number.

### Pricing

Pay per event, so you pay for results rather than runtime:

| Event | Price |
|---|---|
| `device-record` | $0.025 per device |
| `device-detail` | $0.02 per device, only when details are requested |
| `certificate-record` | $0.05 per certificate |
| `operator-record` | $0.02 per economic operator |
| `change-detected` | $0.02 per new or changed record |

### Notes and limits

- The device list itself does not include legislation. It is filled in when you filter on legislation or request details; otherwise it is empty.
- Details are fetched for up to 300 devices per run, to keep runs within a few minutes.
- The *expiring within* filter works on up to 3,000 certificates per run; narrow by notified body or holder for complete coverage of large sets.
- Data is what manufacturers and notified bodies registered in EUDAMED. This Actor normalises it but does not correct it.

Source: [EUDAMED, European Commission](https://ec.europa.eu/tools/eudamed/). Reuse under the Commission's reuse policy, with attribution.

# Actor input Schema

## `modus` (type: `string`):

Devices, certificates issued by notified bodies, or economic operators (manufacturers, authorised representatives, importers). Only the filters of the chosen section are used.

## `handelsnaam` (type: `string`):

Part of the trade name, e.g. "pacemaker", "catheter", "glucose".

## `fabrikantSrn` (type: `string`):

All devices of one manufacturer or procedure-pack producer, by its EUDAMED Single Registration Number, e.g. DE-MF-000005471.

## `risicoklasse` (type: `string`):

Filter on risk class.

## `wetgeving` (type: `string`):

Filter on the regulation the device is registered under.

## `emdnCode` (type: `string`):

European Medical Device Nomenclature category, e.g. Z12 for in vitro diagnostic devices or C for cardiocirculatory devices.

## `alleenOpDeMarkt` (type: `boolean`):

Skip devices marked as not intended for the EU market.

## `basicUdi` (type: `string`):

Look up one exact Basic UDI-DI.

## `udiDi` (type: `string`):

Look up one exact UDI-DI (the product-level device identifier).

## `metDetails` (type: `boolean`):

Fetch intended purpose, legislation, implantable/active/reusable flags and linked certificates for each device (up to 300 per run). Billed per device.

## `houderSrn` (type: `string`):

SRN of the manufacturer that holds the certificates.

## `houderNaam` (type: `string`):

Part of the manufacturer's name.

## `aangemeldeInstantie` (type: `string`):

Four-digit notified body number, e.g. 0123 or 0633.

## `certificaatStatus` (type: `string`):

Filter on certificate status.

## `verlooptBinnenDagen` (type: `integer`):

Only certificates that expire within this many days, soonest first. Revisions that were already replaced by a newer one are left out, so you do not get false alarms.

## `land` (type: `string`):

Two-letter country code, e.g. NL, DE, FR.

## `soort` (type: `string`):

Kind of economic operator.

## `naam` (type: `string`):

Part of the operator's name.

## `srn` (type: `string`):

Look up one operator by its Single Registration Number.

## `maxResultaten` (type: `integer`):

Upper bound per run. Also caps the cost, since billing is per record returned.

## `alleenWijzigingen` (type: `boolean`):

Return only records that are new or changed (status, version, expiry date) since the last run with the same filters. The first run builds the baseline.

## Actor input object example

```json
{
  "modus": "hulpmiddelen",
  "handelsnaam": "pacemaker",
  "alleenOpDeMarkt": true,
  "metDetails": false,
  "maxResultaten": 100,
  "alleenWijzigingen": false
}
```

# Actor output Schema

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

Every record of this run, including change rows.

## `devices` (type: `string`):

Medical devices with trade name, risk class, legislation, status and manufacturer.

## `certificates` (type: `string`):

Certificates with expiry date, days left, notified body, holder and whether a newer revision replaced them.

## `operators` (type: `string`):

Manufacturers, authorised representatives and importers with SRN, type, status and location.

# 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("eu_open_data/eudamed-medical-devices").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("eu_open_data/eudamed-medical-devices").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 eu_open_data/eudamed-medical-devices --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,eu_open_data/eudamed-medical-devices"
        }
    }
}
```

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/QZ4S4DXtkkh3EMrjd/builds/2zBKCtNOiml9taPQ7/openapi.json
