# EUDAMED Certificates Scraper (`automation-lab/eudamed-certificates-scraper`) Actor

Export public EUDAMED MDR/IVDR certificate records with status, validity dates, manufacturers, notified bodies, and source URLs.

- **URL**: https://apify.com/automation-lab/eudamed-certificates-scraper.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Business
- **Stats:** 2 total users, 1 monthly users, 87.5% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.02 / 1,000 certificate saveds

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/platform/actors/running/actors-in-store#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

## EUDAMED Certificates Scraper

Export public EUDAMED MDR/IVDR certificate records into structured datasets for regulatory affairs, compliance monitoring, and market intelligence.

### What does EUDAMED Certificates Scraper do?

- Export public EUDAMED MDR/IVDR certificate records from the European Commission API.
- Search by certificate status, certificate number, manufacturer SRN/name, notified body SRN, or direct EUDAMED URLs.
- Save structured certificate data for compliance review, monitoring, and due diligence.

### Who is it for?

- Regulatory affairs teams tracking MDR/IVDR certificate status.
- Medtech compliance teams validating suppliers and manufacturers.
- Competitive-intelligence analysts monitoring notified bodies and manufacturers.
- Due-diligence teams checking certificate validity before partnerships or acquisitions.

### Why use it?

- The actor turns EUDAMED certificate search results into a clean dataset.
- It includes detail API enrichment when available.
- It preserves source URLs so auditors can trace every row back to EUDAMED.

### Data you can extract

- Certificate UUID and ULID.
- Certificate number, certificate ID, type, status, legislation, dates, manufacturer, notified body, version state, and source URLs.
- The dataset is designed for CSV, JSON, Excel, API, and integration exports.

### How much does it cost to scrape EUDAMED certificates?

The actor uses pay-per-event pricing: a `$0.005` start charge per run, plus one charge for each certificate record saved.

| Apify plan | Price per certificate |
| --- | ---: |
| FREE | `$0.0062436` |
| BRONZE | `$0.0054292` |
| SILVER | `$0.0042348` |
| GOLD | `$0.0032575` |
| PLATINUM | `$0.0021717` |
| DIAMOND | `$0.0015202` |

### How to scrape EUDAMED certificates

- Choose a certificate status or another filter.
- Set the maximum number of certificates.
- Keep detail enrichment enabled when you need certificate ID, legislation, and manufacturer details.
- Run the actor and export the dataset.

### Input options

- startUrls accepts EUDAMED certificate search API URLs and certificate detail API URLs.
- certificateNumber supports exact certificate lookups.
- certificateStatus accepts shortcuts such as issued or full EUDAMED refdata status codes.
- actorSrn, actorName, and notifiedBodySrn narrow searches to manufacturers and notified bodies.

### Output example

- Each row represents one EUDAMED certificate.
- Rows include certificateNumber, certificateStatus, certificateType, issueDate, expiryDate, notifiedBodySrn, actorSrn, actorName, uuid, rawApiUrl, rawDetailUrl, and fetchedAt.
- Optional detail enrichment adds certificateId, applicableLegislation, decisionDate, and manufacturerUuid.

### Tips for better results

- Use exact certificate numbers for audit lookups.
- Use notifiedBodySrn for recurring notified-body monitoring.
- Use certificateStatus issued for broad market exports.
- Use smaller maxItems values for quick tests.

### Integrations

- Send the dataset to Google Sheets for compliance review.
- Use webhooks to alert your team when scheduled runs finish.
- Pull dataset items through the Apify API into BI tools, ERPs, or regulatory databases.
- Schedule recurring runs to monitor certificate status changes.

### API usage with Node.js

- Use the Apify client to run automation-lab/eudamed-certificates-scraper and fetch dataset items.
- Example input: certificateStatus issued, maxItems 100, includeDetails true.

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/eudamed-certificates-scraper').call({ certificateStatus: 'issued', maxItems: 100, includeDetails: true });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0]);
```

### API usage with Python

- Call the actor with apify-client for Python.
- Fetch the default dataset items after the run completes.
- Store the rows in your compliance database.

```python
from apify_client import ApifyClient
client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("automation-lab/eudamed-certificates-scraper").call(run_input={"notifiedBodySrn": "0633", "maxItems": 100, "includeDetails": True})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items[0])
```

### API usage with cURL

- POST to the Apify actor runs endpoint for automation-lab/eudamed-certificates-scraper.
- Pass JSON input with certificateNumber, notifiedBodySrn, or certificateStatus.
- Download dataset items from the run dataset URL.

```bash
curl -X POST "https://api.apify.com/v2/acts/automation-lab~eudamed-certificates-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"certificateNumber":"Z-25-052-S-IX-E","includeDetails":true,"maxItems":5}'
```

### MCP usage

Use this HTTP MCP endpoint in any compatible client:

`https://mcp.apify.com/?tools=automation-lab/eudamed-certificates-scraper`

