# EU Financial License Check: ESMA, EBA, MiCA, Warning Lists (`lerider/eu-licence-check`) Actor

Is this firm authorised in the EU, for what, since when, or on a regulator warning list? Checks banks, payment and e-money firms, investment firms, MiCA crypto providers and warning lists by name, LEI, registration number or domain. ALLOW / REVIEW / BLOCK verdict for KYB and AI payment agents.

- **URL**: https://apify.com/lerider/eu-licence-check.md
- **Developed by:** [Lerider Technologies](https://apify.com/lerider) (community)
- **Categories:** Business, Developer tools, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 licence checks

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

## EU Financial Licence & Warning List Check

Before you pay, deposit with, invest through or onboard a financial firm or crypto platform, ask one question:
**is it authorised in the EU, and is it on a regulator's warning list?**

This Actor checks a firm by name, LEI, registration number and/or website against the EU-level public registers
(ESMA, EBA, ECB, the MiCA register) and national warning lists (France, Belgium, the Netherlands, plus the EU-wide
MiCA list of non-compliant crypto firms). It returns a verdict, **ALLOW**, **REVIEW** or **BLOCK**, with the reasons,
the matching register entries (what the firm is authorised for, since when, withdrawn when, where it is passported),
and for every source the date of the data used.

It is built for KYB and onboarding checks, payment and treasury agents, and AI agents that move money. It does not
replace a compliance officer. **Not legal advice**, not investment advice: see "Limits" below.

### What you get per firm

| Field | Meaning |
|---|---|
| `verdict` | `ALLOW` (active authorisation found, nothing against it), `REVIEW` (a human checks first), `BLOCK` (warning list or EU sanctions hit) |
| `status` | `licensed`, `licensed_and_warned`, `warned`, `sanctioned`, `licence_withdrawn`, `possible_match`, `not_found`, `not_covered` |
| `reasons` | One line per rule that fired |
| `licences` | Up to 5 register entries: register, authority, type, status, `authorised_since`, `withdrawn_on`, `passported_to`, services, match method and confidence, history |
| `warnings`, `sanctions` | Up to 5 warning-list / EU-sanctions entries that match, with date and match confidence |
| `lookalike_domains` | Warning-list websites that look like yours (one character off, or same name on another extension). Shown, not counted as a match |
| `claimed_licence` | Whether the licence the firm claims is `covered` by our sources and `found` (active) |
| `coverage` | Per source: checked / stale / unavailable, and `data_as_of` |
| `history` | When our daily records first saw the entry and what changed since |
| `attribution`, `disclaimer` | Source acknowledgements required by the publishers, and the limits |

`not_found` and `not_covered` are different answers:

- **not_found**: we searched every source that covers this kind of firm and found nothing. For a firm that claims a
  bank, payment, e-money, investment or MiCA licence in the EU, that is a red flag.
- **not_covered**: the licence the firm claims (for example insurance, consumer credit or a purely national licence)
  or its country is not in our sources. We cannot say anything about it; check the national register.

### Input

```json
{"name": "Mollie B.V.", "country": "NL",
 "claimed_licence": "e-money institution NL", "as_of": "2026-10-28"}
```

Give at least one of `name`, `lei`, `reg_number`, `domain`. Batch: `{"entities": [{...}, {...}]}` (up to 500).

- `claimed_licence`: free text ("payment institution NL", "MiCA CASP", "bank") or `{"type": "emi", "country": "NL"}`.
  Types: `bank`, `payment_institution`, `emi`, `aisp`, `pisp`, `investment_firm`, `aifm`, `ucits_manco`,
  `crowdfunding`, `trading_venue`, `casp`, `emt_issuer`, `art_issuer`.
- `as_of`: the status on a past date, from the registers' own authorisation and withdrawal dates where they publish
  them, otherwise from our recorded history. Before our history starts for a register without dates, the answer is
  `unknown` (never a guess).
- `refresh`: `auto` (default) refetches any source older than `max_age_hours` (default 48) from the official file at
  the start of the run; `never` uses the bundled data only; `always` refetches everything.
- `resolve_lei` (default on): looks up the LEI's legal name at GLEIF, so registers that list the firm without its LEI
  still match.

### Example output (shortened)

```json
{"verdict": "BLOCK", "status": "warned",
 "reasons": ["On a warning list: AFM (NL) lists '24era' (exact_name, 2024-07-02)",
             "On a warning list: FSMA (BE) lists '24era.com' (domain, 2024-08-29)"],
 "warnings": [{"source": "afm_warnings", "name": "24era", "date": "2024-07-02",
               "match": {"method": "exact_name", "confidence": 0.95}, "data_as_of": "2026-10-28T07:21:11+00:00"}]}
```

### How matching works

| Method | Confidence |
|---|---|
| LEI or registration number equal | 1.00 |
| Same name after normalising case, accents, punctuation, legal form spelling | 0.95 |
| Same name without the legal form (B.V., GmbH, Ltd, S.A., UAB...) | 0.90 |
| Similar name (token-sorted similarity of 0.88 or more) | 0.60 to 0.85 |
| Same website domain | 0.95 |
| Name matches but the firm's home country differs from yours (and it is not passported there) | minus 0.10 |

Only matches of 0.90 or more can lead to ALLOW or BLOCK. Weaker matches lead to REVIEW.

Rules worth knowing:

- **Clones and impersonation.** Fraudsters copy the names of real banks and brokers, and warning lists then carry
  that name too. When a licensed firm's name also appears on a warning list, the result is REVIEW unless you give the
  domain you deal with and the register confirms it. If your domain is the one on the warning list, it is BLOCK.
- A REVIEW is also given when a licence is withdrawn, when only a similar name matches, when the domain you give
  differs from the domain in the register, when a source could not be read, or when a warning list is more than
  7 days old. ALLOW is never given while a warning list is missing.
- **Domain confirmation needs the register to publish a domain.** The MiCA registers and the AMF PSAN list carry a
  website for almost every entry, so a domain you give is actively checked against them. The ECB bank list and the
  EBA payment/e-money register currently publish none, and the ESMA MiFID register has one for only a small share of
  firms. When you give a domain that the register cannot confirm, the verdict is **REVIEW** with the reason
  `domain_unconfirmed` (a real firm's name with a made-up domain is exactly what impersonators send). The domain is
  still checked against warning lists and sanctions. If you only want the licence status, leave `domain` out; to
  confirm a bank's or payment/e-money institution's website, use the regulator's own register page.
- Warning lists can name natural persons. We return only the entries that match what you send, and there is no
  search or bulk export. E-mail addresses on the AMF list are reduced to their domain.

### Coverage

Licence registers (who is authorised):

| Source | Covers | Countries | Dates in the source |
|---|---|---|---|
| ESMA register of investment firms (MiFID II) | Investment firms, AIFMs, UCITS management companies, crowdfunding providers, trading venues, branches | EU + NO, IS, LI | Authorisation and withdrawal dates |
| EBA register of payment and e-money institutions | Payment institutions, e-money institutions, account information providers, exempted institutions, branches, firms notified as outside PSD2 scope | EU + NO, IS, LI | Authorisation and withdrawal dates |
| ECB list of monetary financial institutions | Credit institutions (banks) and their branches, money market funds | EU-27 (not NO, IS, LI) | None: we record entries and exits from 2026-10-28 |
| ESMA interim MiCA register | Authorised crypto-asset service providers (CASPs), e-money and asset-referenced token issuers | EU + NO, IS, LI | Authorisation date |
| AMF list of PSAN | French digital-asset providers under the pre-MiCA regime (most registrations ended in 2026) | FR | Registration and end dates |

Warning lists and sanctions:

| Source | Covers | Countries |
|---|---|---|
| ESMA interim MiCA register, non-compliant entities | Crypto services offered without MiCA authorisation, reported by every national authority | EU + NO, IS, LI |
| AMF listes noires | Unauthorised forex, binary options, crypto derivatives, miscellaneous goods schemes, identity theft | FR |
| FSMA list of companies operating unlawfully | Fraudulent platforms, clones, unauthorised offers | BE |
| AFM warning list | Firms the AFM warns against | NL |
| EU consolidated financial sanctions list | Legal entities under EU asset freezes (no natural persons) | EU |

Per country, this means:

| Country | Banks | Payment / e-money | Investment firms | Crypto (MiCA) | National warning list |
|---|---|---|---|---|---|
| FR | yes | yes | yes | yes, plus PSAN | yes (AMF) |
| BE | yes | yes | yes | yes | yes (FSMA) |
| NL | yes | yes | yes | yes | yes (AFM) |
| Other EU-27 | yes | yes | yes | yes | only the EU-wide MiCA non-compliant list |
| NO, IS, LI | no | yes | yes | yes | only the EU-wide MiCA non-compliant list |
| UK, CH, rest of world | no | no | no | no | no |

Not covered yet: IOSCO I-SCAN, BaFin (DE), CONSOB (IT) and CNMV (ES) warnings, the UK FCA, insurance companies and
intermediaries, and purely national licences (consumer credit, mortgage advice, trust offices, financial service
providers registered only nationally). The `not_covered` field in every result lists them.

### How up to date is the data?

| What | How often | Where you see it |
|---|---|---|
| Our copy of each register and warning list | Read from the official file **every day** (ESMA MiFID and EBA at 10:25, ECB MFI list and AFM / FSMA / AMF lists at 10:40, MiCA registers and EU sanctions at 20:05, Amsterdam time) | `history` in each result |
| The data bundled in this Actor | **Rebuilt and republished every day at about 11:15 Amsterdam time** from the latest daily copies, after the full test suite passes | `coverage[].data_as_of` per source, in every result |
| Live refresh during your run | `refresh: auto` (default): any source older than `max_age_hours` (48 h) is fetched live from the official file at the start of your run. `always`: every source. `never`: bundled data only | the same `data_as_of` (then the time of your run) |

So with the defaults, an answer is never based on a source copy older than 48 hours, and normally on one from the
same or the previous day. `data_as_of` is when we last read the official file; each authority updates its own
register on its own schedule, so a decision made today may appear in its file later.

**History.** On top of the registers' own dates we keep every change we see, so answers can say "first seen on",
"left the list on" or "first warned on". That history starts on 2026-10-26/28 (per source, shown in each result as
`our_history_starts`) and grows every day.

### Pricing

Pay per event: one `licence-check` event per firm checked. Items rejected for bad input are not charged. A check
where a source was down still returns a verdict (never ALLOW in that case) and is charged.

### Limits

- Indicative only. **Not legal advice**, not investment or compliance advice. Registers can lag the authority's
  decisions by days or weeks; confirm on the authority's own register before you rely on a result.
- A firm missing from a list is not proof it is safe: warning lists only contain firms an authority has noticed.
- Names are matched, not identities. Without an LEI, registration number or domain, two firms with the same name can
  be confused; the confidence score shows how the match was made.
- The ECB list is a statistical list of monetary financial institutions; it is the EU-wide public list of credit
  institutions, but a national banking register is authoritative.

### Sources and licences

- ESMA, Register of investment firms (MiFID II) and interim MiCA register: reproduction authorised, source acknowledged.
- European Banking Authority, Register of payment and electronic money institutions: reproduction authorised, source acknowledged.
- European Central Bank, list of monetary financial institutions: reproduction permitted, source acknowledged.
- AMF (France), listes noires and liste blanche des PSAN, via data.gouv.fr: Licence Ouverte / Open Licence 2.0.
- FSMA (Belgium), list of companies operating unlawfully in Belgium: CC BY 4.0.
- Autoriteit Financiële Markten (AFM), waarschuwingslijst: reuse with explicit attribution to the AFM.
- European Commission, EU Financial Sanctions Files: reuse authorised, source acknowledged.
- GLEIF LEI records (LEI look-up): CC0.

Every result carries the attribution lines for the sources it used.

# Changelog

This Actor's version history is a separate document: https://apify.com/lerider/eu-licence-check/changelog.md

# Actor input Schema

## `name` (type: `string`):

Legal or trading name, e.g. 'Mollie B.V.'. Legal forms (B.V., GmbH, Ltd...) and accents are normalised.

## `lei` (type: `string`):

20-character Legal Entity Identifier. Strongest match key; the legal name is also looked up at GLEIF (CC0) unless resolve_lei is off.

## `reg_number` (type: `string`):

The regulator's or business register's number as published in the register (e.g. DNB 'F0038', ECB RIAD code, SIREN for AMF PSAN).

## `country` (type: `string`):

ISO 3166 alpha-2 (NL, DE, FR...). Lowers name-match confidence for firms from other countries (passported firms excepted).

## `domain` (type: `string`):

The domain you are dealing with (https://example.com, example.com or someone@example.com). Matched against warning lists and register websites; look-alike domains are flagged.

## `claimed_licence` (type: `string`):

What the firm says it is, e.g. 'payment institution NL', 'e-money', 'bank', 'MiCA CASP', 'investment firm DE'. Types we do not cover (insurance, consumer credit...) return not_covered.

## `as_of` (type: `string`):

YYYY-MM-DD. Status on that date, from the registers' own authorisation/withdrawal dates and our recorded history. Default: today.

## `entities` (type: `array`):

A list of {name, lei, reg_number, country, domain, claimed_licence, as_of}. Max 500. Top-level as_of applies to all items that do not set one.

## `refresh` (type: `string`):

The bundled data is rebuilt every day at about 11:15 Amsterdam time from our daily copies of each register. 'auto' (default) also fetches any source older than max_age_hours live from the official file at run start (adds 5-60 s when needed); 'never' uses the bundled data only; 'always' fetches every source live.

## `max_age_hours` (type: `integer`):

With refresh 'auto': sources whose data_as_of is older than this many hours are fetched live (default 48).

## `resolve_lei` (type: `boolean`):

Look up the LEI's legal name at GLEIF so registers that list the firm without its LEI still match.

## Actor input object example

```json
{
  "name": "Mollie B.V.",
  "refresh": "auto",
  "max_age_hours": 48,
  "resolve_lei": true
}
```

# Actor output Schema

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

No description

## `overview` (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 = {
    "name": "Mollie B.V."
};

// Run the Actor and wait for it to finish
const run = await client.actor("lerider/eu-licence-check").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 = { "name": "Mollie B.V." }

# Run the Actor and wait for it to finish
run = client.actor("lerider/eu-licence-check").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 '{
  "name": "Mollie B.V."
}' |
apify call lerider/eu-licence-check --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lerider/eu-licence-check"
        }
    }
}
```

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/sIzJDVHDbqNdixqNi/builds/u38IetIKSwO7F04od/openapi.json
