# EU Company Registry Lookup: FR, NO, FI, EE + VIES VAT + LEI (`rod_analytics/eu-company-lookup`) Actor

Search or look up companies in the official business registers of France (SIRENE), Norway (Brønnøysund), Finland (PRH YTJ) and Estonia (e-Business Register), validate EU VAT numbers in VIES and add GLEIF LEI codes. One normalized schema for KYB, due diligence and B2B lead enrichment.

- **URL**: https://apify.com/rod\_analytics/eu-company-lookup.md
- **Developed by:** [Rod Services](https://apify.com/rod_analytics) (community)
- **Categories:** Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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

### What does EU Company Registry Lookup do?

**EU Company Registry Lookup** searches the **official business registers of France, Norway, Finland and Estonia** in one run and returns every company in **one normalized schema**. Look companies up by **name or registry ID**, **validate EU VAT numbers in VIES**, and add the **LEI code from GLEIF**. It is built for **KYB (Know Your Business)**, **supplier due diligence**, **B2B lead enrichment** and **AI agents** that need verified company data.

Sources are official, keyless open-data APIs:

- **France:** INSEE SIRENE and RNE via [API Recherche d'entreprises](https://recherche-entreprises.api.gouv.fr) (annuaire-entreprises.data.gouv.fr)
- **Norway:** [Brønnøysund Register Centre, Enhetsregisteret](https://data.brreg.no/enhetsregisteret/api/dokumentasjon/en/index.html)
- **Finland:** [PRH YTJ open data](https://avoindata.prh.fi/en/ytj/swagger-ui) (Finnish Patent and Registration Office)
- **Estonia:** [e-Business Register open data](https://avaandmed.ariregister.rik.ee/en) (RIK)
- **VAT:** [EU VIES](https://ec.europa.eu/taxation_customs/vies/) VAT number validation
- **LEI:** [GLEIF API](https://www.gleif.org/en/lei-data/gleif-api)

Run it on the Apify platform and you get an API, scheduling, webhooks, integrations (Google Sheets, Make, Zapier, n8n, Slack), monitoring, and an MCP tool for AI agents. Try it now: the prefilled input searches "Nokia" in all four registers, validates VAT numbers and adds LEI codes in about 15 seconds.

### Why use this EU company lookup?

- **KYB and onboarding.** Confirm that a customer or supplier exists, is active, and has a valid VAT number before you sign or pay.
- **VAT number validation.** Bulk-check EU VAT numbers in VIES for $0.50 per 1,000 and get the registered trader name and address. Norwegian MVA numbers are checked in the Brønnøysund VAT register.
- **B2B lead enrichment.** Add legal form, NACE industry code and label, registration date, employee range, address and website to CRM records.
- **Due diligence and compliance.** Status (active, ceased, bankrupt, in liquidation), LEI and LEI status, with a link to the official source page for each company.
- **AI agents and LLM tools.** Clean JSON with stable field names works as a tool call through the Apify MCP server. Ask "is FR89383474814 valid and who is it?" and get a structured answer.
- **One schema instead of six APIs.** No need to learn SIRENE codes, Norwegian HAL responses, Finnish code sets or VIES error formats.
- **GDPR-aware.** Sole traders and other natural persons are **excluded by default**, and personal data of French executives is removed from raw records.

### How to look up EU companies

1. Open the Actor and go to the **Input** tab.
2. Pick a **Mode**: search by name, look up by registry ID, validate VAT numbers, or look up LEI codes.
3. Select **Countries** (France, Norway, Finland, Estonia) for search and lookup.
4. Enter **company names or registry IDs** in "queries", or **VAT numbers** in "vatNumbers".
5. Choose enrichment: **VIES VAT check** (on by default) and **GLEIF LEI** (optional).
6. Click **Start**. Download results as JSON, CSV, Excel or HTML, or read them through the Apify API.

### Input

All fields are on the Input tab. The main ones:

| Field                   | What it does                                                                                               |
| ----------------------- | ---------------------------------------------------------------------------------------------------------- |
| `mode`                  | `search` (by name), `lookup` (by registry ID), `vat` (VIES validation), `lei` (GLEIF)                      |
| `countries`             | `FR`, `NO`, `FI`, `EE`. Used by search and lookup                                                          |
| `queries`               | Company names, registry IDs (`383474814`, `923609016`, `0112038-9`, `12417834`, or `NO:923609016`) or LEIs |
| `vatNumbers`            | VAT numbers with prefix, e.g. `FR89383474814`, `EE101335276`, `NO923609016MVA`, `DE123456789`              |
| `maxItemsPerQuery`      | Max companies per query and country (1 to 500)                                                             |
| `industryCodes`         | Keep only companies whose main NACE code starts with these codes, e.g. `62`, `62.01`, `47.64` (FR, NO, FI) |
| `includeVies`           | Validate each company's VAT number in VIES                                                                 |
| `includeLei`            | Find the LEI in GLEIF by registry ID                                                                       |
| `estoniaBulkEnrichment` | Add Estonian VAT number and registration date from the daily open-data file                                |
| `excludeNaturalPersons` | Skip sole traders (default on)                                                                             |
| `onlyActive`            | Skip ceased, deleted, bankrupt or liquidating companies                                                    |
| `includeRaw`            | Keep the original source record in `raw`                                                                   |

Example input: IT companies named "consulting" in France, Norway and Finland, active only:

```json
{
    "mode": "search",
    "countries": ["FR", "NO", "FI"],
    "queries": ["consulting"],
    "industryCodes": ["62"],
    "onlyActive": true,
    "maxItemsPerQuery": 20
}
```

Example input for VAT validation:

```json
{
    "mode": "vat",
    "vatNumbers": ["FR89383474814", "EE101335276", "NO923609016MVA", "IT00743110157"]
}
```

### Output

Each dataset item is one company. Example (raw omitted, attribution shortened):

```json
{
    "country": "FR",
    "registryId": "383474814",
    "name": "AIRBUS",
    "legalForm": "SAS, société par actions simplifiée",
    "legalFormCode": "5710",
    "status": "active",
    "statusDetail": "Active",
    "registrationDate": "1991-10-18",
    "address": {
        "street": "2 ROND-POINT DEWOITINE",
        "postalCode": "31700",
        "city": "BLAGNAC",
        "country": "FR",
        "full": "2 ROND-POINT DEWOITINE 31700 BLAGNAC"
    },
    "industryCode": "30.30Z",
    "industryLabel": "Manufacture of air and spacecraft and related machinery",
    "industryClassification": "NAF rev. 2 (label: NACE Rev. 2)",
    "employeesRange": "10000+",
    "vatNumber": "FR89383474814",
    "vatValid": true,
    "vatCheckSource": "VIES",
    "vatName": "SAS AIRBUS",
    "vatAddress": "2 RPT EMILE DEWOITINE, 31700 BLAGNAC",
    "lei": "529900FCMZ4LKXFD0R69",
    "leiStatus": "ISSUED",
    "website": null,
    "isNaturalPerson": false,
    "source": "FR_SIRENE",
    "sourceUrl": "https://annuaire-entreprises.data.gouv.fr/entreprise/383474814",
    "licence": "Licence Ouverte / Open Licence 2.0 (Etalab)",
    "attribution": "France: INSEE SIRENE and RNE via API Recherche d'entreprises ... VAT check: VIES, European Commission ... LEI: GLEIF, CC0 1.0 ...",
    "fetchedAt": "2026-09-27T10:53:51.616Z",
    "raw": null
}
```

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel. The Output tab has four views: **Overview**, **KYB and VAT check**, **B2B lead enrichment**, and **Sources and licences**. A `SUMMARY` record in the key-value store lists counts, skipped natural persons, IDs not found and errors.

### Data fields

| Field                                                        | Description                                                                                     |
| ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------- |
| `country`, `registryId`                                      | Country and national ID: SIREN (FR), organisasjonsnummer (NO), Y-tunnus (FI), registrikood (EE) |
| `name`, `legalForm`, `legalFormCode`                         | Registered name and legal form                                                                  |
| `status`, `statusDetail`                                     | `active` or `inactive`, plus the source's wording (ceased, bankrupt, in liquidation)            |
| `registrationDate`                                           | Creation or first registration date                                                             |
| `address`                                                    | `street`, `postalCode`, `city`, `country`, `full`                                               |
| `industryCode`, `industryLabel`                              | NAF (FR), SN (NO), TOL (FI) in NACE format, with label. Estonia: not available                  |
| `employeesRange`, `employeesCount`                           | INSEE headcount band (FR) or exact count (NO)                                                   |
| `vatNumber`, `vatValid`, `vatName`, `vatAddress`, `vatError` | VAT number and VIES answer                                                                      |
| `lei`, `leiStatus`                                           | GLEIF Legal Entity Identifier                                                                   |
| `website`                                                    | When the registry API has it (NO, FI)                                                           |
| `isNaturalPerson`                                            | True for sole traders                                                                           |
| `source`, `sourceUrl`, `licence`, `attribution`              | Where the data comes from and the licence text you must keep                                    |
| `raw`                                                        | Original source record                                                                          |

### How much does it cost to look up EU companies?

This Actor uses **pay per event** pricing:

- **$4.00 per 1,000 company results** ($0.004 each)
- **$0.50 per 1,000 VIES VAT checks** ($0.0005 each). Failed checks, such as a member state being offline, are not charged.
- A tiny start fee per run.

**Bulk VAT validation costs $0.50 per 1,000 numbers**, the cheapest VIES checker on the Store (others charge $1 to $5 per 1,000). In VAT mode, a number with no linked registry record (for example DE, IT, NL, ES) is charged only the VIES check ($0.0005). French, Finnish, Norwegian and Estonian numbers that match a registry record also return the full company record: one result plus one VIES check ($0.0045). Not charged: numbers with a wrong format (skipped before any call), failed VIES checks such as a member state being offline (saved with `vatError`), unknown IDs and duplicates. Set **Maximum cost per run** to cap spend. The Actor stops before it would go over the cap, also when many lookups run in parallel.

A KYB check of 200 suppliers with VAT validation costs about **$0.90**. Validating 10,000 German or Italian VAT numbers costs about **$5**. With the Apify free plan ($5 monthly credit) you can check about 1,100 companies with VAT validation each month. Compute is included.

### Tips and advanced options

- **Look up by ID when you have it.** Lookup mode is exact and faster than name search. Prefix IDs with the country (`FI:0112038-9`) to skip format guessing.
- **SIRET works too.** A 14-digit French SIRET is reduced to its SIREN.
- **Industry filter.** `industryCodes` matches the start of the main activity code, so `62` keeps all IT services and `62.01` only programming. Norway is filtered on the server. France and Finland are filtered after the name search, so a rare industry may return fewer results than `maxItemsPerQuery`. Estonian results have no industry code and are skipped when the filter is set. French codes from before 2008 (older NAF) have no label.
- **Norwegian names common among sole traders** (for example "Hansen") can return fewer results than `maxItemsPerQuery`. Brreg cannot filter ENK on the server, so the Actor scans up to 30 pages and skips them.
- **Bad VAT numbers do not stop the run.** Numbers with the wrong length or pattern for their country are skipped and listed in `SUMMARY.invalidInput`.
- **VAT mode links registries.** French, Finnish and Norwegian VAT numbers are matched to their registry record automatically. Turn on the Estonian open-data file to match Estonian VAT numbers.
- **LEI lookups are rate limited** to one per second by GLEIF. Leave `includeLei` off for large batches unless you need it.
- **Estonia returns at most 10 companies per name query** because the public autocomplete is capped. Use more specific names.
- **Finnish name search** is loose on the PRH side. The Actor runs a whole-word query first and ranks results by name match.
- **Speed.** Each host has its own rate limiter (France 5/s, Norway 5/s, Finland 2/s, Estonia 2/s, VIES 2/s, GLEIF 1/s). VIES answers take 5 to 7 seconds, so VAT checks run in parallel.

### FAQ, disclaimers and support

**Is this legal?** Yes. All sources are official open data published for reuse: Licence Ouverte 2.0 (France), NLOD 2.0 (Norway), CC BY 4.0 (Finland, Estonia, VIES content) and CC0 (GLEIF). Each item carries the required **attribution**. Keep it when you republish the data.

**What about GDPR?** Registries include sole traders whose business address is often a home address. The Actor **skips natural persons by default** (French entrepreneurs individuels and non-diffusible records, Norwegian ENK, Estonian FIE, GLEIF sole proprietors). In VAT mode a sole trader's number is still validated, but name and address are withheld. French records without any legal form (stubs that often carry a person's name) are treated the same way. French executives who are natural persons are removed from raw records, and phone and e-mail fields are removed from Norwegian raw records. If you switch the filter off, you are responsible for having a lawful basis.

**Why is `vatValid` null?** VIES answers only when the member state's service is up. Check `vatError` (for example `MS_UNAVAILABLE`) and try again later.

**Why no Estonian VAT number?** The public Estonian autocomplete has no VAT field. Turn on `estoniaBulkEnrichment` to add it from the official daily file.

**Why no Estonian industry code or website?** The public autocomplete and the daily basic-data file do not include them. The e-Business Register web page shows them, but this Actor uses open-data APIs only.

**What happens if my input is invalid?** The run still ends **SUCCEEDED** and you pay only the small start fee. No company or VIES check is charged. The dataset gets one help row, and the run status message says the same:

```json
{
    "error": true,
    "errorCode": "EMPTY_INPUT",
    "message": "No company name or registry ID in \"queries\".",
    "howToFix": "Add at least one company name or registry ID to \"queries\" ..."
}
```

Codes: `EMPTY_INPUT` (nothing to search), `INVALID_INPUT` (an unsupported country, NACE code, LEI or VAT format, or a value out of range) and `NO_RESULTS` (the registries answered but nothing matched). If every registry call fails because a source is down, the run fails instead, so you can tell an outage from an input problem.

**Which countries are next?** Tell us in the Issues tab. Custom registry integrations are available on request.

Found a bug or a missing field? Open an issue on the **Issues** tab and we will fix it quickly.

# Actor input Schema

## `mode` (type: `string`):

What to do with your input. Search by company name, look up by registry ID (SIREN, organisasjonsnummer, Y-tunnus, registrikood), validate VAT numbers, or look up LEI codes.

## `countries` (type: `array`):

Registers to query in search and lookup modes: FR France (SIRENE), NO Norway (Brønnøysund), FI Finland (PRH YTJ), EE Estonia (e-Business Register). Ignored in VAT and LEI modes.

## `queries` (type: `array`):

Search mode: company names, e.g. "Nokia". Lookup mode: registry IDs, e.g. 383474814 (FR SIREN), 923609016 (NO), 0112038-9 (FI), 12417834 (EE). Prefix with the country to avoid ambiguity, e.g. NO:923609016. LEI mode: 20-character LEI codes.

## `vatNumbers` (type: `array`):

VAT mode only. EU VAT numbers with country prefix, e.g. FR89383474814, FI01120389, EE101335276, DE123456789. Numbers with a wrong format for their country are skipped without a charge and listed in the SUMMARY record. Norwegian numbers (NO923609016MVA) are checked in the Brønnøysund VAT register because Norway is not in VIES. French, Finnish and Norwegian numbers are also matched to their registry record.

## `maxItemsPerQuery` (type: `integer`):

Maximum companies saved per query in each country. Estonia's public autocomplete returns at most 10.

## `industryCodes` (type: `array`):

Search and lookup modes. Keep only companies whose main activity code starts with one of these NACE codes, e.g. 62 (IT services), 62.01 or 47.64. Works for France, Norway and Finland. Estonian results have no industry code and are skipped when this filter is set. Leave empty for all industries.

## `includeVies` (type: `boolean`):

For each company with a known EU VAT number (France, Finland, Estonia with open-data enrichment), check it live in the EU VIES service and add vatValid, vatName and vatAddress. Each successful check is a small extra charge.

## `includeLei` (type: `boolean`):

Look up the Legal Entity Identifier (LEI) of each company in the GLEIF database by its registry ID. Adds about 1 second per company (GLEIF rate limit).

## `estoniaBulkEnrichment` (type: `boolean`):

The Estonian public autocomplete has no VAT number or registration date. When on, the Actor downloads the official daily open-data file (about 18 MB, CC BY 4.0) once per run and adds VAT number, first registration date and a normalized address. Needed to validate Estonian VAT numbers against a registry record. Adds 5 to 15 seconds.

## `excludeNaturalPersons` (type: `boolean`):

Skip entities that are natural persons, such as French entrepreneurs individuels, Norwegian ENK, Estonian FIE and GLEIF sole proprietors. French records without a legal form are treated the same way. Their registry address is often a home address. Keep this on unless you have a lawful basis to process personal data.

## `onlyActive` (type: `boolean`):

Skip companies that are ceased, deleted, bankrupt or in liquidation.

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

Add the original API record in the raw field. Personal data is removed: natural-person executives from French records, and phone and e-mail fields from Norwegian records.

## Actor input object example

```json
{
  "mode": "search",
  "countries": [
    "FR",
    "NO",
    "FI",
    "EE"
  ],
  "queries": [
    "Nokia"
  ],
  "vatNumbers": [],
  "maxItemsPerQuery": 2,
  "industryCodes": [],
  "includeVies": true,
  "includeLei": true,
  "estoniaBulkEnrichment": false,
  "excludeNaturalPersons": true,
  "onlyActive": false,
  "includeRaw": true
}
```

# Actor output Schema

## `companies` (type: `string`):

No description

## `kyb` (type: `string`):

No description

## `leads` (type: `string`):

No description

## `summary` (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 = {
    "mode": "search",
    "countries": [
        "FR",
        "NO",
        "FI",
        "EE"
    ],
    "queries": [
        "Nokia"
    ],
    "vatNumbers": [],
    "maxItemsPerQuery": 2,
    "industryCodes": [],
    "includeLei": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("rod_analytics/eu-company-lookup").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 = {
    "mode": "search",
    "countries": [
        "FR",
        "NO",
        "FI",
        "EE",
    ],
    "queries": ["Nokia"],
    "vatNumbers": [],
    "maxItemsPerQuery": 2,
    "industryCodes": [],
    "includeLei": True,
}

# Run the Actor and wait for it to finish
run = client.actor("rod_analytics/eu-company-lookup").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 '{
  "mode": "search",
  "countries": [
    "FR",
    "NO",
    "FI",
    "EE"
  ],
  "queries": [
    "Nokia"
  ],
  "vatNumbers": [],
  "maxItemsPerQuery": 2,
  "industryCodes": [],
  "includeLei": true
}' |
apify call rod_analytics/eu-company-lookup --silent --output-dataset

```

## MCP server setup

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

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/KGqaeQfWdOoFE0Js0/builds/pNBpyCIUgxFo6wdD1/openapi.json