#### Claude Code

```bash
claude mcp add --transport http apify "https://mcp.apify.com/?tools=automation-lab/eudamed-certificates-scraper"
```

#### Claude Desktop

Add this server to your Claude Desktop MCP configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com/?tools=automation-lab/eudamed-certificates-scraper"
    }
  }
}
```

#### Cursor

Open **Settings → Tools & Integrations → New MCP Server**, select an HTTP server, and use the endpoint above.

#### VS Code

Open the Command Palette, choose **MCP: Add Server**, select **HTTP**, and use the endpoint above.

- Example prompt: "Run the EUDAMED Certificates Scraper for issued certificates and summarize certificates expiring soon."
- Example prompt: "Extract certificates for notified body SRN 0633 and return manufacturer names, expiry dates, and source URLs."

### Legality and data source

- This actor accesses public EUDAMED certificate endpoints made available by the European Commission.
- Do not use the output as a substitute for legal or regulatory advice.
- Always verify critical decisions against the official EUDAMED source links in the dataset.

### FAQ

- Can I scrape all issued certificates? Yes, set certificateStatus to issued and increase maxItems.
- Can I search one certificate number? Yes, use certificateNumber for exact lookup.
- Why is a notified body name sometimes blank? Some search rows expose SRN first; detail data depends on the public API response.
- Does it require login? No public API calls worked without login during feasibility testing.

### Troubleshooting

- If you get zero rows, loosen filters and try status issued.
- If a direct URL fails, make sure it is a public EUDAMED certificate search or certificate detail API URL.
- If detail fields are missing, keep includeDetails enabled and review rawApiUrl.

### Related scrapers

- Use other automation-lab compliance and public-source scrapers when your workflow needs company, registry, or document data outside EUDAMED certificates.
- This actor is intentionally focused on EUDAMED certificate records rather than broad medical-device listings.

### Changelog

- Initial private release supports public EUDAMED certificate search and detail enrichment.
- Future releases may add change detection helpers if user demand appears.

### Field reference

- `uuid` — exported when available from the EUDAMED search or detail API.
- `ulid` — exported when available from the EUDAMED search or detail API.
- `certificateNumber` — exported when available from the EUDAMED search or detail API.
- `certificateId` — exported when available from the EUDAMED search or detail API.
- `certificateType` — exported when available from the EUDAMED search or detail API.
- `certificateStatus` — exported when available from the EUDAMED search or detail API.
- `applicableLegislation` — exported when available from the EUDAMED search or detail API.
- `issueDate` — exported when available from the EUDAMED search or detail API.
- `decisionDate` — exported when available from the EUDAMED search or detail API.
- `startingValidityDate` — exported when available from the EUDAMED search or detail API.
- `expiryDate` — exported when available from the EUDAMED search or detail API.
- `versionNumber` — exported when available from the EUDAMED search or detail API.
- `revisionNumber` — exported when available from the EUDAMED search or detail API.
- `versionState` — exported when available from the EUDAMED search or detail API.
- `latestVersion` — exported when available from the EUDAMED search or detail API.
- `notifiedBodySrn` — exported when available from the EUDAMED search or detail API.
- `notifiedBodyName` — exported when available from the EUDAMED search or detail API.
- `actorSrn` — exported when available from the EUDAMED search or detail API.
- `actorName` — exported when available from the EUDAMED search or detail API.
- `actorStatus` — exported when available from the EUDAMED search or detail API.
- `manufacturerUuid` — exported when available from the EUDAMED search or detail API.
- `authorizedRepresentativeSrns` — exported when available from the EUDAMED search or detail API.
- `rawDetailUrl` — exported when available from the EUDAMED search or detail API.
- `rawApiUrl` — exported when available from the EUDAMED search or detail API.
- `sourceSearchUrl` — exported when available from the EUDAMED search or detail API.
- `fetchedAt` — exported when available from the EUDAMED search or detail API.

### Example workflows

#### Build a certificate audit evidence pack

Search by `certificateNumber`, keep `includeDetails` enabled, and export the result as JSON or CSV. Preserve `rawDetailUrl`, `rawApiUrl`, and `fetchedAt` so an auditor can trace each row back to the EUDAMED source record and the time it was collected.

#### Monitor a notified body's certificates

Filter by `notifiedBodySrn` and schedule recurring Actor runs. Compare each new dataset with the previous export to detect new certificates, status changes, or approaching expiry dates associated with that notified body.

#### Perform manufacturer due diligence

Search by `actorSrn` or `actorName`, optionally narrow by `certificateStatus`, and review the returned certificate and authorized-representative fields. Load the structured output into a compliance system to assess a manufacturer's current EUDAMED certificate footprint before onboarding or periodic review.

### Operational notes

- Use conservative maxItems values when testing new filters.
- Schedule recurring runs for monitoring workflows rather than manually exporting rows.
- Keep rawApiUrl and rawDetailUrl columns in downstream systems for traceability.
- Review EUDAMED source records before making regulatory decisions.
- Use certificateNumber lookups for audit evidence packs.
- Use notifiedBodySrn filters for notified-body monitoring.
- Use actorSrn filters for manufacturer due diligence.
- Use certificateStatus filters for broad market snapshots.
- Export to CSV when sharing with non-technical reviewers.
- Export to JSON when loading into data pipelines.
- Pair expiryDate with scheduled runs to identify certificates approaching renewal.
- Pair certificateStatus with historical datasets to detect status changes.
- Keep includeDetails enabled for the richest dataset.
- Disable includeDetails only for faster broad sampling.
- Contact the official EUDAMED source for authoritative interpretation.

# Actor input Schema

## `startUrls` (type: `array`):

Optional EUDAMED certificate search API URLs or certificate detail API URLs. If set, URL filters are used before the fields below.

## `certificateNumber` (type: `string`):

Exact EUDAMED certificate number, for example Z-25-052-S-IX-E.

## `certificateStatus` (type: `string`):

Status code or shortcut. Examples: issued, suspended, withdrawn, refused, restricted, or refdata.certificate-status.issued.

## `certificateType` (type: `string`):

Optional EUDAMED certificate type code or accepted API value.

## `actorSrn` (type: `string`):

Manufacturer/actor SRN, for example DE-MF-000006413.

## `actorName` (type: `string`):

Manufacturer/actor name text search, for example AIRAmed.

## `notifiedBodySrn` (type: `string`):

Notified body SRN, for example 0633.

## `includeDetails` (type: `boolean`):

Fetch each certificate detail API endpoint to enrich rows with certificate ID, legislation, decision date, and manufacturer details.

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

Maximum certificate records to save to the dataset.

## `pageSize` (type: `integer`):

EUDAMED API page size. Keep at 100 or below for reliable responses.

## `startPage` (type: `integer`):

Zero-based EUDAMED API page to start from.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://ec.europa.eu/tools/eudamed/api/certificates/search/?certificateStatus=refdata.certificate-status.issued&size=10&page=0"
    }
  ],
  "certificateNumber": "Z-25-052-S-IX-E",
  "certificateStatus": "issued",
  "notifiedBodySrn": "0633",
  "includeDetails": true,
  "maxItems": 10,
  "pageSize": 10,
  "startPage": 0
}
```

