# EUDAMED EU Medical Device Registry Scraper (`jungle_synthesizer/eudamed-eu-medical-device-registry-scraper`) Actor

Extracts the EU's mandatory EUDAMED medical device registry in full: UDI-DI device records and notified-body certificates, joined by manufacturer SRN for regulatory-affairs, competitive-intelligence and distributor-prospecting use.

- **URL**: https://apify.com/jungle\_synthesizer/eudamed-eu-medical-device-registry-scraper.md
- **Developed by:** [BowTiedRaccoon](https://apify.com/jungle_synthesizer) (community)
- **Categories:** Business, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 record scrapeds

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

## EUDAMED EU Medical Device Registry Scraper

Pull the European Union's mandatory medical device registry — EUDAMED — in full. Returns UDI-DI device records (make, model, risk class, legislation, device status, manufacturer) and notified-body certificates, joined on the manufacturer's EU Single Registration Number (SRN) so you can answer "which notified body certified this manufacturer, under what certificate, valid until when" in one dataset instead of two lookups.

***

### EUDAMED Scraper Features

- Walks the entire public registry instead of answering one search at a time — the device endpoint alone reports 3.5M+ records
- Emits notified-body certificates alongside device records, joined by manufacturer/actor SRN
- Derives the manufacturer's registered country from its SRN prefix, so you don't have to parse it yourself
- Translates the registry's internal reference codes (risk class, device status, certificate status) into plain labels instead of raw codes
- Carries version and status fields (`latest_version`, `version_number`, `last_update_date`) so a device's history is diffable across runs
- Choose device records, certificates, or both in a single run
- No account or login required — EUDAMED is a public EU registry

***

### Who Uses EU Medical Device Registry Data?

- **Regulatory-affairs teams** — check whether a competitor's device is already MDR/IVDR certified, by whom, and under which certificate
- **Competitive intelligence** — track a competitor's device portfolio and watch it change over time via the version/status fields
- **Distributor and importer prospecting** — the manufacturer SRN is the legal entity you'd contract with; use it directly instead of resolving a company name
- **Notified-body and consultancy practices** — cross-reference certificate coverage across manufacturers and device classes
- **Supply-chain risk teams** — monitor when a device moves to "no longer placed on the market"

***

### How EUDAMED Scraper Works

1. Choose which record types you want — device records, certificates, or both (default: both).
2. It walks the registry's device and/or certificate listings from the start, page by page.
3. Reference codes (risk class, device status, certificate status, manufacturer status) are translated into plain labels, and the manufacturer's country is derived from its SRN.
4. Every record lands in your dataset as clean, consistently-shaped JSON — device rows and certificate rows share one schema, joinable on `manufacturer_srn` / `actor_srn`.

***

### Input

```json
{
  "maxItems": 100,
  "recordTypes": ["device", "certificate"]
}
```

| Field         | Type    | Default                     | Description |
|---------------|---------|-----------------------------|-------------------------------------------------------------------------------------------------------------------|
| `maxItems`    | integer | 10                          | Maximum number of records to save across all selected record types. Set 0 to pull the entire selected corpus. |
| `recordTypes` | array   | `["device", "certificate"]` | Which record types to include: `device` (UDI-DI registrations) and/or `certificate` (notified-body certifications) |

#### Pulling only certificates

```json
{
  "maxItems": 500,
  "recordTypes": ["certificate"]
}
```

***

### EUDAMED Scraper Output Fields

```json
{
  "record_type": "device",
  "uuid": "2e40ce1c-8ce2-4711-be82-98a2f5dd6cbe",
  "ulid": "01M3106VVG2JM2X3N99PRPXQMF",
  "basic_udi": "B-WB-IFIgE-454(AT)28",
  "primary_di": "D-WB-IFIgE-454(AT)28",
  "issuing_agency": null,
  "trade_name": "Inhalant-Food Allergen-specific IgE Antibodies Rapid Test kit (Immunoblotting)",
  "device_name": null,
  "device_model": null,
  "reference": "WB-IFIgE-454",
  "risk_class": "IVD General",
  "applicable_legislation": null,
  "device_status": "On The Market",
  "sterile": null,
  "multi_component": null,
  "container_package_count": 0,
  "device_criterion": null,
  "manufacturer_name": "Hangzhou Alltest Biotech.Co.,Ltd.",
  "manufacturer_srn": "CN-MF-000010710",
  "manufacturer_status": "Active",
  "manufacturer_country": "CN",
  "authorised_representative_name": "VidaQuick Biotech S.L.",
  "authorised_representative_srn": "ES-AR-000048138",
  "notified_body_srn": null,
  "certificate_number": null,
  "certificate_type": null,
  "certificate_valid_from": null,
  "certificate_valid_to": null,
  "certificate_status": null,
  "actor_name": null,
  "actor_srn": null,
  "latest_version": true,
  "version_number": 1,
  "last_update_date": null,
  "scraped_at": "2026-09-21T13:12:23.260Z"
}
```

| Field                                                              | Type    | Description |
|--------------------------------------------------------------------|---------|---------------------------------------------------------------------------------------------------|
| `record_type`                                                      | string  | `device` or `certificate` |
| `uuid` / `ulid`                                                    | string  | Registry-internal identifiers for this record |
| `basic_udi` / `primary_di`                                         | string  | Device rows only — Basic UDI-DI and Primary DI |
| `issuing_agency`                                                   | string  | Device rows only — UDI issuing agency (GS1, HIBCC, ICCBBA, IFA), when published |
| `trade_name` / `device_name` / `device_model`                      | string  | Device rows only — as published by the manufacturer |
| `reference`                                                        | string  | Device rows only — manufacturer's internal reference |
| `risk_class`                                                       | string  | Device rows only — MDR/IVDR risk classification (Class I / IIa / IIb / III, IVD General/A–D) |
| `applicable_legislation`                                           | string  | Device rows only — MDR 2017/745 or IVDR 2017/746, when published |
| `device_status`                                                    | string  | Device rows only — e.g. "On The Market", "No Longer Placed On The Market" |
| `sterile` / `multi_component`                                      | boolean | Device rows only — as published; frequently unpublished (null) on a given device |
| `container_package_count`                                          | integer | Device rows only |
| `device_criterion`                                                 | string  | Device rows only |
| `manufacturer_name` / `manufacturer_srn`                           | string  | Device rows only — the legal manufacturer and its EU Single Registration Number |
| `manufacturer_status`                                              | string  | Device rows only — the manufacturer's registration status |
| `manufacturer_country`                                             | string  | Device rows only — ISO 3166-1 alpha-2 code, derived from the manufacturer SRN prefix |
| `authorised_representative_name` / `authorised_representative_srn` | string  | Device rows only — EU authorised representative, when the manufacturer is outside the EU |
| `notified_body_srn`                                                | string  | Certificate rows only — the certifying notified body's identifier |
| `certificate_number` / `certificate_type` / `certificate_status`   | string  | Certificate rows only |
| `certificate_valid_from` / `certificate_valid_to`                  | string  | Certificate rows only — ISO-8601 validity window |
| `actor_name` / `actor_srn`                                         | string  | Certificate rows only — the certificate holder and its SRN (equivalent to `manufacturer_name`/`manufacturer_srn` on a device row) |
| `latest_version`                                                   | boolean | Whether this is the current version of the record |
| `version_number`                                                   | integer | Registry version counter for this record |
| `last_update_date`                                                 | string  | Device rows only — when the registry last updated this record |
| `scraped_at`                                                       | string  | ISO-8601 timestamp when this record was scraped |

Device-only fields are `null` on certificate rows and vice versa — join a device row to a certificate row on `manufacturer_srn == actor_srn` to see which notified body certified that manufacturer.

Reference-data codes are translated into plain labels (e.g. `refdata.risk-class.class-iia` → `Class IIa`). An unrecognised future code falls back to a generic title-cased label rather than the raw code.

***

### Resuming a large crawl

Every run emits a `resumeCursor` in its Output. If a large crawl stops before it finishes — because it hit `maxItems`, your spend cap (`maxTotalChargeUsd`), or was aborted — start a new run with **the same input** plus that `resumeCursor` to continue from where it left off. The crawl resumes from the queued work the previous run didn't reach.

- You are **not re-charged** for records the earlier run already delivered.
- Resume within your account's run-retention window — on the free tier, roughly your 10 most recent runs. Once the source run is pruned, its `resumeCursor` is no longer valid.
- `resumeCursor` is opaque — supply it unmodified.

***

### FAQ

#### How do I scrape the full EUDAMED registry?

Set `maxItems` to `0` and leave `recordTypes` at its default to pull every device record and every certificate. A full pull is several million records, so budget your run's time and spend cap accordingly, or pull it incrementally with `resumeCursor`.

#### Can I get just the certificates, not the devices?

Yes. Set `recordTypes` to `["certificate"]`.

#### How do I join a device to its notified-body certificate?

Match a device row's `manufacturer_srn` to a certificate row's `actor_srn`. Both are the same EU Single Registration Number scheme.

#### Does this cover IVD devices as well as medical devices?

Yes. `risk_class` reports both the MDR classes (I, IIa, IIb, III) and the IVDR classes (IVD General, A–D) exactly as the registry publishes them.

#### Does EUDAMED Scraper require an account or subscription?

No. EUDAMED is a public EU registry — no account, no login, nothing to sign up for.

***

### Need More Features?

Need additional fields or a different filter? [File an issue](https://console.apify.com/actors/issues) or get in touch.

### Why Use EUDAMED Scraper?

- **Full-registry coverage** — walks the entire public device and certificate listing instead of answering one search box query at a time.
- **The certificate join** — the only EUDAMED actor that emits notified-body certificates linked to devices by manufacturer SRN.
- **Diffable output** — version and status fields let you track a manufacturer's portfolio changing over time instead of re-buying a snapshot.

# Actor input Schema

## `sp_intended_usage` (type: `string`):

What will this data feed? E.g. lead lists, KYB checks, price tracking.

## `sp_improvement_suggestions` (type: `string`):

Provide any feedback or suggestions for improvements.

## `sp_contact` (type: `string`):

We'll personally help with your use case. No spam.

## `resumeCursor` (type: `string`):

Leave empty for a fresh crawl. To CONTINUE a previous run where it stopped — without paying again for records you already received — paste the `resumeCursor` value from that run's Output (the run's OUTPUT key). Resume promptly: the previous run's data expires with your account's retention window (free tier: your ~10 most recent runs).

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

Maximum number of records to save across all selected record types. Set 0 to pull the entire selected corpus (3.5M+ device records and/or 5K+ certificates as of 2026-09) — a full crawl can take several hours.

## `recordTypes` (type: `array`):

Which EUDAMED record types to include. Device records are individual UDI-DI device registrations; certificate records are notified-body certifications linkable to devices via manufacturer SRN.

## Actor input object example

```json
{
  "sp_intended_usage": "Describe your intended use...",
  "sp_improvement_suggestions": "Share your suggestions here...",
  "sp_contact": "Share your email here...",
  "maxItems": 10,
  "recordTypes": [
    "device",
    "certificate"
  ]
}
```

# Actor output Schema

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

No description

# 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 = {
    "sp_intended_usage": "Describe your intended use...",
    "sp_improvement_suggestions": "Share your suggestions here...",
    "sp_contact": "Share your email here...",
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("jungle_synthesizer/eudamed-eu-medical-device-registry-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 = {
    "sp_intended_usage": "Describe your intended use...",
    "sp_improvement_suggestions": "Share your suggestions here...",
    "sp_contact": "Share your email here...",
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("jungle_synthesizer/eudamed-eu-medical-device-registry-scraper").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 '{
  "sp_intended_usage": "Describe your intended use...",
  "sp_improvement_suggestions": "Share your suggestions here...",
  "sp_contact": "Share your email here...",
  "maxItems": 10
}' |
apify call jungle_synthesizer/eudamed-eu-medical-device-registry-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jungle_synthesizer/eudamed-eu-medical-device-registry-scraper"
        }
    }
}
```

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/76tqJkfDRX7LttrcI/builds/15aZrCtgb7flBlFPl/openapi.json
