# EU Company Verification (KYB): VIES VAT, LEI, SIREN (`ostrata/eu-company-check`) Actor

KYB (know your business) company verification for Europe: VAT validation in live VIES, LEI lookup (GLEIF), SIREN/SIRET and org numbers checked in official business registries (France, Norway, Finland, Czechia), plus BODACC insolvency. One verdict per company with reasons. MCP-ready.

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

## Pricing

from $5.00 / 1,000 company 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 Company Verification (KYB): VIES VAT, LEI, SIREN

**Verify a European company in one call.** Give it a company name, a national registration number, an EU VAT number or an LEI. You get back **one clean record with a verdict** (`verified` / `review` / `inactive` / `not_found`) and the reasons behind it. The record combines:

**Also known as:** KYB API, company verification API, business verification, VAT number checker / VIES VAT validation, LEI lookup (GLEIF), SIREN check, company registry lookup, know-your-business (KYB) checks for supplier onboarding. 🇫🇷 *vérification d'entreprise, numéro de TVA intracommunautaire, contrôle SIREN* · 🇩🇪 *Firmenprüfung, USt-IdNr. prüfen*.

- the **official business register** (France 🇫🇷, Norway 🇳🇴, Finland 🇫🇮, Czechia 🇨🇿), with legal name, status, legal form, address, activity code, creation and cessation dates;
- a **live EU VAT check in VIES** (all 27 EU countries + Northern Ireland), with the VAT number derived automatically from the registration number where possible;
- the **LEI** from GLEIF (worldwide, CC0);
- **insolvency / liquidation signals** (France: BODACC collective proceedings; Finland: PRH bankruptcy/restructuring/liquidation situations; Czechia: ARES insolvency register flag).

Every result cites its sources and their licences. Only official, free, open public-sector APIs are used: no scraping, no logins, no third-party data brokers.