# Actor output Schema

## `overview` (type: `string`):

Structured EUDAMED certificate rows collected by this run.

# 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 = {
    "startUrls": [
        {
            "url": "https://ec.europa.eu/tools/eudamed/api/certificates/search/?certificateStatus=refdata.certificate-status.issued&size=10&page=0"
        }
    ],
    "certificateNumber": "Z-25-052-S-IX-E",
    "certificateStatus": "issued",
    "notifiedBodySrn": "0633",
    "includeDetails": true,
    "maxItems": 10,
    "pageSize": 10,
    "startPage": 0
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/eudamed-certificates-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 = {
    "startUrls": [{ "url": "https://ec.europa.eu/tools/eudamed/api/certificates/search/?certificateStatus=refdata.certificate-status.issued&size=10&page=0" }],
    "certificateNumber": "Z-25-052-S-IX-E",
    "certificateStatus": "issued",
    "notifiedBodySrn": "0633",
    "includeDetails": True,
    "maxItems": 10,
    "pageSize": 10,
    "startPage": 0,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/eudamed-certificates-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://ec.europa.eu/tools/eudamed/api/certificates/search/?certificateStatus=refdata.certificate-status.issued&size=10&page=0"
    }
  ],
  "certificateNumber": "Z-25-052-S-IX-E",
  "certificateStatus": "issued",
  "notifiedBodySrn": "0633",
  "includeDetails": true,
  "maxItems": 10,
  "pageSize": 10,
  "startPage": 0
}' |
apify call automation-lab/eudamed-certificates-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=automation-lab/eudamed-certificates-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/7hyc05mFdDvlno1GK/builds/ZLrMXzKO7S3sBq3fQ/openapi.json
