# France Company & SIRET Search (`cliqtomedia/france-sirene-company-search`) Actor

Look up French companies by SIREN, SIRET or VAT number, or search by name with department, NAF and status filters. Official Sirene data with legal form, NAF, head office, establishments and clear not-found status.

- **URL**: https://apify.com/cliqtomedia/france-sirene-company-search.md
- **Developed by:** [Cliqto Media](https://apify.com/cliqtomedia) (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 $7.20 / 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

France Company & SIRET Search looks up French companies in the official Sirene directory. Add SIREN, SIRET or French VAT numbers, or search by company name with department, postal code, NAF code and status filters. You get one clean row per company, with legal form, NAF activity, size, dates, head office and a clear status: active, ceased or not found.

It is made for KYB checks, CRM cleaning and B2B lead lists. No login and no API key are needed. A typical run of three SIREN numbers finishes in a few seconds and costs about $0.024.

![France Company & SIRET Search: SIREN, SIRET or VAT in, official company record and establishments out, with active, ceased or not found status](https://api.apify.com/v2/key-value-stores/Su0yh0dBwk9pJfDQh/records/README-BANNER-20261010.png)

### Contents

- [What it does](#what-it-does)
- [Quick start](#quick-start)
- [Use cases](#use-cases)
- [Input](#input)
- [Output](#output)
- [Pricing](#pricing)
- [Limits](#limits)
- [API and integrations](#api-and-integrations)
- [Troubleshooting](#troubleshooting)
- [FAQ](#faq)
- [Data source and licence](#data-source-and-licence)
- [Support](#support)

### What it does

The Actor reads the public [Recherche d'entreprises API](https://recherche-entreprises.api.gouv.fr/docs/) of the French administration. This API serves INSEE Sirene and INPI RNE data. The Actor has two modes:

- **Identifier lookup.** Each SIREN, SIRET or VAT number is an exact match. A SIRET also returns that establishment. A wrong or unknown number returns a `not_found` row, so no input is lost.
- **Name search.** A full-text search on company names, brands and addresses, with filters. Results are ranked by the source. Check `siren` and `name` before you use a search result as a verified match.

Optionally, the Actor adds one row per **establishment** (SIRET): address, status, head-office flag, NAF code and trade names.

#### Good fit

- Check that a supplier or customer exists and is still active (KYB, onboarding).
- Fill CRM records with the official name, legal form, NAF code, VAT number and head office.
- Build a list of companies in a department or with a NAF code.
- Find the open and closed establishments of a company.

#### Not a fit

- Directors, shareholders, phone numbers or emails. The Actor does not output them. Note: a sole trader (entrepreneur individuel) is registered under a person's name, and Sirene shows that name as the company name, unless the person hid it.
- Companies that asked to hide their data (non-diffusible). The public API does not serve them.
- A full copy of the Sirene database. Use the official Sirene files for bulk downloads.
- Legal certificates such as a Kbis extract.

### Quick start

1. Open the **Input** tab. The form already has three SIREN numbers: EDF, TotalEnergies and LVMH.
2. Click **Start**.
3. Open the **Companies** view in the Output tab. Check `name`, `administrativeStatus` and `headOfficeAddress`.
4. Replace the numbers with your own list (up to 100). Turn on **Include establishments** if you need SIRET rows.

Expected result: three `complete` company rows in a few seconds.

### Use cases

| Buyer job | Input | Output | Key fields |
| --- | --- | --- | --- |
| Verify a company (KYB) | `identifiers` | company row | `status`, `administrativeStatus`, `closureDate`, `legalFormLabel` |
| Clean CRM records | `identifiers` (SIREN, SIRET or VAT) | company row | `name`, `vatNumber`, `nafCode`, `headOfficeAddress` |
| Map a company's sites | `identifiers` + `includeEstablishments` | establishment rows | `siret`, `address`, `administrativeStatus`, `isHeadOffice` |
| Prospect list by area and activity | `query` + `departments` / `nafCodes` | company rows | `name`, `employeeRangeLabel`, `companyCategory`, `searchRank` |

### Input

Use **either** `identifiers` **or** a search (`query` and filters) in one run. A run with both is rejected with `INVALID_INPUT`.

| Field | Type | Default | Allowed values | What it does |
| --- | --- | --- | --- | --- |
| `identifiers` | array of strings | none (form example: 3 SIREN) | up to 100; SIREN (9 digits), SIRET (14 digits), French VAT (`FR` + 2 characters + SIREN) | Exact lookup. Spaces, dots and dashes are ignored. The same number written twice (or a SIREN and its VAT number) is looked up once. A SIREN and a SIRET of the same company are two lookups. |
| `query` | string | none | 3–200 characters, or shorter with a filter | Fuzzy search on names, brands and addresses. |
| `departments` | array of strings | empty | up to 20; `01`–`95`, `2A`, `2B`, `971`–`976` | Keeps companies with at least one establishment in these departments. |
| `postalCodes` | array of strings | empty | up to 20; 5 digits | Keeps companies with at least one establishment in these postal codes. |
| `nafCodes` | array of strings | empty | up to 20; NAF rev. 2 codes like `62.01Z` or `6201Z` | Activity filter. Unknown codes and NAF 2025 codes are rejected with `INVALID_INPUT`. |
| `companyStatus` | string | `any` | `any`, `active`, `ceased` | Company status filter for search. |
| `maxResults` | integer | 25 | 1–100 | Maximum companies in a search. |
| `includeEstablishments` | boolean | `false` | | Adds establishment (SIRET) rows. |
| `maxEstablishmentsPerCompany` | integer | 20 | 1–100 | Maximum establishment rows per company. |

Filters belong to search mode and cannot be combined with identifiers. With identifiers, the number already selects one company.

#### Input examples

Lookup with establishments:

```json
{
  "identifiers": ["552100554", "55208131701156", "FR03552081317"],
  "includeEstablishments": true,
  "maxEstablishmentsPerCompany": 10
}
```

Search for active bakeries in Paris:

```json
{
  "query": "boulangerie",
  "departments": ["75"],
  "companyStatus": "active",
  "maxResults": 30
}
```

### Output

Each Dataset row has `recordType`: `company` or `establishment`. Use the **Companies** and **Establishments** views, or filter on `recordType` in your export. The key-value store has a `RUN_SUMMARY` record with the run status and counts.

#### Row status

| `status` | Meaning | Charged |
| --- | --- | --- |
| `complete` | The record was found. Fields are as complete as the public data allows. | yes |
| `partial` | The company was found, but a requested SIRET was not found, or extra establishments could not be listed. Read `statusReason`. | yes |
| `not_found` | The number is not in the public index: unknown, hidden (non-diffusible) or not yet indexed. A **ceased company is not `not_found`**: it is `complete` with `administrativeStatus: "ceased"`. | not-found price |
| `error` | Not a valid identifier (`INVALID_IDENTIFIER`) or a source failure (`RATE_LIMITED`, `SOURCE_UNAVAILABLE`, …). | no |

#### Company fields

| Field | Meaning | Example |
| --- | --- | --- |
| `input`, `inputType` | Your value and its type (`siren`, `siret`, `search`, `invalid`) | `"55208131701156"`, `"siret"` |
| `matchedBy` | `siren_exact`, `siret_exact` or `search` | `"siret_exact"` |
| `checksumValid` | INSEE checksum of your number; `false` usually means a typo | `true` |
| `searchRank`, `searchQuery` | Position and query in search mode, else `null` | `1` |
| `siren`, `name`, `legalName`, `acronym` | Company number and names | `"552081317"`, `"ELECTRICITE DE FRANCE (EDF)"` |
| `legalFormCode`, `legalFormLabel` | INSEE legal category | `"5599"`, `"SA à conseil d'administration (s.a.i.)"` |
| `nafCode`, `nafVersion`, `nafLabel` | Main activity, NAF rev. 2 | `"35.11Z"`, `"NAFRev2"`, `"Production d’électricité"` |
| `naf2025Code` | Main activity in the new NAF 2025, kept separate; can be `null` | `"35.11Y"` |
| `nafSectionCode`, `nafSectionLabel` | NAF section | `"D"` |
| `employeeRangeCode`, `employeeRangeLabel`, `employeeRangeYear` | INSEE headcount band and its year | `"53"`, `"10 000 salariés et plus"`, `2024` |
| `companyCategory`, `companyCategoryYear` | `PME`, `ETI` or `GE` | `"GE"` |
| `creationDate`, `closureDate` | Dates in `YYYY-MM-DD` | `"1955-01-01"`, `null` |
| `administrativeStatus`, `administrativeStatusCode` | `active` (`A`) or `ceased` (`C`) | `"active"` |
| `diffusionStatus`, `hiddenFields` | `partial` when some data is hidden by law; hidden fields are `null` and listed | `"partial"`, `["headOffice.adresse"]` |
| `vatNumber` | Intra-EU VAT number as given by the source; `null` if the source has none | `"FR03552081317"` |
| `isIndividualEntrepreneur`, `isAssociation`, `isSocialEconomy` | Source flags | `false` |
| `isEmployer` | Employer flag at company level; the source often leaves it empty, so it is usually `null`. Use the establishment `isEmployer` instead. | `null` |
| `latestFinancialYear`, `revenueEur`, `netIncomeEur` | Latest published accounts, when the company files them | `2024`, `118690000000` |
| `establishmentsTotal`, `establishmentsOpen` | All known establishments and open ones | `9158`, `3551` |
| `establishmentsReturned`, `establishmentsComplete`, `establishmentsScope` | How many establishment rows this run returned, and whether that is the full list | `20`, `false`, `"name_matched_subset"` |
| `headOfficeSiret`, `headOfficeAddress`, `headOfficePostalCode`, `headOfficeCity`, `headOfficeCommuneCode`, `headOfficeDepartment`, `headOfficeRegion`, `headOfficeLatitude`, `headOfficeLongitude`, `headOfficeStatus` | Head office | `"55208131766522"`, `"22-30 22 AVENUE DE WAGRAM 75008 PARIS"` |
| `annuaireUrl` | Public page on annuaire-entreprises.data.gouv.fr | |
| `status`, `statusReason`, `errorCode` | Row result, see above | |
| `source`, `sourceUrl`, `fetchedAt`, `sourceUpdatedAt`, `sourceUpdatedAtInsee`, `sourceUpdatedAtRne` | Provenance and update dates | |

#### Establishment fields

`siret`, `siren`, `companyName`, `isHeadOffice`, `wasHeadOffice`, `administrativeStatus` (`active` or `closed`), `administrativeStatusCode` (`A` or `F`), `creationDate`, `activityStartDate`, `closureDate`, `address`, `postalCode`, `city`, `communeCode`, `department`, `region`, `latitude`, `longitude`, `nafCode`, `nafVersion`, `nafLabel`, `naf2025Code`, `employeeRangeCode`, `employeeRangeLabel`, `employeeRangeYear`, `isEmployer`, `tradeNames`, `commercialName`, `diffusionStatus`, `hiddenFields`, `matchedBy`, `annuaireUrl`, `status`, `statusReason`, `errorCode`, `input`, `source`, `sourceUrl`, `fetchedAt`.

`matchedBy` tells where the row comes from: `siret_exact` (your SIRET), `head_office`, `company_establishments` (listed for your SIREN) or `search_match` (matched your search).

#### Output example

A trimmed company row for a ceased company:

```json
{
  "recordType": "company",
  "status": "complete",
  "input": "552100554",
  "matchedBy": "siren_exact",
  "siren": "552100554",
  "name": "PEUGEOT SA",
  "legalFormLabel": "SA à directoire (s.a.i.)",
  "nafCode": "70.10Z",
  "nafVersion": "NAFRev2",
  "naf2025Code": null,
  "administrativeStatus": "ceased",
  "creationDate": "1955-01-01",
  "closureDate": "2021-01-16",
  "vatNumber": null,
  "establishmentsTotal": 5,
  "establishmentsOpen": 0,
  "headOfficeSiret": "55210055400054",
  "headOfficeCity": "VELIZY-VILLACOUBLAY",
  "headOfficeStatus": "closed",
  "annuaireUrl": "https://annuaire-entreprises.data.gouv.fr/entreprise/552100554",
  "sourceUpdatedAt": "2026-10-08T09:06:03"
}
```

`null` means the source has no value. It never means zero.

#### Run summary

`RUN_SUMMARY.status` is one of `COMPLETE`, `PARTIAL`, `NOT_FOUND` (no identifier was found), `NO_RESULTS` (empty search), `CAPPED` (stopped at a limit), `ERROR`, `INVALID_INPUT` or `CANCELLED`. `counts` shows rows by status and charged rows. `source` names the data licence.

### Pricing

Pay per event. Platform usage is included.

| Event | Price | When |
| --- | ---: | --- |
| Actor start | $0.002 | Once per run (per GB of memory; the default 256 MB counts once) |
| Company record | $0.0072 | Each `complete` or `partial` company row |
| Not-found lookup | $0.001 | Each `not_found` company row |
| Establishment record | $0.0003 | Each `complete` establishment row |

`error` rows are free. An empty search costs only the start.

| Run | Example cost |
| --- | ---: |
| 3 SIREN (form example) | $0.0236 |
| 10 SIREN | $0.074 |
| 100 SIREN | $0.722 |
| 100 SIREN with establishments (1,854 rows in our test) | $1.278 |
| 100 unknown numbers | $0.102 |

Set a maximum cost per run in the run options to cap your spend. The Actor stops before a paid row that does not fit and reports `CAPPED`.

### Limits

- Up to 100 identifiers per run, or up to 100 companies per search.
- Up to 100 establishments per company. The source cannot list more. Check `establishmentsComplete`: in our test of 100 transport companies, 96 had their full list.
- In search mode, establishments are the ones that **matched your search or filters**, not all establishments of the company.
- The Actor sends at most about 3 requests per second. The source allows 7 per second per IP and shares a limit across cloud providers, so a busy moment can give `RATE_LIMITED` rows. Run them again later.
- Internal time budget is 240 seconds. 100 identifiers with establishments took 94 seconds in our test.
- `naf2025Code` is a temporary field of the source. The source says it may be removed after 2027-01-01.

### API and integrations

Start a run with the same JSON input through the Apify API (`POST /v2/acts/cliqtomedia~france-sirene-company-search/runs`), then read the Dataset. Export to CSV, Excel or JSON from the Dataset, or connect the run to other tools with the usual Apify integrations.

Join rows on `siren` (company) and `siret` (establishment). For CSV, use the **Companies** or **Establishments** view.

There is no built-in monitoring mode. To re-check the same list regularly, create an Apify schedule for a saved task and compare `administrativeStatus` or `sourceUpdatedAt` between runs.

#### Use with AI agents (MCP)

AI agents can call this Actor through the Apify MCP server: add `https://mcp.apify.com?tools=cliqtomedia/france-sirene-company-search` to your MCP client (Claude, Cursor, VS Code and others). The MCP server needs your Apify account (OAuth sign-in or an Apify API token); the data source itself needs no key. The agent builds the input from the input schema. The smallest useful input:

```json
{ "identifiers": ["552081317"] }
```

Key output fields for an agent: `status` (`complete`, `not_found`, …), `name`, `administrativeStatus` (`active` or `ceased`), `legalFormLabel`, `nafCode`, `vatNumber`, `headOfficeAddress`. A call with 10 numbers usually finishes in well under 30 seconds and costs about $0.074; up to 100 numbers or 100 search results fit in one run. A large run (100 numbers, around 45 seconds) can outlast the MCP call wait, so the agent may need to poll the run for its result. Search results are fuzzy, so an agent should verify a company by SIREN or SIRET.

### Troubleshooting

| Symptom | Check | Action |
| --- | --- | --- |
| `not_found` for a real company | `checksumValid` | `false` means a typo. If `true`, the company may be non-diffusible or very new. |
| A ceased company | `administrativeStatus`, `closureDate` | This is correct data, not an error. |
| Address is `null` | `diffusionStatus`, `hiddenFields` | The company hides some data by law. |
| `RATE_LIMITED` rows | `RUN_SUMMARY.http.rateLimited` | Run the failed identifiers again later. |
| Fewer establishments than `establishmentsTotal` | `establishmentsComplete`, `maxEstablishmentsPerCompany` | Raise the limit up to 100. Above 100, the source gives a subset. |
| `INVALID_INPUT` | `RUN_SUMMARY.message` | Common causes: identifiers and a search in one run; no valid SIREN/SIRET/VAT in the list; an unknown NAF code; a search query shorter than 3 characters without a filter. |

### FAQ

#### Do I need an API key or a French account?

No. The source is open and free. You only need your Apify account.

#### Is a search result a verified match?

No. Search is fuzzy. For verification, use the SIREN or SIRET. Exact lookups show `matchedBy: "siren_exact"` or `"siret_exact"`.

#### Why are directors not included?

They are personal data. This Actor gives company data only. Sole traders still appear under their registered name.

#### How fresh is the data?

Each run reads the source live. Each row has `fetchedAt` (our read time) and `sourceUpdatedAt` (the source update time of that record).

#### Can I use the data commercially?

The Sirene data is published under the French Licence Ouverte 2.0, which allows commercial reuse with attribution. See below.

### Data source and licence

Data: [API Recherche d'entreprises](https://www.data.gouv.fr/dataservices/api-recherche-dentreprises) (DINUM, annuaire-entreprises.data.gouv.fr), built on [INSEE Sirene](https://www.data.gouv.fr/datasets/base-sirene-des-entreprises-et-de-leurs-etablissements-siren-siret) and INPI RNE data, under the [Licence Ouverte / Etalab 2.0](https://www.etalab.gouv.fr/licence-ouverte-open-licence/). When you reuse the data, name the source and the update date (`sourceUpdatedAt`). This Actor is independent and not endorsed by INSEE, INPI or the French administration.

### Support

Use the **Issues** tab of this Actor. Add the run ID, the mode (identifiers or search) and the `statusReason` or `errorCode` you saw. Do not send API tokens or private data.

# Actor input Schema

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

Exact lookup of up to 100 French company numbers: SIREN (9 digits, e.g. 552081317), SIRET (14 digits, e.g. 55208131766522) or French VAT number (FR + 2 characters + SIREN, e.g. FR03552081317). Spaces, dots and dashes are ignored; duplicates are looked up once. Never a fuzzy name match. Leave empty to run a name search instead.

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

Fuzzy full-text search on company names, brands, acronyms and addresses, e.g. boulangerie or Michelin. 3–200 characters (shorter is allowed with a filter). Cannot be combined with identifiers (the run is rejected with INVALID_INPUT). Results are ranked by the source: check siren and name before treating one as a verified match.

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

Search filter, not combinable with identifiers. Up to 20 French department codes: 01–95, 2A, 2B, 971–976, e.g. 75 or 69. Keeps companies with at least one establishment there. Default: empty (all of France).

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

Search filter, not combinable with identifiers. Up to 20 five-digit postal codes, e.g. 75008. Keeps companies with at least one establishment there. Default: empty.

## `nafCodes` (type: `array`):

Search filter, not combinable with identifiers. Up to 20 NAF rev. 2 activity codes, with or without the dot, e.g. 62.01Z or 6201Z. Unknown codes and NAF 2025 codes are rejected with INVALID_INPUT. Default: empty.

## `companyStatus` (type: `string`):

Search filter on company status: any (default), active or ceased. Active or ceased cannot be combined with identifiers.

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

Search mode only. Maximum companies returned, 1–100. Default 25. Each company row is charged.

## `includeEstablishments` (type: `boolean`):

Add one row per establishment (SIRET: address, status, head-office flag, NAF, trade names). For identifiers: the head office plus establishments listed by the source; for a search: the establishments that matched the search. Default false. Each found establishment row is charged.

## `maxEstablishmentsPerCompany` (type: `integer`):

Maximum establishment rows per company, 1–100. Default 20. The company row shows establishmentsTotal and establishmentsComplete so you know when the list is a subset. Used only with includeEstablishments.

## Actor input object example

```json
{
  "identifiers": [
    "552081317",
    "542051180",
    "775670417"
  ],
  "companyStatus": "any",
  "maxResults": 25,
  "includeEstablishments": false,
  "maxEstablishmentsPerCompany": 20
}
```

# Actor output Schema

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

Company rows (and establishment rows) as a table.

## `establishments` (type: `string`):

Establishment (SIRET) rows view.

## `runSummary` (type: `string`):

Status, counts, source attribution and request statistics.

# 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 = {
    "identifiers": [
        "552081317",
        "542051180",
        "775670417"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("cliqtomedia/france-sirene-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 = { "identifiers": [
        "552081317",
        "542051180",
        "775670417",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("cliqtomedia/france-sirene-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 '{
  "identifiers": [
    "552081317",
    "542051180",
    "775670417"
  ]
}' |
apify call cliqtomedia/france-sirene-company-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cliqtomedia/france-sirene-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/vqsEkYd8oWrMe2yzG/builds/nez0GmB0z8cFyjM5o/openapi.json
