# Company Register Search: France SIREN/SIRET + Global LEI (`humble-echidna/company-registers`) Actor

Official company data without an API key: search French companies by name, SIREN, SIRET or VAT and any company worldwide by name or LEI, or monitor new French company registrations daily (BODACC), by département and NAF code. One clean schema, LEI<->SIREN links. Companies only.

- **URL**: https://apify.com/humble-echidna/company-registers.md
- **Developed by:** [Michael Costa](https://apify.com/humble-echidna) (community)
- **Categories:** Business, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 companies

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 Company Register Search: France SIREN/SIRET + Global LEI do?

**Company Register Search** looks up and searches companies in two **official, free registers**: France's
**SIREN/SIRET** register and the **Global LEI Index**. Give it names, SIREN, SIRET, VAT or LEI numbers, or filters,
and get one clean record per company. No API key, no login.

**Companies only.** It never requests directors or other people, and sole traders (entrepreneurs individuels, LEI
sole proprietors) are never returned.

**Monitor new companies:** set `mode` to `newCompanies` to get the companies newly registered in France, from the
official BODACC daily files, filtered by département, region and NAF code, each returned once
([how](#monitor-new-companies-registered-in-france)).

**Try it in one click:** the input comes pre-filled with the search `airbus`. That's up to 20 companies (10 from each
register), about $0.06 (20 × $0.003 per company, plus $0.00005 for the run start). **Then replace it with what you
actually want.**

### What data does Company Register Search return?

| Field | Example | Notes |
|---|---|---|
| `name` | `AIRBUS` | The legal name. |
| `register` | `france` | `france` or `lei`. |
| `status` | `active` | Active or closed. |
| `legalForm` | `5710`, `SAS, société par actions simplifiée` | Code and name. |
| `foundedOn`, `closedOn` | `1991-10-18` | YYYY-MM-DD. |
| `address` | `2 ROND-POINT DEWOITINE 31700 BLAGNAC` | Registered address, split into lines, postal code, city and country. |
| `identifiers` | `siren`, `siret`, `lei`, `vatNumbers` | Every identifier, with French records and LEI records linked both ways. |
| `france.activity` | `30.30Z`, `Construction aéronautique et spatiale` | NAF/APE code with INSEE's label (French records). |
| `france.sizeCategory`, `france.employees` | `GE`; `min` 10000 | Size and employee range as numbers as well as INSEE's code. |
| `france.establishments` | `total` 11, `open` 6 | |
| `france.financials` | `2024`: revenue 57412795000, net income 2206027000 | Published revenue and net income, in euros. |
| `france.flags` | `qualiopiCertified`, `socialEconomy`, ... | Labels such as ESS, mission company, RGE, Qualiopi. |
| `lei` | category, jurisdiction, registration status, next renewal | LEI records only; `null` on French records. |
| `bodacc` | issue, `publishedOn`, `activity`, `naf`, `capital` | New companies only (`newCompanies` mode): the BODACC registration notice. |
| `attribution` | source, licence, `lastUpdated`, `fileUrl` | The credit the licence asks for (BODACC records also name the file). |
| `id` | `FR-383474814` | Stable across runs (`FR-<SIREN>`, `LEI-<LEI>`). |

Every company has the same top-level fields; the full record is under [Output](#output).

### How much does it cost to search company registers?

You pay per company returned: **$3.00 per 1,000 companies**, plus $0.00005 each time a run starts. A company found in
both registers is two results (one French record, one LEI record). The registers themselves are free. A company found
by several of your inputs is returned, and charged, once. A search that matches nothing costs nothing but the start
fee. Adding the LEI to French companies is free.

- **The example below:** 20 companies × $0.003 = $0.06, plus the $0.00005 start fee.
- **A month, for example:** enriching 2,000 SIRENs from your CRM against the French register only: 2,000 × $0.003 =
  **$6.00**; or a monthly lead list of 1,000 companies from filters: **$3.00**.
- **New companies:** same price per company returned. Companies outside your filters, companies whose NAF code isn't
  known yet, and failed lookups are never charged, and with only-new on each company is charged once. A scheduled run
  on a day with no new issue costs only the start fee.
- **Caps:** **Max results per run** in the input, and **Maximum cost per run** in the run options. It stops cleanly at
  whichever comes first, and stops fetching as soon as the limit is covered, so a capped run is also a fast one.

**Speed** (measured): a 1,000-company French list with LEIs added takes about a minute, a 1,000-record LEI list
about 30 seconds, and numbers are looked up at about one per second (the French API has no batch lookup; the LEI
side of a list of numbers is fetched 50 at a time).

### How to search the French company register and the LEI index

1. Open the actor and type company names into **Company names to search for**, or numbers into **SIREN, SIRET, VAT or
   LEI numbers**, one per line.
2. Choose the **Registers** (France, LEI, or both) and, for lead lists, add filters such as activity codes,
   departments, size or revenue.
3. Click **Start**.
4. Open the **Output** tab and export the companies as JSON, CSV or Excel, or read them through the API.

The two registers:

- **France**: every French company in the SIREN/SIRET register (INSEE Sirene and INPI RNE), through the government's
  API Recherche d'entreprises, the API behind the Annuaire des Entreprises.
- **Global LEI Index**: every company or other legal entity worldwide that has a Legal Entity Identifier (LEI), from
  GLEIF, the foundation that runs the LEI system.

For French companies you also get activity, size, employees, establishments, published revenue and net income, and
labels (ESS, mission company, RGE, Qualiopi...). French companies and their LEI records are **linked both ways**: a
French company gets its LEI, and an LEI record gets its SIREN, so you can join the two.

### Monitor new companies registered in France

Set **Mode** to `newCompanies` and the actor reads **BODACC A**, the official bulletin in which every company
registration at a French commercial court is published, from the daily files of its publisher, DILA
([echanges.dila.gouv.fr](https://echanges.dila.gouv.fr/OPENDATA/BODACC/FluxAnneeCourante/)). It returns the
**companies registered since your last run**, in the places and activities you choose. About 860 companies are
registered on a publication day (5 issues a week), 90 of them in Paris.

1. Set **Mode** to `newCompanies`.
2. Choose where: **departments** (`75`, `69`, `2A`, `974`...), **regions** (`ile-de-france`, `bretagne`...) or
   **postal codes**. Leave them all empty for all of France.
3. Optionally choose what: **activity codes** (NAF, e.g. `62.01Z`) or **activity sections** (e.g. `J`). A NAF filter
   needs a place filter (see below).
4. Save it as a task and add a daily **schedule** (issues are posted at about 07:00 Paris time), and send the new
   companies where you work with a webhook or Make, Zapier or n8n.

How it works:

- **Only new.** With **onlyNew** (on by default) the actor remembers, in a key-value store in your own account and
  separately for each filter combination, the last BODACC issue it read and the companies it returned. The first run
  reads the last **sinceDays** days (default 3); every later run reads only the issues published since (at most 31
  days back). A run with nothing new downloads nothing and charges only the start fee.
- **Places are free to filter**: the whole file is read and filtered by the registered office's postal code.
- **NAF codes cost a lookup.** BODACC notices describe the activity in words (`activity`, as published) but carry no
  NAF code, so with a NAF filter each company in your area is looked up in the French register (API Recherche
  d'entreprises) for its code. That is why a NAF filter needs a place filter, and why **maxNafLookups** caps the
  lookups per run (default 300, at most 1,000; about 2 per second). Only companies that match are charged.
- **Companies too new to have a NAF code are held, not charged.** INSEE classifies a new company some days after it
  registers; until then the register shows `00.00Z` or doesn't list it yet. On our Paris test (below) that was 40 of
  211 companies. They are not returned and not charged, and are looked up again on each later run for up to 7 days
  after publication, then dropped. Companies over the lookup cap, a failed lookup, or companies cut by Max results or
  your maximum cost are held the same way. `RUN_STATS.held` counts them by reason.
- **Companies only, by structure.** Two thirds of the registrations in BODACC are sole traders (people): their notices
  are dropped whole. Company notices also name the managers and sometimes a previous owner: those parts are emptied as
  the file is read and are never returned or stored. So is the notices' free text about the business's origin. The
  memory kept between runs holds SIREN numbers, dates and issue numbers only.
- **Only registrations of new companies**: "Immatriculation d'une personne morale" notices, with or without activity
  (`withoutActivity` marks holding and dormant companies). Registrations of a company moving from another court,
  transformations and corrections are left out.

#### Example: new software and media companies in Paris

```json
{"mode": "newCompanies", "departments": ["75"], "activitySections": ["J"], "sinceDays": 3}
```

A local run on 2026-09-26 read the two issues of the last three days (1,081 company registrations in France), looked
up the 211 in Paris, and returned **28** (13 in 62.01Z, 5 in 63.12Z, 4 in 62.02A, 4 in 58.29C...) for 28 × $0.003 =
**$0.084**, in 112 seconds. 40 more were held for the next run because INSEE hadn't classified them yet. One of them
(real output):

```json
{
  "id": "FR-130137490",
  "register": "bodacc",
  "name": "Koten AI",
  "status": null,
  "country": "FR",
  "legalForm": {"code": "5710", "name": "Société par actions simplifiée"},
  "foundedOn": "2026-09-16",
  "closedOn": null,
  "address": {"lines": ["59 rue de Ponthieu"], "postalCode": "75008", "city": "Paris", "region": null,
              "country": "FR", "full": "59 rue de Ponthieu, 75008 Paris"},
  "identifiers": {"siren": "130137490", "siret": null, "lei": null, "vatNumbers": [],
                  "registrationNumber": "130137490", "registrationAuthority": "RCS Paris"},
  "france": null,
  "lei": null,
  "bodacc": {
    "announcementRef": "7580BP2026B4578", "announcementNumber": 1506, "issue": "20260184",
    "publishedOn": "2026-09-25", "registrationDate": "2026-09-16", "activityStartDate": "2026-10-01",
    "creationCategory": "Immatriculation d'une personne morale (B, C, D) suite à création d'un établissement principal",
    "withoutActivity": false,
    "activity": "Édition de logiciels applicatifs",
    "naf": {"code": "58.29C", "label": "Édition de logiciels applicatifs", "naf2025Code": "58.29Y", "section": "J",
            "sectionLabel": "Information et communication"},
    "acronym": null, "tradeName": null,
    "capital": {"amount": 1000.0, "currency": "EUR", "variable": null},
    "department": "75",
    "court": "GREFFE DU TRIBUNAL DES ACTIVITÉS ECONOMIQUES DE PARIS"
  },
  "url": "https://annuaire-entreprises.data.gouv.fr/entreprise/130137490",
  "attribution": {"source": "bodacc.fr/DILA", "licence": "Licence Ouverte 2.0",
                  "licenceUrl": "https://www.etalab.gouv.fr/licence-ouverte-open-licence/", "lastUpdated": "2026-09-25",
                  "fileUrl": "https://echanges.dila.gouv.fr/OPENDATA/BODACC/FluxAnneeCourante/RCS-A_BXA20260184.taz",
                  "fileName": "RCS-A_BXA20260184.taz", "fileDate": "2026-09-25T05:00:10Z"},
  "query": "new companies: départements 75; NAF J",
  "scrapedAt": "2026-09-26T02:26:16Z"
}
```

`naf` is filled only when a NAF filter was set (otherwise `null`: no lookup is made), and `legalForm.code` with it.
`status` is `null`: BODACC doesn't say. Without a NAF filter, all of France took 6 seconds for 1,081 companies
(2 issues).

#### What the new-companies mode deliberately doesn't return

- **Managers, partners and other people** named in the notices (`administration`), and **sole traders**, whose notices
  are dropped whole.
- **Previous owners or operators** of a business bought or rented (`precedentProprietaire`, `precedentExploitant`),
  and the notices' free-text `descriptif` and `origineFonds`, which can name people.
- **Other BODACC notices**: sales, changes, removals, insolvency (BODACC B and C) aren't read.

### Example: "airbus" in both registers

The pre-filled input:

```json
{"searchTerms": ["airbus"], "registers": ["france", "lei"], "maxResultsPerSearch": 10, "crossLink": true, "status": "any"}
```

It returned 20 companies: 10 French records (AIRBUS, AIRBUS HELICOPTERS, AIRBUS OPERATIONS, ...) and 10 LEI records
(AIRBUS in France, AIRBUS SE in the Netherlands, ...). The first one (real output from a local run on 2026-09-25;
`france.flags` and `collectiveAgreements` shortened):

```json
{
  "id": "FR-383474814",
  "register": "france",
  "name": "AIRBUS",
  "status": "active",
  "legalForm": {"code": "5710", "name": "SAS, société par actions simplifiée"},
  "foundedOn": "1991-10-18",
  "address": {"full": "2 ROND-POINT DEWOITINE 31700 BLAGNAC", "postalCode": "31700", "city": "BLAGNAC", "country": "FR"},
  "identifiers": {"siren": "383474814", "siret": "38347481400100", "lei": "529900FCMZ4LKXFD0R69",
                  "vatNumbers": ["FRZU383474814", "FR89383474814"]},
  "france": {
    "activity": {"code": "30.30Z", "label": "Construction aéronautique et spatiale"},
    "sizeCategory": {"code": "GE", "label": "Large (GE)", "year": "2023"},
    "employees": {"code": "53", "min": 10000, "max": null, "label": "10 000 salariés et plus", "year": "2023"},
    "establishments": {"total": 11, "open": 6},
    "financials": [{"year": "2024", "revenue": 57412795000, "netIncome": 2206027000}]
  },
  "url": "https://annuaire-entreprises.data.gouv.fr/entreprise/383474814"
}
```

### Input

| Field | What it does |
|---|---|
| **Company names to search for** | One per line; each is searched in every selected register, best match first. A line that is a number is looked up as one. |
| **SIREN, SIRET, VAT or LEI numbers** | Exact lookups, one per line, in any common form or as an Annuaire des Entreprises / GLEIF link. |
| Registers | France, the Global LEI Index, or both (default). |
| Max companies per search | 10 by default, up to 10,000, per register. |
| Add each French company's LEI | On by default; free. |
| Filter: status | Active or closed only (both registers). |
| France filters | NAF/APE activity codes, NAF sections, departments, postal codes, INSEE legal forms, size (PME/ETI/GE), employee ranges, minimum/maximum revenue. Any of them limits searches to the French register. |
| LEI filters | Countries, entity categories (general, branch, fund, ...), LEI registration status (issued, lapsed, ...). Any of them limits searches to the LEI index. |
| Mode | `search` (default): everything above. `newCompanies`: new French companies from BODACC ([how](#monitor-new-companies-registered-in-france)). |
| France: regions | The 18 regions, in both modes (e.g. `ile-de-france`, `bretagne`, `la-reunion`). |
| New companies: days to look back (`sinceDays`) | First run, or every run with only-new off: the last 1 to 31 days of issues (default 3). |
| New companies: only new (`onlyNew`) | On by default: each company once, and only the issues since the last run. |
| New companies: max NAF lookups (`maxNafLookups`) | With a NAF filter: lookups per run, default 300, up to 1,000. |
| Max results per run | Cap the total number of companies across all inputs and registers. |

Filters apply to searches; numbers are always looked up. France and LEI filters can't be mixed in one run (each
register can only apply its own); with filters and no names, the filters alone are one search.

```json
{
  "searchTerms": ["airbus", "boulangerie paul"],
  "identifiers": ["662 042 449", "R0MUWSFPU8MPRO8K5P83", "FR89383474814"],
  "registers": ["france", "lei"],
  "maxResultsPerSearch": 10,
  "maxResults": 100
}
```

Software companies in the Rhône with more than EUR 1M revenue:

```json
{
  "registers": ["france"],
  "status": "active",
  "activityCodes": ["62.01Z", "62.02A"],
  "departments": ["69"],
  "revenueMin": 1000000,
  "maxResultsPerSearch": 500
}
```

LEIs in Germany that weren't renewed:

```json
{
  "registers": ["lei"],
  "countries": ["DE"],
  "leiRegistrationStatus": ["LAPSED"],
  "maxResultsPerSearch": 1000
}
```

### Output

Every company has the same fields. Fields a register doesn't publish for a company are `null`; `france` is `null` on
LEI and BODACC records, `lei` is `null` on French and BODACC records, and `bodacc` is `null` except on new companies
(see [the example above](#example-new-software-and-media-companies-in-paris)).

```json
{
  "id": "FR-383474814",
  "register": "france",
  "name": "AIRBUS",
  "status": "active",
  "country": "FR",
  "legalForm": {"code": "5710", "name": "SAS, société par actions simplifiée"},
  "foundedOn": "1991-10-18",
  "closedOn": null,
  "address": {"lines": ["2 ROND-POINT DEWOITINE"], "postalCode": "31700", "city": "BLAGNAC", "region": null,
              "country": "FR", "full": "2 ROND-POINT DEWOITINE 31700 BLAGNAC"},
  "identifiers": {"siren": "383474814", "siret": "38347481400100", "lei": "529900FCMZ4LKXFD0R69",
                  "vatNumbers": ["FRZU383474814", "FR89383474814"], "registrationNumber": "383474814",
                  "registrationAuthority": "INSEE Sirene"},
  "france": {
    "displayName": "AIRBUS", "acronym": null, "tradeName": null,
    "activity": {"code": "30.30Z", "label": "Construction aéronautique et spatiale", "naf2025Code": "30.31Y",
                 "section": "C", "sectionLabel": "Industrie manufacturière"},
    "sizeCategory": {"code": "GE", "label": "Large (GE)", "year": "2023"},
    "employees": {"code": "53", "min": 10000, "max": null, "label": "10 000 salariés et plus", "year": "2023"},
    "isEmployer": true,
    "establishments": {"total": 11, "open": 6},
    "department": "31",
    "location": {"latitude": 43.624640185, "longitude": 1.3835065654},
    "financials": [{"year": "2024", "revenue": 57412795000, "netIncome": 2206027000}],
    "flags": {"socialEconomy": false, "missionCompany": false, "qualiopiCertified": true,
              "genderPayIndexPublished": true, "ghgReportPublished": true},
    "collectiveAgreements": ["1612", "3248", "9999", "1944"],
    "matchedEstablishment": null
  },
  "lei": null,
  "bodacc": null,
  "url": "https://annuaire-entreprises.data.gouv.fr/entreprise/383474814",
  "attribution": {"source": "Annuaire des Entreprises / API Recherche d'entreprises (DINUM), from INSEE (Sirene), INPI (RNE) and other French administrations",
                  "licence": "Licence Ouverte 2.0", "licenceUrl": "https://www.etalab.gouv.fr/licence-ouverte-open-licence/",
                  "lastUpdated": "2026-09-25T09:15:24", "fileUrl": null, "fileName": null, "fileDate": null},
  "query": "airbus",
  "scrapedAt": "2026-09-25T12:00:00Z"
}
```

(`flags` shortened: it has 14 labels.) An LEI record has the same top-level fields, `france: null`, and
`lei`: other names, category, jurisdiction, headquarters address, LEI registration status, initial registration,
last update and next renewal dates, managing LOU, corroboration level, BICs and OpenCorporates id.

`id` is stable across runs (`FR-<SIREN>`, `FR-<SIREN>-<SIRET>` for a SIRET lookup, `LEI-<LEI>`), so you can use it to
deduplicate.

### Run it on a schedule, or from your own code

- **Schedule:** save the input as a task (**Save as a new task** at the top right of the actor's page) and add it to a
  schedule in Apify Console (**Schedules**, **Create new**): for example monthly, to refresh a lead list or re-check
  your customers' status (active or closed).
- **API:** fetch a task's latest results with
  `GET https://api.apify.com/v2/actor-tasks/<task id>/runs/last/dataset/items?status=SUCCEEDED&format=csv` and your
  API token (`format` can also be `json` or `xlsx`).
- **Webhooks and automation:** a webhook when a run succeeds, or Make, Zapier or n8n through Apify's integrations.

In `search` mode each run returns, and charges for, every company it finds; each record's `id` is stable
(`FR-<SIREN>`, `LEI-<LEI>`), so you can update your copy in place. To watch for **new** companies, schedule the
`newCompanies` mode daily: with only-new on, each company is returned once.

#### Can I use Company Register Search from an AI agent (MCP)?

Yes. Connect the agent to Apify's MCP server (`https://mcp.apify.com`) and add `humble-echidna/company-registers` as
a tool; the agent passes the same input JSON as above. For checking one company, have it pass the number in
`identifiers` rather than a name search, and keep **Max companies per search** small. A field left out takes its
default, and `searchTerms` defaults to `airbus`, so a lookup passes `{"identifiers": ["662042449"], "searchTerms": []}`.

### Who it's for

Sales, KYC/compliance and data teams working with French companies or with LEIs: checking and enriching a list of
company numbers, pulling lead lists by activity code, region and size, or linking a company's SIREN to its LEI. And
anyone who sells to new businesses (accountants, banks, insurers, web agencies, office suppliers) and wants the
companies registered in their area each morning. It
replaces manual look-ups on the Annuaire des Entreprises and the GLEIF search, with one clean record per company.

### Why this one?

- **Official sources only**, used the way their owners publish them for machines: no scraping of Pappers, Societe.com
  or other commercial sites, no key, no account.
- **Two registers, one schema.** The same top-level fields for a French company and an LEI record, with what only one
  register has in `france` or `lei`. Cross-links in `identifiers` (SIREN <-> LEI), found through the LEI records'
  French registration (Sirene or the RCS, whichever spelling it uses).
- **Every identifier form.** `662042449`, `662 042 449`, a SIRET, `FR76662042449`, an LEI, or an Annuaire des
  Entreprises or GLEIF link. Check digits are verified, so a typo is reported instead of fetched and charged.
- **Lead lists from filters.** For example: active SAS companies in software (62.01Z) in the Rhône with more than
  EUR 1M revenue; or every LEI in Germany whose registration lapsed.
- **Clean values.** Dates as YYYY-MM-DD, employee ranges as numbers (`min`/`max`) as well as INSEE's code, revenue in
  euros, INSEE's own labels for activity and legal form codes, the LEI legal form's name from the ISO 20275 list.
- **Stays within each API's published rate limit** on its own (France: 2 requests per second against the published
  7; LEI: under 60 per minute) and honours `Retry-After`. It identifies itself honestly (User-Agent
  `HumbleEchidnaApify`) and follows robots.txt.
- **Reliable.** A bad line, an unknown number or one register being down never affects the rest of your run: the
  other register's results are still returned. The run log and the `RUN_STATS` record say exactly which input had a
  problem and why.

### Limits

- **France and the LEI index only.** Other countries' company registers aren't read; companies elsewhere are found
  only if they have an LEI.
- **Up to 10,000 companies per search** (the French API's own limit). For every French company, use the Sirene bulk
  download (see the FAQ).
- **Only new applies to new companies.** `search` mode returns every company it finds on each run.
- **New companies: France only, companies only, BODACC A creation notices only.** A NAF filter needs a place filter
  and is capped at 1,000 lookups a run; companies INSEE hasn't classified within 7 days of publication are dropped
  uncharged. The mode reads DILA's current-year folder: in the first days of January, issues from late December may no
  longer be there (not checked yet), so a first run then may cover fewer days than asked.
- **No people.** Directors, owners and sole traders are never returned (see the FAQ).

### FAQ

#### Does it return directors or owners?

No, by design. Directors (dirigeants) are never requested from the French
API, the managers and previous owners named in BODACC notices are emptied as the file is read (never returned or
stored), and sole traders are never returned: a sole trader's company *is* a person. The French API is asked to leave
them out of searches, and a lookup by number that still finds one reports "sole trader" instead of returning it. The
same goes for LEI sole proprietors. The legal forms that are groups of named people ("entre personnes physiques") are
left out too.

#### Can a registered address still be someone's home?

Yes: many small companies use a founder's home as their
registered office, and the register publishes it as the company's address. If you use these addresses (for example
for marketing), you are responsible for doing so lawfully under the GDPR.

#### Can I get only new companies since my last run?

Yes: `mode` `newCompanies` with `onlyNew` on (the default). The first run returns the last `sinceDays` days; each later
run with the same filters returns only companies registered since, each once. Changing a filter starts a new memory.
It lives in a key-value store named `company-registers-new-companies` in your account; delete it to start over.

#### Why was a new company missing, or returned a day late?

With a NAF filter, a company INSEE hasn't classified yet (code `00.00Z`), one the French register doesn't list yet,
one whose lookup failed, and one over the lookup cap are held, uncharged, and looked up again on your next runs for up
to 7 days. `RUN_STATS.held` counts them by reason. Without a NAF filter nothing is held: every company in your area is
returned the day its notice is published.

#### Why are some French companies missing?

The API only has companies whose data is public ("diffusible"). Companies
that asked for their data not to be published, and those refused registration at the RCS, aren't in it.

#### Why do I get a French record and an LEI record for the same company?

They are two registers with different data.
Choose one in "Registers" if you only want one; they stay linked through `identifiers.siren` and `identifiers.lei`.

#### Can I get every French company?

INSEE publishes the whole Sirene database as a free monthly
[download on data.gouv.fr](https://www.data.gouv.fr/datasets/base-sirene-des-entreprises-et-de-leurs-etablissements-siren-siret/);
GLEIF publishes its [Golden Copy](https://www.gleif.org/en/lei-data/gleif-golden-copy) the same way. A search here
returns at most 10,000 companies (the French API's own limit); this actor is for lookups, searches and filtered lists.

#### Why does something that used to work now fail or return fewer results?

One of the APIs may have changed or be down. The
run log names the input and what went wrong, and the other register and every other input are unaffected. The French
API also limits every network to 30 requests per second, shared with everyone on it; if it keeps answering "too many
requests" after waiting as asked, try again a few minutes later. Please open an issue with the input you used.

#### Is it legal to use French register and LEI data?

Yes. All three sources are official, open data published for reuse.

- **France.** The API Recherche d'entreprises is run by the French government's digital agency (DINUM) and documented
  for machines at [recherche-entreprises.api.gouv.fr/docs](https://recherche-entreprises.api.gouv.fr/docs/): "L'API
  étant totalement ouverte d'accès", with a limit of "au maximum 7 requêtes par seconde par adresse IP" (this actor
  stays at 2). Its data is published on data.gouv.fr under the
  [Licence Ouverte 2.0](https://www.data.gouv.fr/pages/legal/licences/etalab-2.0), which grants "un droit non
  exclusif et gratuit de libre « Réutilisation » de l'« Information » ..., à des fins commerciales ou non", including
  to "la diffuser, la redistribuer, la publier et la transmettre, de l'exploiter à titre commercial", "sous réserve de
  mentionner la paternité de l'« Information » : sa source (a minima le nom du « Concédant ») et la date de la
  dernière mise à jour". That is what every French record's `attribution` carries (source and `lastUpdated`); keep
  it when you publish the data. The licence also says "La « Réutilisation » ne doit pas induire en erreur des tiers
  quant au contenu de l'« Information », sa source et sa date de mise à jour", and that the attribution must not
  "suggérer une quelconque reconnaissance ou caution par le « Concédant »": this actor is not affiliated with or
  endorsed by DINUM, INSEE or INPI. On personal data the licence says it "peut être librement réutilisée ... à
  condition de respecter le cadre légal relatif à la protection des données à caractère personnel", which is why
  people are left out (see above).
- **BODACC (new companies).** DILA, the publisher, puts the BODACC files at
  [echanges.dila.gouv.fr/OPENDATA/BODACC](https://echanges.dila.gouv.fr/OPENDATA/BODACC/) and its data sheet
  (`DILA_BODACC_Presentation_20260327.pdf`, "Conditions de réutilisation") says: "Les données sont réutilisables
  gratuitement sous licence ouverte v2.0", asking reusers to credit "la paternité des données (bodacc.fr/DILA)",
  "l'url d'accès longue de téléchargement" and "le nom du fichier téléchargé ainsi que la date du fichier": every
  BODACC record's `attribution` carries all four (`source`, `fileUrl`, `fileName`, `fileDate`); keep them when you
  publish the data. The data.gouv.fr dataset "BODACC" (licence Licence Ouverte) says "L'accès aux données est libre via
  les protocoles HTTPS : https://echanges.dila.gouv.fr/OPENDATA/", and bodacc.fr's legal notice says "Sauf mention
  contraire, tous les contenus de ce site sont sous licence etalab-2.0". The site's robots.txt
  (`echanges.dila.gouv.fr/robots.txt`) answers "not found", which allows every path; the actor reads it on every run
  and would stop if it ever disallowed the files. (The BODACC API on bodacc.fr is not used: its robots.txt disallows
  `/api/` for every bot but Google's.) DILA's notice on personal data reminds reusers that French data-protection law
  applies to the people named in BODACC: that's why this mode returns companies only (see above). This actor isn't
  affiliated with or endorsed by DILA.
- **Global LEI Index.** GLEIF's [LEI Data Terms of Use](https://www.gleif.org/en/meta/lei-data-terms-of-use):
  "The Access Service on the website http(s)://www.gleif.org is provided for free. The data available through the
  Access Service are provided under the CC0 licence". Its API documentation says "There is no charge for the use of
  GLEIF's LEI data" and "Rate limiting is currently set at 60 requests, per minute, per user" (this actor stays
  below). The terms also ask users not to create "the impression that, data and/or services, except the original LEI
  and LE-RD downloaded by you through the Access Service, are provided or supported or authorized or granted or
  otherwise associated by or with GLEIF": this actor is an independent tool, not a GLEIF service, and is not
  affiliated with or endorsed by GLEIF or any LEI issuer. The LEI records it returns are GLEIF's data as published.

### Related actors

| Actor | Use it when |
|---|---|
| [Dataset Transformer: Filter, Dedupe, Convert](https://apify.com/humble-echidna/dataset-transform) | You want to flatten the nested records into plain columns and export CSV for a CRM import. |
| [Company Career Page Jobs Scraper](https://apify.com/humble-echidna/ats-jobs) | You want to see which of the companies on your list are hiring, and for what. |

### Feedback and support

Found a bug, or need a field or register that isn't here? Open an issue on the **Issues** tab with the input you used.

### Versions

Current version: **1.1**. See the Changelog tab for what changed in each version.

# Changelog

This Actor's version history is a separate document: https://apify.com/humble-echidna/company-registers/changelog.md

# Actor input Schema

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

`search` (the default): look up companies by name, SIREN/SIRET/VAT/LEI or filters in the registers below. `newCompanies`: companies newly registered in France, read from BODACC's daily files, filtered by departments, regions, postalCodes and optionally activityCodes/activitySections; searchTerms, identifiers, registers and the other filters are then ignored or refused.

## `searchTerms` (type: `array`):

Company names (or parts of names), one per line, e.g. `airbus` or `boulangerie paul`. Each line is searched in every selected register and returns up to maxResultsPerSearch from each, best match first. A line that is a SIREN, SIRET, French VAT number or LEI is looked up as one. Left out, it defaults to airbus: pass an empty list for identifier lookups or filter-only searches.

## `identifiers` (type: `array`):

Exact lookups, one per line: a SIREN (9 digits, e.g. 662042449), a SIRET (14 digits), a French VAT number (FR76662042449), an LEI (20 characters, e.g. R0MUWSFPU8MPRO8K5P83), or an Annuaire des Entreprises or GLEIF search link. Each returns the company from every selected register that has it. Check digits are verified, so a typo is reported instead of fetched. For lookups only, set searchTerms to an empty list.

## `registers` (type: `array`):

Which registers to return companies from: `france` (the SIREN/SIRET register, API Recherche d'entreprises) and/or `lei` (the Global LEI Index, GLEIF, all countries). Default both. Each company is one result, so a company found in both registers is two results (linked by their `identifiers`).

## `maxResultsPerSearch` (type: `integer`):

How many companies each search line (or the filters alone) returns at most from each register, best match first: 1 to 10,000 (the French API's own limit per search), default 10.

## `crossLink` (type: `boolean`):

Default true: fill `identifiers.lei` of French companies from the Global LEI Index (one extra request per 50 companies, no extra charge). LEI records always get their French `identifiers.siren` when they have one.

## `status` (type: `string`):

`any` (the default), `active` (active only) or `inactive` (closed / inactive only). France: état administratif; LEI: entity status. Applies to both registers.

## `activityCodes` (type: `array`):

Only French companies with one of these main activity codes (NAF rev. 2 / APE), one per line, e.g. 62.01Z (computer programming) or 6201Z. Search mode: any France filter limits the search to the French register. newCompanies mode: needs departments, regions or postalCodes, and costs one lookup per company in that area (see maxNafLookups).

## `activitySections` (type: `array`):

Only French companies in these NAF sections, one letter per line, e.g. J (information and communication), F (construction), K (finance). In newCompanies mode, like activityCodes: needs a place filter; a company matching either list is kept.

## `departments` (type: `array`):

Only companies in these départements, one per line, e.g. 75, 69, 2A, 971. Search mode: an establishment there. newCompanies mode: the registered office there (from its postal code).

## `regions` (type: `array`):

Only companies in these regions (all their départements), in both modes, e.g. `ile-de-france`, `bretagne`, `auvergne-rhone-alpes`, `provence-alpes-cote-d-azur`, `la-reunion`. Combined with departments: either matches.

## `postalCodes` (type: `array`):

Only companies at these postal codes, one per line, e.g. 75009. Search mode: an establishment there. newCompanies mode: the registered office.

## `legalForms` (type: `array`):

Only these INSEE legal forms (catégorie juridique, 4 digits), one per line, e.g. 5710 (SAS), 5499 (SARL), 5599 (SA), 9220 (association). Sole traders (1000) are never returned.

## `sizeCategories` (type: `array`):

Only French companies in these INSEE size categories: PME (SME), ETI (mid-size), GE (large). Leave empty (the default) for any size.

## `employeeRanges` (type: `array`):

Only French companies in these INSEE employee ranges, one code per line: 00 (none at year end), 01 (1-2), 02 (3-5), 03 (6-9), 11 (10-19), 12 (20-49), 21 (50-99), 22 (100-199), 31 (200-249), 32 (250-499), 41 (500-999), 42 (1,000-1,999), 51 (2,000-4,999), 52 (5,000-9,999), 53 (10,000+), NN (non-employer).

## `revenueMin` (type: `integer`):

Only French companies whose latest published revenue (chiffre d'affaires) is at least this many euros. Companies that don't publish accounts are left out by this filter.

## `revenueMax` (type: `integer`):

Only French companies whose latest published revenue is at most this many euros.

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

Only LEI records whose legal address is in these countries, ISO 3166 two-letter codes, one per line, e.g. DE, GB, US. Any LEI filter limits the search to the Global LEI Index.

## `entityCategories` (type: `array`):

Only LEI records in these categories. Sole proprietors are never returned.

## `leiRegistrationStatus` (type: `array`):

Only LEIs with these registration statuses, e.g. LAPSED to find LEIs that weren't renewed.

## `sinceDays` (type: `integer`):

newCompanies mode only: on a first run (or with onlyNew off), read the BODACC issues published in the last N days, 1 to 31, default 3 (1 = today's issue only). With onlyNew, later runs read every issue since the last run instead, up to 31 days back.

## `onlyNew` (type: `boolean`):

newCompanies mode only, default true: remember (in your account, per filter combination) which companies were already returned and which BODACC issue was read last, so a scheduled run returns and charges each company once, and holds companies whose NAF isn't known yet for a retry. False: every run reads the last sinceDays days and returns everything in them.

## `maxNafLookups` (type: `integer`):

newCompanies mode with activityCodes/activitySections only: at most this many companies are looked up in the French register for their NAF code per run, 1 to 1000, default 300 (about 3 minutes). Companies past the cap aren't charged and are held for the next run.

## `maxResults` (type: `integer`):

Stop after this many companies in total across all inputs and registers, e.g. 20. Minimum 1; leave empty (the default) for no limit. The run also stops cleanly at the maximum cost per run you set in the run options, whichever comes first. Set it to keep a run small and quick.

## Actor input object example

```json
{
  "mode": "search",
  "searchTerms": [
    "airbus"
  ],
  "identifiers": [],
  "registers": [
    "france",
    "lei"
  ],
  "maxResultsPerSearch": 10,
  "crossLink": true,
  "status": "any",
  "sinceDays": 3,
  "onlyNew": true,
  "maxNafLookups": 300
}
```

# Actor output Schema

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

No description

## `runStats` (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 = {
    "searchTerms": [
        "airbus"
    ],
    "identifiers": [],
    "registers": [
        "france",
        "lei"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("humble-echidna/company-registers").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 = {
    "searchTerms": ["airbus"],
    "identifiers": [],
    "registers": [
        "france",
        "lei",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("humble-echidna/company-registers").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 '{
  "searchTerms": [
    "airbus"
  ],
  "identifiers": [],
  "registers": [
    "france",
    "lei"
  ]
}' |
apify call humble-echidna/company-registers --silent --output-dataset

```

## MCP server setup

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

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/Mh8kvXQzSfYgXXoUD/builds/cgQtYbfXIsuBkki5z/openapi.json
