# DORA Critical ICT Third-Party Provider Monitor (`chosen_loafer/dora-ctpp-monitor`) Actor

Monitors the ESAs joint Article 31(9) DORA list of designated Critical ICT Third-Party Providers (CTPPs) for additions and removals, with optional watchlist matching against a buyers own vendor names. Source is a PDF published by EBA/EIOPA/ESMA, not a per-provider register. No personal data.

- **URL**: https://apify.com/chosen_loafer/dora-ctpp-monitor.md
- **Developed by:** [Pavel Staurouski](https://apify.com/chosen_loafer) (community)
- **Categories:** Business, Automation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 checked provider records

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

## DORA Critical ICT Third-Party Provider Monitor

Tracks the European Supervisory Authorities' (EBA, EIOPA, ESMA) joint list of
**Critical ICT Third-Party Providers (CTPPs)** designated under Article 31(9) of the
Digital Operational Resilience Act (DORA) -- the EU-level "who is critical enough to be
directly overseen by the ESAs" list, currently 19 providers (first published 18 November
2025: Accenture, AWS, Microsoft, Google Cloud, Oracle, SAP, IBM, Deutsche Telekom, Orange,
and others).

### What you get

One record per currently-designated provider, plus one per provider that was on the list
at your last check but has since dropped off it. Every record carries an explicit
`matchState`: `FIRST_SEEN` (your own baseline run), `NEW` (added since your last check),
`UNCHANGED`, or `REMOVED`. If you pass an optional `watchlist` of your own ICT vendor
names, each record also gets a `matchesWatchlist` flag so you can filter to the vendors
you actually use.

### What it does not do

**This is not the confidential Register of Information.** DORA Article 28(3) requires
financial entities to maintain their own detailed register of ICT contractual
arrangements, reported annually to national competent authorities in a structured
XBRL-CSV format -- that data is supervisory-only and never made public. What the ESAs
*do* publish is the short, high-level outcome of their own criticality assessment: the
names of the providers designated as "critical" at Union level. This Actor tracks that
published outcome, not the private underlying registers.

**The source is a PDF, not an API.** The ESAs' Joint Committee publishes this list as a
short PDF (mirrored identically on eba.europa.eu, eiopa.europa.eu and esma.europa.eu),
not a CSV, JSON feed, or searchable database. No per-provider detail is published either
\-- no lead overseer, no sector, no designation date, no services covered -- just the
legal-entity name, in alphabetical order. This Actor fetches whichever ESA mirror
responds (all three are tried, in order, for resilience) and parses that PDF; it cannot
report fields the ESAs themselves do not publish.

No personal data: every entry is a company/legal-entity name (the DORA criticality
criteria under Article 31(2) only apply to large-scale undertakings). As a second-layer
guard, any parsed entry that structurally resembles a bare personal name rather than a
company name is withheld from output entirely, not logged, not shipped.

### Why you might need this

Banks, insurers, investment firms and their own ICT vendors have had DORA's third-party
risk-management obligations in force since January 2025. If one of your vendors is
designated a CTPP, it becomes subject to direct ESA oversight (inspections, binding
recommendations) under Articles 33-39 -- something your own third-party risk register
and board reporting should reflect promptly, not discover by chance months later. The
ESAs reportedly intend to review and republish this list annually; this Actor exists to
catch that review's outcome without you manually re-reading a PDF on a schedule.

### Input

```json
{
  "watchlist": ["Microsoft", "Amazon Web Services", "Google Cloud"]
}
```

`watchlist` is optional (default: empty, meaning "report the full list, no highlighting").
Each entry is matched against every currently-designated provider name, case-insensitive,
as a substring either direction -- so "Microsoft" matches "Microsoft Ireland Operations
Limited" without needing the exact published legal name.

### Change tracking across runs

Run this Actor on a schedule (monthly is more than enough given the ESAs' own annual
review cadence). Each provider's first-seen/last-seen timestamps are stored per Actor, so
a run after the ESAs' next annual review immediately reports exactly what was added or
removed, not just a re-dump of the current list.

### Pricing

Pay per run started, plus per provider record produced (currently-designated or
removed-since-last-check). See the Pricing tab for exact rates.

# Actor input Schema

## `watchlist` (type: `array`):

Optional list of your own ICT vendor names. Each currently-designated provider's record gets a matchesWatchlist flag (case-insensitive substring match either direction) so you can filter for vendors you actually use. Leave empty to just track the full list.

## Actor input object example

```json
{
  "watchlist": [
    "Microsoft",
    "Amazon Web Services",
    "Google Cloud"
  ]
}
```

# Actor output Schema

## `ctppResults` (type: `string`):

Per-provider records for 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 = {
    "watchlist": [
        "Microsoft",
        "Amazon Web Services",
        "Google Cloud"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("chosen_loafer/dora-ctpp-monitor").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 = { "watchlist": [
        "Microsoft",
        "Amazon Web Services",
        "Google Cloud",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("chosen_loafer/dora-ctpp-monitor").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 '{
  "watchlist": [
    "Microsoft",
    "Amazon Web Services",
    "Google Cloud"
  ]
}' |
apify call chosen_loafer/dora-ctpp-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,chosen_loafer/dora-ctpp-monitor"
        }
    }
}
```

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/7UfCP6D3ZAgkJx09k/builds/IM7KE2REno842Bs76/openapi.json
