# EU Company Registry Search – France, Norway, Finland, Czechia (`liora-tools/eu-company-registry`) Actor

Reliable registry lookups: "not found" and "source down" are separate free status rows, never a silent empty result. Official FR SIRENE, NO Brreg, FI PRH/YTJ, CZ ARES by name or number: registration and VAT number, legal form, status, address, NACE, employees.

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

## Pricing

from $2.00 / 1,000 company 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

## EU Company Registry API – France, Norway, Finland, Czechia (Official Data)

Look up companies in **four official European business registers with one input** – France (SIRENE/RNE), Norway (Brønnøysund), Finland (PRH/YTJ) and Czechia (ARES). Search by name or paste registration / VAT numbers and get one clean, unified record per company.

- ✅ **Never a silent empty dataset:** if a source is down you get a free `status: "error"` row naming it; if nothing matched you get a free `status: "no_results"`-type row saying so. Errors and status rows are never charged.
- ✅ Official open-data APIs only – no scraping of websites, no login, no proxies needed
- ✅ One clean, documented schema across all sources
- ✅ Pay only for results: **$0.002 per company** ($2.00 per 1,000). Errors are free.

### Coverage

- **Registers:** France – INSEE SIRENE / RNE via recherche-entreprises.api.gouv.fr; Norway – Brønnøysund Enhetsregisteret (data.brreg.no); Finland – PRH/YTJ open data API v3; Czechia – ARES (ares.gov.cz). No other countries (e.g. DE, NL) yet.
- **Lookups:** company name (`query`) or registration numbers – SIREN/SIRET, Norwegian org.nr, Finnish Y-tunnus, Czech IČO.
- **Fields:** country, registry, registration number, VAT number, name, trade names, legal form (+code), status (active/ceased/bankrupt/in liquidation), registration/ceased date, address, NACE activity code + description, employees band, open establishments, website, revenue/net income/financial year (where published), source URL, matchedBy, fetchedAt. Sole traders (natural persons) are skipped unless `includeSoleTraders` is on.

### When a source is down – error, not empty

- Each register is queried independently, with retries on timeouts/429.
- Register did not answer: **free row** `status: "source_unavailable"` ("This is not a 'no match' result; run again later"). Other countries continue; the run ends **SUCCEEDED**.
- Register answered, no match: **free row** `status: "no_match"` (name search) or `status: "not_found"` (registration number) per country.
- Invalid registration number: free `status: "error"` row. No name and no numbers at all: the run **FAILS** immediately with an input error (nothing charged).

### Cost example and cost cap

- 4 countries × 50 results (default) = up to 200 companies = **$0.40**. Looking up 1,000 registration numbers ≈ $2.00.
- **Cap it two ways:** `maxItems` (total companies, e.g. `100` → max $0.20) and/or **Max charge per run** (Console → Run options, or `maxTotalChargeUsd` in the API). The Actor stops cleanly at the limit. Status rows are free.

### What can you use it for?

- KYB / supplier onboarding: verify that a company exists, is active, and get its legal form, address and VAT number
- Lead enrichment for B2B sales: add registration number, NACE/NAF activity, employee band and (FR) revenue to your CRM
- Bulk validation of SIREN/SIRET, Norwegian org.nr / MVA, Finnish Y-tunnus and Czech IČO / DIČ lists
- Market mapping: find every active company matching a keyword in one or more countries

### Input

| Field | What it does |
|---|---|
| `query` | Company name or keyword, e.g. `Nokia`, `boulangerie lyon` |
| `registrationNumbers` | SIREN, SIRET, FR VAT, NO org.nr / MVA, FI Y-tunnus, CZ IČO / CZ VAT – the country is auto-detected |
| `countries` | Any of FR, NO, FI, CZ (default: all) |
| `maxResultsPerCountry` | Cap per country for name searches |
| `maxItems` | Optional total billable cap for the whole run (empty = no total cap) |
| `onlyActive` | Skip dissolved / ceased companies |
| `includeSoleTraders` | Off by default – sole traders are personal data in most EU countries |

Example input:

```json
{
  "query": "Nokia",
  "registrationNumbers": [
    "552081317",
    "923609016",
    "0112038-9",
    "27082440"
  ],
  "countries": [
    "FR",
    "NO",
    "FI",
    "CZ"
  ],
  "maxResultsPerCountry": 10
}
```

### Output

Each result is one row in the dataset (download as JSON, CSV, Excel or via API). Example:

```json
{
  "country": "FR",
  "registry": "SIRENE / RNE (INSEE, INPI) via recherche-entreprises.api.gouv.fr",
  "registrationNumber": "552081317",
  "vatNumber": "FR03552081317",
  "name": "ELECTRICITE DE FRANCE",
  "tradeNames": [
    "EDF"
  ],
  "legalFormCode": "5599",
  "legalForm": "SA à conseil d'administration",
  "status": "active",
  "registrationDate": "1955-01-01",
  "ceasedDate": null,
  "address": {
    "street": "22-30 22 AVENUE DE WAGRAM 75008 PARIS",
    "postalCode": "75008",
    "city": "PARIS",
    "countryCode": "FR"
  },
  "addressHidden": null,
  "activityCode": "35.11Z",
  "activityCodeSystem": "NAF rév. 2",
  "activityDescription": null,
  "employees": "10000+",
  "establishmentsOpen": 3549,
  "website": null,
  "revenue": 118690000000,
  "netIncome": 11854000000,
  "financialYear": "2024",
  "sourceUrl": "https://annuaire-entreprises.data.gouv.fr/entreprise/552081317",
  "matchedBy": "registrationNumber",
  "query": null,
  "fetchedAt": "2026-10-24T16:33:46+00:00"
}
```

