# Europe Company Search: FR, NO, FI, UK by Sector, City, Date (`datacraft-studio/europe-company-search`) Actor

Search registered companies in France, Norway, Finland and the UK by name, sector code, city, legal form and creation date. Official open registry data.

- **URL**: https://apify.com/datacraft-studio/europe-company-search.md
- **Developed by:** [Yahya Nouali](https://apify.com/datacraft-studio) (community)
- **Categories:** Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 company founds

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

## Europe Company Search: FR, NO, FI, UK by Sector, City, Date

Search registered companies in France, Norway, Finland and the United Kingdom from one Actor. Each hit is one dataset row with the same fields: country, id, name, legal form, status, address, activity code and label, registration date, source and licence. A `run_summary` row closes the dataset.

The rows come from the official registers, not from a scraped commercial directory:

| Country | Register | Licence |
| --- | --- | --- |
| France | [Recherche d'entreprises](https://recherche-entreprises.api.gouv.fr) (SIRENE) | Licence Ouverte 2.0 |
| Norway | [Brønnøysund Enhetsregisteret](https://data.brreg.no/enhetsregisteret/api/docs/index.html) | NLOD 2.0 |
| Finland | [PRH YTJ open data v3](https://avoindata.prh.fi/opendata-ytj-api/v3/companies) | CC BY 4.0 |
| United Kingdom | [Companies House](https://developer.company-information.service.gov.uk/) | Open Government Licence v3.0 |

France, Norway and Finland need no API key. The UK needs `COMPANIES_HOUSE_API_KEY`.

### Use cases

**Lead lists.** Pull active restaurants in Lyon (`naceCodes: ["56.10A"]`, `city: "Lyon"`) or new limited companies in Oslo since January (`nativeActivityCodes.NO: ["56.110"]`, `legalForm: "llc"`, `createdFrom`). Filter the dataset with `recordType = company` and send it to a CRM.

**Market mapping.** Compare how many companies in a sector sit in Helsinki and Oslo by running both countries with the same date window and reading `foundNO` and `foundFI` on the summary row. Pair this Actor with the country enrichment Actors when a lead needs officers, accounts or a KYB flag.

### Input

```json
{
  "countries": ["FR"],
  "naceCodes": ["56.10A"],
  "city": "Lyon",
  "activeOnly": true,
  "maxResultsPerCountry": 100
}
```

| Field | Default | What it does |
| --- | --- | --- |
| `countries` | FR, NO, FI, UK | Any mix of `FR`, `NO`, `FI`, `UK`. |
| `name` | empty | Name or fragment. At least 2 characters. |
| `naceCodes` | empty | Sector prefixes. France uses NAF, Norway a næringskode prefix, Finland a TOL prefix, the UK SIC 2007 codes that start with the digits. |
| `nativeActivityCodes` | `{}` | Optional `{ "FR": [], "NO": [], "FI": [], "UK": [] }`. When a country key is set, it replaces `naceCodes` for that country. |
| `city` | empty | Commune or city. France resolves Lyon to postal codes 69001–69009. Norway resolves Oslo to municipality `0301`. The UK keeps companies whose registered-office locality is that city. |
| `postalCode` | empty | One code for every selected country. France and Finland want 5 digits, Norway 4. A wrong shape errors that country instead of searching the whole register. |
| `legalForm` | empty | `llc`, `plc`, `sole_trader`, `partnership` or `association`. |
| `nativeLegalForms` | `{}` | Registry codes that replace `legalForm` for the countries you set. |
| `createdFrom`, `createdTo` | empty | Inclusive `YYYY-MM-DD`. |
| `activeOnly` | `true` | Drops ceased, bankrupt and liquidated companies. In France it also drops a closed establishment in the requested city. |
| `maxResultsPerCountry` | `100` | Cap 10,000. |
| `minRequestIntervalMs` | `300` | France never goes faster than 150 ms (under 7 requests/second). Finland never goes faster than 300 ms. |
| `companiesHouseApiKey` | empty | Secret override of `COMPANIES_HOUSE_API_KEY`. |

You need at least one of name, sector, city, postal code, legal form or creation date. An empty run stops before any request.

`56.10A` is the French NAF code for traditional restaurants. The same token becomes næringskode prefix `56.10`, TOL prefix `5610` and SIC codes `56101`, `56102`, `56103`. It is not crosswalked. Norway's current restaurant code is `56.110` (SN2025) and Finland's is `56111`. Pass those in `nativeActivityCodes` when you search those countries.

Sole traders are `1000` in France and `ENK` in Norway. Companies House and the Finnish company search do not list sole traders, so those countries return a warning and zero rows for `legalForm: "sole_trader"`.

### Output

```json
{
  "recordType": "company",
  "country": "FR",
  "id": "302077821",
  "name": "LE BISTROT DE LYON",
  "legalForm": "llc",
  "legalFormCode": "5499",
  "legalFormLabel": "Société à responsabilité limitée (sans autre indication)",
  "status": "active",
  "statusDetail": "Active",
  "address": "64 RUE MERCIERE 69002 LYON",
  "city": "LYON",
  "postalCode": "69002",
  "activityCode": "56.10A",
  "activityLabel": "Restauration traditionnelle",
  "registrationDate": "2019-06-24",
  "employeesBand": "20 to 49 employees",
  "source": "Recherche d'entreprises (SIRENE)",
  "license": "Licence Ouverte 2.0",
  "sourceUrl": "https://annuaire-entreprises.data.gouv.fr/entreprise/302077821",
  "chargedEvents": "company-found",
  "chargeSimulated": false
}
```

`legalForm` is the normalised value (`llc`, `plc`, `sole_trader`, `partnership`, `association`, `other`). `legalFormCode` is the registry code. `employeesBand` is the French headcount band or, in Norway, a headcount when the register publishes one. Finland and the UK search payloads do not include a headcount.

The last item is `recordType: "run_summary"`. It counts deliveries, filter drops, per-country errors and the price that applied. Keep `recordType = company` for a lead export.

### Pricing

Pay per event. No start fee and no synthetic event.

| Event | Price | When |
| --- | --- | --- |
| `company-found` | $0.002 | A company row was delivered. Primary event. |
| — | $0 | Empty search, filtered-out company, duplicate id, registry error, missing UK key, summary row. |

1,000 delivered companies cost $2. The pricing JSON is in `PUBLISHING.md`.

On a local run without pay-per-event pricing, rows still come back with `chargeSimulated: true`. On the platform, a row is pushed only after `Actor.charge` accepts it. If the event budget is spent, later companies are not delivered and `stoppedReason` is `charge_limit`.

### UK API key

Create a key in the [Companies House developer hub](https://developer.company-information.service.gov.uk/). On Apify, store it as the secret `COMPANIES_HOUSE_API_KEY`. You can also pass `companiesHouseApiKey` for one run. The key is the HTTP Basic username and an empty password. It is not written to the dataset or the log.

The Actor keeps one token bucket of **600 requests per 5 minutes** for the whole run, and it retries HTTP 429 and 5xx. Name-only searches use `/search/companies`. Sector, city, postal code, legal form and incorporation dates use `/advanced-search/companies`.

### Rate limits

- France: at least 150 ms between calls, under the published ceiling of about 7 requests/second. Pagination is 25 rows per page and at most 400 pages.
- Norway: at least 200 ms. A query stops at 10,000 registry hits.
- Finland: at least 300 ms, because the PRH quota is shared by every caller.
- UK: the token bucket above, plus the minimum interval.

### Caveats

France has no creation-date query parameter. The Actor pages through the other filters and keeps companies whose `date_creation` falls inside `createdFrom` / `createdTo`. A narrow date on a broad query can read up to 10,000 companies and still return fewer than `maxResultsPerCountry`. `truncated` on the summary is then true.

When a French city is set, a row is a company with an establishment in that city's postal codes. A closed establishment, or one whose own NAF code does not match, is dropped. Chains are returned with the local establishment address, not the distant head office.

Norway's `registrationDate` is the Enhetsregisteret registration date, then the foundation date if the registration date is missing. The live næringskode list follows SN2025.

A postal code is one value for every selected country. Search countries separately when the codes differ. A city name is also sent as-is, so `Lyon` is the right city for France and the wrong city for Norway.

Companies House advanced search stops at 5,000 hits per query. This build was not smoke-tested against the live UK API; the UK path is covered by mocked tests. Set your own key before a live UK run.

### Automate with Make, Zapier or n8n

Put the Apify token in the integration credentials. Do not paste it into the Actor input.

**Make.** Watch new rows in Google Sheets, then **Apify → Run an Actor** (synchronous) with the JSON below, then **Get dataset items**, keep rows where `recordType` is `company`, and update the sheet or create the CRM lead.

```json
{
  "countries": ["FR", "NO"],
  "naceCodes": ["62.01"],
  "legalForm": "llc",
  "createdFrom": "2024-01-01",
  "activeOnly": true,
  "maxResultsPerCountry": 200
}
```

**Zapier.** Trigger on a new HubSpot company or a schedule. Action **Apify → Run Actor** with that JSON. Formatter keeps `name`, `city`, `activityCode` and `sourceUrl`. Update the HubSpot company or append a Google Sheet row. A **Finished Actor Run** trigger can do the same after a scheduled run.

**n8n.** Install the official node [`@apify/n8n-nodes-apify`](https://docs.apify.com/platform/integrations/n8n). Use resource **Actors**, operation **Run an Actor and Get Dataset**, memory **512**, and the input JSON in **Input JSON**. Authenticate with an Apify API key or OAuth2. An importable workflow is in [`examples/n8n-europe-company-search.json`](examples/n8n-europe-company-search.json): Schedule → Run an Actor and Get Dataset → IF `recordType` equals `company`. Point the Actor id at `YOUR_USERNAME~europe-company-search` and add a Slack node on the true branch if you want the lead posted.

### Run locally

```bash
npm install
npm test
npm run build
npm run smoke
npm start
```

`npm run smoke` calls the live French, Norwegian and Finnish registers (restaurants in Lyon, Oslo and Helsinki) and does not call Companies House.

The Actor reads JSON from the Apify input. For a local process run, `apify run` with `storage/key_value_stores/default/INPUT.json` is the usual path. `examples/input.lyon.json` is a starting point.

```bash
npm run package:actor
```

writes `artifacts/europe-company-search-actor.tar.gz` without `node_modules`.

### Licence notes

Attribute the register on every redistribution. The French rows include Licence Ouverte 2.0 / Etalab. Norwegian rows include NLOD 2.0. Finnish rows include CC BY 4.0 and name the Finnish Patent and Registration Office and YTJ; this Actor is not an official PRH service. UK rows include the Open Government Licence v3.0. NAF and catégorie juridique labels are bundled from INSEE under Licence Ouverte 2.0. SIC 2007 labels are the Office for National Statistics condensed titles.

### Recherche de sociétés en Europe

Cet Actor interroge les registres officiels de France, de Norvège, de Finlande et du Royaume-Uni. Une ligne `company` par société, puis une ligne `run_summary`.

**Listes de prospection.** Restaurants actifs à Lyon : `naceCodes: ["56.10A"]`, `city: "Lyon"`. Sociétés norvégiennes créées depuis janvier : `nativeActivityCodes.NO: ["56.110"]`, `createdFrom: "2024-01-01"`. Filtrez `recordType = company` avant l'export CRM.

**Cartographie de marché.** Le même filtre sectoriel sur Oslo et Helsinki, puis `foundNO` et `foundFI` dans le résumé. Les codes ne sont pas convertis d'une nomenclature à l'autre : la France reste en NAF rév. 2 (`56.10A`), la Norvège en SN2025 (`56.110` pour les restaurants), la Finlande en TOL (`56111`), le Royaume-Uni en SIC 2007 (`56101`).

**Tarif.** Événement unique `company-found` à 0,002 $, événement principal. Une recherche vide, une société hors filtre, un doublon ou une erreur de registre ne sont pas facturés. Pas d'événement synthétique.

**Clé Royaume-Uni.** Variable secrète `COMPANIES_HOUSE_API_KEY`, ou champ secret `companiesHouseApiKey`. Le jeton reste dans les identifiants Make, Zapier ou n8n, jamais dans l'entrée. Le plafond Companies House est de 600 requêtes par 5 minutes.

**Licences.** France : Licence Ouverte 2.0. Norvège : NLOD 2.0. Finlande : CC BY 4.0 (PRH / YTJ). Royaume-Uni : Open Government Licence v3.0.

**Limites utiles.** La France n'a pas de filtre de date de création : l'Actor pagine puis filtre `date_creation`, à moins de 7 requêtes par seconde. La Finlande attend au moins 300 ms entre deux appels. Les entreprises individuelles britanniques et finlandaises ne sont pas dans ces moteurs de recherche.

# Changelog

This Actor's version history is a separate document: https://apify.com/datacraft-studio/europe-company-search/changelog.md

# Actor input Schema

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

Registries to search. France, Norway, Finland and the United Kingdom can be combined in one run.

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

Optional name or name fragment. France searches the legal name and address. Norway, Finland and the UK search the registered name.

## `naceCodes` (type: `array`):

Activity prefixes. Each code is applied in the national format: NAF for France, næringskode for Norway, TOL for Finland and SIC 2007 for the UK. 56.10A is exact in France and becomes 56.10, 5610 and 5610x elsewhere. Classifications are not crosswalked: Norway and Finland now use newer restaurant codes (56.110 and 56111).

## `nativeActivityCodes` (type: `object`):

Optional exact codes per country. When a country key is set, it replaces naceCodes for that country. Keys are FR, NO, FI and UK.

## `city` (type: `string`):

Commune or city name. France resolves it to postal codes (Lyon covers 69001–69009). Norway resolves it to a municipality number. Finland passes it as location. The UK passes it as the Companies House location.

## `postalCode` (type: `string`):

One postal code applied to every selected country. France and Finland expect 5 digits, Norway 4 digits. A code in the wrong shape skips that country with an error and does not search the whole country.

## `legalForm` (type: `string`):

Normalised form. Private limited covers SARL/SAS, AS, OY and Ltd. Public limited covers SA, ASA, OYJ and Plc. Sole traders exist in France and Norway only.

## `nativeLegalForms` (type: `object`):

Optional registry codes per country. When a country key is set, it replaces legalForm for that country. Example: {"FR":\["5710"],"NO":\["AS"]}.

## `createdFrom` (type: `string`):

Inclusive start date, YYYY-MM-DD. France has no such API filter: date_creation is applied after download. Norway uses Enhetsregisteret registration date. Finland uses registrationDate. The UK uses incorporation date.

## `createdTo` (type: `string`):

Inclusive end date, YYYY-MM-DD.

## `activeOnly` (type: `boolean`):

Keep companies the registry still treats as active. Closed French establishments in the requested city are dropped. Bankrupt, liquidated and ceased companies are dropped.

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

Stop each country after this many delivered companies. The registries themselves cap a query around 10,000 hits.

## `minRequestIntervalMs` (type: `integer`):

Pause between calls to the same registry. France never goes faster than 150 ms (under the 7 requests/second ceiling). Finland never goes faster than 300 ms. Norway uses at least 200 ms. The UK also keeps a 600 requests / 5 minutes token bucket.

## `companiesHouseApiKey` (type: `string`):

Optional. Overrides the COMPANIES_HOUSE_API_KEY secret for this run. Required only when UK is selected. The key is sent as the HTTP Basic username and is not written to the dataset or the log.

## Actor input object example

```json
{
  "countries": [
    "FR"
  ],
  "naceCodes": [
    "56.10A"
  ],
  "nativeActivityCodes": {},
  "city": "Lyon",
  "nativeLegalForms": {},
  "activeOnly": true,
  "maxResultsPerCountry": 100,
  "minRequestIntervalMs": 300
}
```

# Actor output Schema

## `overview` (type: `string`):

One row per company, then a run_summary row. Filter recordType to company when you export a lead list.

# 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 = {
    "countries": [
        "FR"
    ],
    "name": "",
    "naceCodes": [
        "56.10A"
    ],
    "nativeActivityCodes": {},
    "city": "Lyon"
};

// Run the Actor and wait for it to finish
const run = await client.actor("datacraft-studio/europe-company-search").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 = {
    "countries": ["FR"],
    "name": "",
    "naceCodes": ["56.10A"],
    "nativeActivityCodes": {},
    "city": "Lyon",
}

# Run the Actor and wait for it to finish
run = client.actor("datacraft-studio/europe-company-search").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 '{
  "countries": [
    "FR"
  ],
  "name": "",
  "naceCodes": [
    "56.10A"
  ],
  "nativeActivityCodes": {},
  "city": "Lyon"
}' |
apify call datacraft-studio/europe-company-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datacraft-studio/europe-company-search"
        }
    }
}
```

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/PV4c9KdFQIP7hV1DX/builds/N96AubIygsudAYoag/openapi.json