**Use cases:** supplier and customer onboarding (KYB), B2B checkout VAT checks, invoice and reverse-charge compliance, CRM and ERP data cleaning, lead qualification, and fraud checks ("does this company really exist and is it still active?"). It also works as a tool for AI agents (see [Use it from AI agents (MCP)](#use-it-from-ai-agents-mcp)).

### Why this Actor

| | This Actor | Typical single-source Actor |
|---|---|---|
| Registry + VAT + LEI + insolvency in **one** row | ✅ | ❌ one source per Actor |
| Clear verdict + machine-readable reasons | ✅ | ❌ raw data only |
| Accepts names, IDs, VAT numbers and LEIs mixed in one list | ✅ | ❌ |
| Checksum validation (SIREN/SIRET, org.nr, Y-tunnus, IČO, LEI) before any call | ✅ | rarely |
| **Pay only for companies found**: not-found and invalid inputs are free | ✅ | usually billed per row |
| Sole proprietors (natural persons) excluded from name searches by default | ✅ | ❌ |

### Input

Paste one query per line in **Companies**. Each line can be:

| Example | Interpreted as |
|---|---|
| `Doctolib` | company name, searched in the *default country* register |
| `NO: Equinor` | company name in Norway (prefix `CC:` picks the country) |
| `552 120 222` / `55212022200013` | French SIREN / SIRET |
| `FI: 0112038-9`, `NO: 923609016`, `CZ: 27082440` | Finnish Y-tunnus, Norwegian org.nr, Czech IČO |
| `FR40303265045`, `DE811569869`, `IE6388047V` | EU VAT number (any EU country + XI) |
| `969500BPSLCSC039UV67` | LEI |
| `ES: Inditex` | name in a country without a register adapter → searched in GLEIF |

```json
{
  "companies": ["Doctolib", "FR40303265045", "NO: Equinor", "FI: 0112038-9", "CZ27082440"],
  "defaultCountry": "FR",
  "maxCandidatesPerQuery": 1,
  "checkVat": true,
  "checkLei": true,
  "checkInsolvency": true,
  "excludeSoleProprietors": true,
  "minNameScore": "0.5"
}
```

Options: `maxCandidatesPerQuery` (1–25, for name searches), `minNameScore` (0–1), `includeRaw` (attach the untouched source responses), `concurrency` (1–10). Up to 5,000 queries per run.

### Output

One dataset row per company (or per candidate for name searches with `maxCandidatesPerQuery > 1`). The **Overview** table view shows the flat fields. Each row also carries nested `company`, `vat`, `leiRecord`, `insolvency` and `sources` objects.

| Field | Meaning |
|---|---|
| `verdict` | `verified`, `review`, `inactive`, `not_found`, `invalid_input` or `error` |
| `reasons` | why, e.g. `registry_status_active`, `vat_valid_in_vies`, `lei_issued`, `name_match_1`, `weak_name_match_0.62`, `vat_number_not_valid_in_vies`, `insolvency_or_liquidation_flag`, `registry_status_ceased` |
| `warnings` | non-blocking notes (e.g. VIES temporarily unavailable, Norway not in VIES) |
| `legalName`, `country`, `registrationNumber`, `registrationNumberType` | identity |
| `registryStatus` | `active`, `ceased` or `unknown` |
| `vatNumber`, `vatValid` | VAT number and live VIES result (`null` = could not be checked) |
| `lei`, `insolvencyFlag`, `matchScore`, `inputIndex`, `checkedAt` | |

**Verdict logic.** `inactive` means the register says the company has ceased. `review` means something needs a human: VAT invalid, an insolvency/liquidation notice in the last 3 years, a name match below 0.85, a lapsed LEI, or a status that could not be confirmed. `verified` means the company is active in the register (or has a valid VAT number in VIES where no register is covered), with no red flag.

#### Sample output (real local runs, 18 Oct 2026)

| Query | Verdict | Legal name | Reg. no. | VAT (VIES) | LEI | Notes |
|---|---|---|---|---|---|---|
| `Doctolib` | verified | DOCTOLIB | 794598813 | FR14794598813 ✅ | 969500BPSLCSC039UV67 | name match 1.0 |
| `FR40303265045` | verified | SODIMAS | 303265045 | ✅ | 969500GZTMR1IRVURM23 | |
| `552 120 222` | verified | SOCIETE GENERALE | 552120222 | FR27552120222 ✅ | O2RNE8IBXP4R0TD8PU41 | |
| `440471100` | **inactive** | LB | 440471100 | FR63440471100 ❌ | – | ceased + BODACC liquidation |
| `Blablacar` | verified | COMUTO | 491904546 | FR76491904546 ✅ | 969500XQAR03ZTKPUC93 | brand → legal entity |
| `NO: Equinor` | verified | EQUINOR ASA | 923609016 | n/a (not in VIES) | OW6OFBNCKXC4US5C7523 | |
| `FI: Nokia` | verified | Nokia Oyj | 0112038-9 | FI01120389 ✅ | 549300A0JPRWG1KI7U06 | |
| `CZ: Alza` | verified | Alza.cz a.s. | 27082440 | CZ27082440 ✅ | 315700MJRNJSVB95U852 | |
| `IE6388047V` | verified | GOOGLE IRELAND LIMITED | – | ✅ | YYPPRNO5HB304LHFVG31 | VIES + GLEIF |
| `DE: Siemens Aktiengesellschaft` | verified | Siemens Aktiengesellschaft | HRB 6684 | – | W38RGI023J3WT1HWRP32 | via GLEIF |
| `ES: Inditex` | review | INDUSTRIA DE DISEÑO TEXTIL, S.A. (INDITEX, S.A.) | – | – | 9598004YCFER8AFHFN23 | GLEIF status unconfirmed |
| `NO: 123456789` | invalid_input (free) | | | | | bad checksum |
| `zzqx nonexistent company 4821` | not_found (free) | | | | | |

One full row (`CZ27082440`), shortened:

```json
{
  "query": "CZ27082440", "queryType": "vat", "verdict": "verified",
  "reasons": ["registry_status_active", "vat_valid_in_vies", "lei_issued"],
  "legalName": "Alza.cz a.s.", "country": "CZ", "registrationNumber": "27082440", "registrationNumberType": "ICO",
  "registryStatus": "active", "vatNumber": "CZ27082440", "vatValid": true, "lei": "315700MJRNJSVB95U852", "insolvencyFlag": false,
  "company": { "legalForm": "Akciová společnost (a.s.)", "registrationDate": "2003-08-26",
               "address": { "line": "Jankovcova 1522/53, Holešovice, 17000 Praha 7", "city": "Praha", "country": "CZ" },
               "activity": { "code": "532", "scheme": "CZ-NACE" }, "isSoleProprietor": false, "registryVatRegistered": true },
  "vat": { "valid": true, "name": "Alza.cz a.s.", "address": "Jankovcova 1522/53, PRAHA 7 - HOLEŠOVICE, 170 00  PRAHA 7" },
  "leiRecord": { "entityStatus": "ACTIVE", "registrationStatus": "ISSUED", "corroborationLevel": "FULLY_CORROBORATED" },
  "insolvency": { "flag": false, "details": [] },
  "sources": [ { "name": "ARES …" }, { "name": "VIES …" }, { "name": "GLEIF LEI API", "license": "CC0 1.0" } ]
}
```

Timing in those runs: about 1.5 s per company with all checks on. France takes longer when VIES is busy, because the Actor retries automatically.

### Pricing (pay per event)

- **$0.005 per company check delivered** ($5 per 1,000), charged only for rows with verdict `verified`, `review` or `inactive`.
- `not_found`, `invalid_input` and `error` rows are **free**.
- No subscription. Apify platform usage is included. Set a *maximum cost per run* in the run options: the Actor stops cleanly when that budget is reached.

### Use it from AI agents (MCP)

Every public Apify Actor is automatically available as a tool on the **Apify MCP server** (`https://mcp.apify.com`). Add the Actor in Claude Desktop, Cursor, VS Code or any MCP client:

```json
{ "mcpServers": { "apify": { "url": "https://mcp.apify.com?tools=ostrata/eu-company-check" } } }
```

Then ask: *"Check whether FR40303265045 and NO: Equinor are active companies with valid VAT numbers."* The input is a plain list of strings and the output carries a verdict and reasons, so agents can act on it directly. You can also call it over the Apify API (`run-sync-get-dataset-items`) or with the `apify-client` libraries. *(Replace `ostrata` with the publishing account's username if different.)*

### Data sources & licences

| Source | Coverage | Licence |
|---|---|---|
| [API Recherche d'entreprises](https://recherche-entreprises.api.gouv.fr) (INSEE Sirene + RNE, DINUM) | FR register | Licence Ouverte 2.0 |
| [BODACC](https://www.bodacc.fr) via DILA open data | FR collective proceedings | Licence Ouverte 2.0 |
| [Brønnøysundregistrene – Enhetsregisteret](https://data.brreg.no) | NO register | NLOD 2.0 |
| [PRH – YTJ open data API v3](https://avoindata.prh.fi) | FI register | CC BY 4.0 |
| [ARES](https://ares.gov.cz) (Ministry of Finance CZ) | CZ register | public open data |
| [VIES](https://ec.europa.eu/taxation_customs/vies/) (European Commission) | EU VAT validity | public EU service |
| [GLEIF API](https://www.gleif.org/en/lei-data/gleif-api) | LEI worldwide, name search elsewhere | CC0 1.0 |

The Actor respects each API's published rate limits, using per-host throttling, Retry-After handling and exponential backoff.

### Limitations

- Register adapters exist for FR, NO, FI and CZ. In other countries, names are looked up in GLEIF, so this covers only companies that have an LEI, and VAT numbers are checked in VIES. UK, DE, NL and others are planned.
- Some countries (e.g. Germany, Spain) never return the name or address in VIES. You then get `vatValid` but `legalName: null`.
- VIES is sometimes unavailable for a member state. The Actor retries and, if it still fails, returns `vatValid: null` with a warning instead of a false negative.
- Finnish register status codes are not formally documented. The mapping used (1 = registered, 4 = ceased) is based on observed data.
- Results reflect the sources at query time. This is a data tool, not legal advice.

### Privacy

The Actor queries company registers only. By default it **excludes sole proprietors** (natural persons) from name searches. It does not return directors, shareholders or any personal contact data. Your input list is processed in your own Apify run and is not stored by the author.

### Related Actors

- [Website to Company (Impressum & Mentions Légales)](https://apify.com/ostrata/website-company-check): find the legal entity behind a website (SIREN/VAT from the legal notice) and verify it.
- [France Company List (SIRENE)](https://apify.com/ostrata/france-company-list): build lists of French companies by NAF code, area, headcount and revenue from the official register.
- [Greenhouse, Lever & Ashby Jobs API](https://apify.com/ostrata/ats-jobs-api): normalized job postings from Greenhouse, Lever, Ashby, Workable, SmartRecruiters and Recruitee boards, with only-new-jobs mode.
- [AI Brand Visibility Tracker](https://apify.com/ostrata/ai-search-visibility): check whether ChatGPT, Perplexity and Gemini mention and cite your brand, with position, competitors and share of voice (your own API keys).

***

### 🇫🇷 En bref

**Vérifiez une entreprise européenne en un appel :** nom, SIREN/SIRET, numéro de TVA intracommunautaire ou LEI → une fiche unique avec un verdict (`verified` / `review` / `inactive` / `not_found`). La fiche combine le registre officiel (France via l'API Recherche d'entreprises, Norvège, Finlande, Tchéquie), le contrôle TVA en direct dans VIES (avec calcul automatique de la TVA depuis le SIREN), le LEI GLEIF et les procédures collectives BODACC.

**0,005 $ par entreprise trouvée.** Les recherches sans résultat et les saisies invalides sont gratuites. Uniquement des sources publiques officielles (Licence Ouverte 2.0, NLOD, CC BY, CC0), sans scraping. Les entrepreneurs individuels sont exclus des recherches par nom par défaut. Utilisable comme outil MCP par les agents IA via `mcp.apify.com`.

Publié par Sublime Traders SAS (Ostrata), France.

# Actor input Schema

## `companies` (type: `array`):

Company names, registration numbers, EU VAT numbers or LEIs, one per line. Optional country prefix: "FI: Nokia", "NO: 923609016". Max 5000 per run.

## `defaultCountry` (type: `string`):

Where to search company names that have no country prefix. FR, NO, FI and CZ use the official registries. ANY searches the global GLEIF LEI index (only entities that hold an LEI). Identifiers are detected automatically.

## `maxCandidatesPerQuery` (type: `integer`):

For name searches: how many best-matching companies to return (each returned company is one billable check). Identifier lookups always return one record.

## `checkVat` (type: `boolean`):

Live check of the company's EU VAT number in the European Commission's VIES service (VAT numbers are derived from the registry ID for FR and FI, and read from ARES for CZ).

## `checkLei` (type: `boolean`):

Look up the company's Legal Entity Identifier and its registration status in the GLEIF index.

## `checkInsolvency` (type: `boolean`):

France: insolvency-proceeding notices (procédures collectives) published in BODACC in the last 3 years. Norway, Finland, Czechia: bankruptcy/liquidation flags from the registry.

## `excludeSoleProprietors` (type: `boolean`):

Sole proprietors are registered under a person's name. When on (recommended), name searches only return legal entities. Lookups by an identifier you already have are never filtered.

## `minNameScore` (type: `string`):

Candidates below this similarity are dropped. A match below 0.85 is returned with verdict "review".

## `includeRaw` (type: `boolean`):

Adds the untouched registry record under "raw" (larger output).

## `concurrency` (type: `integer`):

Queries processed in parallel. Each upstream API is additionally rate-limited per host to respect its published limits.

## Actor input object example

```json
{
  "companies": [
    "Doctolib",
    "FR40303265045",
    "NO: Equinor",
    "FI: 0112038-9",
    "CZ27082440"
  ],
  "defaultCountry": "FR",
  "maxCandidatesPerQuery": 1,
  "checkVat": true,
  "checkLei": true,
  "checkInsolvency": true,
  "excludeSoleProprietors": true,
  "minNameScore": "0.5",
  "includeRaw": false,
  "concurrency": 3
}
```

# Actor output Schema

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

Dataset items, one per company/candidate checked.

# 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 = {
    "companies": [
        "Doctolib",
        "FR40303265045",
        "NO: Equinor",
        "FI: 0112038-9",
        "CZ27082440"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("ostrata/eu-company-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 = { "companies": [
        "Doctolib",
        "FR40303265045",
        "NO: Equinor",
        "FI: 0112038-9",
        "CZ27082440",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("ostrata/eu-company-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 '{
  "companies": [
    "Doctolib",
    "FR40303265045",
    "NO: Equinor",
    "FI: 0112038-9",
    "CZ27082440"
  ]
}' |
apify call ostrata/eu-company-check --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ostrata/eu-company-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/UGNnSpDvHY7GYrchx/builds/BMc8vnFWo9gf46JGH/openapi.json