### Reliability – "not found" vs "source down"

Status rows are free (never charged):

- `status: "not_found"` – the registry answered but has no company with that registration number (France: some companies are legally non-public and are not served by the open API).
- `status: "no_match"` – the registry answered but no company matched your name query in that country.
- `status: "source_unavailable"` – the registry did not answer (timeout / rate limit after retries); try again later.
  A per-country `RUN_SUMMARY` (query matches, ids requested, ids found) is written to the key-value store.

### Pricing

Pay-per-event, no subscription:

| Event | Price |
|---|---|
| Company record (`company`) | $0.002 ($2.00 / 1,000) |
| Actor start | $0.00005 |

Error rows and empty results are never charged. Set **Max charge per run** in Apify Console to cap your spend – the Actor stops cleanly when the limit is reached.

### Option names (shared across our open-data Actors)

The five Actors in this pack (Prediction Markets, US Building Permits, EU Company Registry, UK Public Tenders, EU Fuel Prices) use the same names for the same job:

| Job | Option | Notes |
|---|---|---|
| Free-text filter | `keywords` (array) | EU Company Registry uses `query` (one company name) + `registrationNumbers` |
| Date window | `daysBack` + `…From` / `…To` | `issuedFrom/To` (permits), `publishedFrom/To` (tenders) |
| Total billable cap | `maxItems` | available in all five; per-source caps (`maxMarketsPerPlatform`, `maxItemsPerCity`, `maxResultsPerCountry`, `maxPagesPerSource`) still work |
| Only new rows on schedules | `onlyNewSinceLastRun` | EU Fuel Prices: `onlyChangedSinceLastRun` (prices that changed) |
| Which sources | `platforms` / `cities` / `countries` / `sources` | the natural unit of each source |

Status rows always use the same `status` values: `error` / `source_unavailable` (source down), `no_results` / `no_match` / `not_found` (source answered, nothing matched), `no_new` (nothing new since last run). They are never charged.

### FAQ

**Where does the data come from?**\
Only from the official public APIs: recherche-entreprises.api.gouv.fr (Etalab Licence Ouverte 2.0), data.brreg.no (NLOD), avoindata.prh.fi (CC BY 4.0) and ares.gov.cz (open data). No scraping of commercial sites such as Pappers, Northdata or Societe.com.

**Do you return directors or people?**\
No. Officers, shareholders and sole traders are personal data under GDPR, so the Actor deliberately returns company-level fields only. French companies that opted out of public address display (statut de diffusion partielle) are returned with `addressHidden: true`.

**Is the VAT number official?**\
Norway, Czechia and Finland VAT numbers come from the registry. The French intra-EU VAT number is computed from the SIREN with the official key formula – validate on VIES if you need legal certainty.

**Why do I get an error row for a broad Czech search?**\
ARES refuses searches with more than 1,000 matches. Narrow the query; the error row is free.

**Which countries are next?**\
UK Companies House (bring your own free key), Denmark CVR and GLEIF LEI enrichment are on the roadmap.

### Legal & data sources

This Actor only reads public data published by government bodies or by the platforms' own public APIs under open licences (each row has `source`/`license` or `url` fields where available). It returns organisation-level data and deliberately excludes personal data. You are responsible for using the data in line with the source licence and applicable law (e.g. GDPR).

### Integrations

Schedule runs, then push results to Google Sheets, Slack, webhooks, Zapier, Make or your database with Apify integrations, or call the Actor from the Apify API / Python / JavaScript clients.

# Actor input Schema

## `query` (type: `string`):

Company name or keyword to search in every selected register (e.g. 'Michelin', 'Equinor', 'Nokia', 'Škoda').

## `registrationNumbers` (type: `array`):

Exact look-ups. Accepts French SIREN (9 digits), SIRET (14) or FR VAT; Norwegian org.nr (9 digits, optional NO…MVA); Finnish Y-tunnus (1234567-8) or FI VAT; Czech IČO (up to 8 digits) or CZ VAT. Prefix with FR:, NO:, FI:, CZ: to force a country.

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

Registers to search.

## `maxResultsPerCountry` (type: `integer`):

Cap on name-search matches per register (exact number look-ups are always returned).

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

Optional total cap on billable companies for the whole run (same option name as in our other open-data Actors). Leave empty for no total cap; `maxResultsPerCountry` still applies. For a hard dollar cap use 'Max charge per run' in Run options.

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

Skip dissolved, bankrupt or deregistered companies in name searches.

## `includeSoleTraders` (type: `boolean`):

Sole traders are natural persons and their trade name is often a personal name. Off by default for GDPR reasons; turn on only if you have a lawful basis.

## Actor input object example

```json
{
  "query": "Nokia",
  "registrationNumbers": [
    "923609016",
    "0112038-9"
  ],
  "countries": [
    "FR",
    "NO",
    "FI",
    "CZ"
  ],
  "maxResultsPerCountry": 50,
  "onlyActive": true,
  "includeSoleTraders": false
}
```

# Actor output Schema

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

Rows saved by this run (overview table).

# 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 = {
    "query": "Nokia",
    "registrationNumbers": [
        "923609016",
        "0112038-9"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("liora-tools/eu-company-registry").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 = {
    "query": "Nokia",
    "registrationNumbers": [
        "923609016",
        "0112038-9",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("liora-tools/eu-company-registry").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 '{
  "query": "Nokia",
  "registrationNumbers": [
    "923609016",
    "0112038-9"
  ]
}' |
apify call liora-tools/eu-company-registry --silent --output-dataset

```

## MCP server setup

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

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/4DO3rc5PZtM5XWSXa/builds/52K2jTDQnV17MxDwM/openapi.json
