# French Company Search: SIRENE, SIREN, SIRET, NAF, VAT (`vantum/french-company-search`) Actor

Search and export French companies from the official SIRENE / Annuaire des Entreprises open API: SIREN, SIRET, NAF, address, GPS, headcount, revenue, VAT, labels. Filters by industry, department, size. GDPR-friendly, no proxies.

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

## Pricing

$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

### What does French Company Search do?

**French Company Search** exports French companies and establishments from the **official SIRENE register** (INSEE, via the government's *API Recherche d'entreprises*) into clean, English-labelled rows: **SIREN, SIRET, VAT number, NAF/APE activity, headcount, revenue, net income, address with GPS, certifications** and more.

Pick an industry and a place, for example *software companies in Lyon* or *bakeries within 2 km of a point*, or paste a list of SIREN/SIRET numbers. You get a spreadsheet-ready dataset in minutes. You need no API key, no proxy and no login, and you **pay only for the rows you get**.

- 🇫🇷 **Every company and establishment in SIRENE**, active or closed, refreshed daily from INSEE SIRENE and INPI RNE
- 🧭 **Exports past the 10,000-result limit** of the source API by splitting big searches automatically (department → sector → headcount → NAF code)
- 🛡️ **GDPR-friendly by design**: it never outputs officers who are natural persons, and sole traders (*entrepreneurs individuels*) are excluded by default
- 💶 **Free dry run** that counts matches and estimates the cost before you spend anything

### Why use French Company Search?

- **B2B lead lists**: every active IT services firm (NAF 62.02A) with 20–99 employees in Île-de-France, with revenue.
- **Market sizing and TAM**: how many restaurants opened in Bordeaux this year, and how many are SMEs.
- **CRM enrichment and KYB**: turn a column of SIREN/SIRET numbers into VAT numbers, legal form, status and head-office address.
- **Supplier and partner sourcing**: RGE-certified builders, Qualiopi training organisations, organic (*bio*) producers, ESS companies.
- **Local prospecting**: every establishment within a radius of a point, for field sales or retail planning.
- **A cheap Pappers or Societe.com alternative** for bulk exports, built on the same open data at a fraction of the cost.

### What data can I extract from the French company register?

| Group | Fields |
|---|---|
| Identity | `siren`, `siret`, `name`, `legalName`, `acronym`, `tradeNames`, `vatNumber` (intra-EU VAT) |
| Status | `isActive`, `createdOn`, `closedOn`, `isHeadOffice`, `dataUpdatedAt` |
| Activity | `nafCode` (APE), `nafLabel`, `nafSection`, `nafSectionLabel`, `nafCode2025` (new NAF 2025) |
| Size | `companyCategory` (PME / ETI / GE), `employeeRange`, `employeesMin`, `employeesMax`, `establishmentsCount` |
| Finances | `revenueEur` (chiffre d'affaires), `netIncomeEur` (résultat net), `financialYear` (when published) |
| Location | `address`, `postalCode`, `city`, `cityCode` (INSEE), `department`, `region`, `latitude`, `longitude` |
| Labels | `labels` (RGE, Qualiopi, Bio, ESS, mission-driven company, FINESS, …), `collectiveAgreements` (IDCC) |
| Governance | `corporateOfficers` (only officers that are **companies**: name, SIREN, role), `naturalPersonOfficersCount` |
| Source | `officialRegistryUrl` (annuaire-entreprises.data.gouv.fr page), `scrapedAt` |

### How to export French companies (step by step)

1. Click **Try for free** and open the **Input** tab.
2. Leave **Mode** on *Search the register*.
3. Choose one or more **NAF/APE codes** (e.g. `62.01Z`) or a broad **sector**, then a **department**, **region**, **postal code** or **city**.
4. Optionally narrow by **headcount**, **company size**, **legal form**, **revenue**, **certifications** or **creation date**.
5. Set **Max records**, or tick **Dry run** first to see how many companies match and what a full export would cost.
6. Click **Start**. Download the results as **JSON, CSV, Excel, XML or HTML**, or pull them from the API.

To **enrich a list**, switch **Mode** to *Look up SIREN / SIRET numbers* and paste your IDs (spaces and dots are fine). To **search around a point**, choose *Nearby*, then enter latitude, longitude and a radius of up to 50 km.

### How much does it cost to export French company data?

You pay **per record saved**, and nothing else: no start fee, no subscription, no proxy costs.

| | Price |
|---|---|
| 1 company or establishment row | **$0.002** ($2 per 1,000) |
| 10,000 companies | about **$20** |
| Dry run (count + cost estimate) | **free** |
| Lookups for unknown or invalid IDs | **free** (only found companies are charged) |

Apify's free plan includes monthly credit, which is enough for a few thousand rows to test with. Set **Maximum cost per run** in the run options and the Actor stops cleanly at your budget.

### Input

All filters are optional, but a search needs at least one filter or a keyword, so the Actor never downloads the whole register by accident. Example: active software companies in the Rhône department.

```json
{
    "mode": "search",
    "nafCodes": ["62.01Z"],
    "departments": ["69"],
    "employeeRanges": ["11", "12", "21"],
    "maxResults": 500
}
```

Lookup example:

```json
{
    "mode": "lookup",
    "ids": ["552 032 534", "40305211102020"],
    "outputLevel": "companies"
}
```

Main options:

- **Output level**: `companies` gives one row per company (head office). `establishments` gives one row per matching location (SIRET), which suits retail chains, restaurants and branches.
- **Location filters apply to the head office** (on by default): a search for *companies in Lyon* returns companies headquartered there, not national groups that merely have a branch there.
- **Establishments must match the activity** (on by default): with establishment rows, only locations whose *own* NAF code matches are kept. A bakery chain's head office (coded as a holding) is left out.
- **Active companies only** (on by default), **Include sole traders** (off by default, see GDPR below), **Created after / before**.
- **Auto-split large searches** (on by default) exports beyond the source API's 10,000-results-per-query limit.

### Output

Each row looks like this (real output, shortened):

```json
{
    "recordType": "company",
    "siren": "452487416",
    "siret": "45248741600060",
    "name": "SYNOLIA",
    "isActive": true,
    "createdOn": "2004-03-01",
    "legalForm": "SAS, société par actions simplifiée",
    "nafCode": "62.01Z",
    "nafLabel": "Programmation informatique",
    "companyCategory": "PME",
    "employeeRange": "50 à 99 salariés",
    "employeesMin": 50,
    "employeesMax": 99,
    "address": "59 RUE DE L'ABONDANCE 69003 LYON",
    "postalCode": "69003",
    "city": "LYON",
    "department": "Rhône",
    "region": "Auvergne-Rhône-Alpes",
    "latitude": 45.754120383,
    "longitude": 4.8559396747,
    "vatNumber": "FR28452487416",
    "revenueEur": 12095056,
    "netIncomeEur": 317717,
    "financialYear": "2024",
    "labels": ["Egapro index published"],
    "corporateOfficers": [{ "name": "SEVENTY SIX", "siren": "911885275", "role": "Président de SAS" }],
    "naturalPersonOfficersCount": 1,
    "officialRegistryUrl": "https://annuaire-entreprises.data.gouv.fr/entreprise/452487416"
}
```

An establishment row (from `outputLevel: "establishments"`) has the same fields, but `siret`, address, NAF code, headcount and dates describe **that location**:

```json
{
    "recordType": "establishment",
    "siren": "899507552",
    "siret": "89950755200045",
    "name": "AB COPAINS",
    "tradeNames": ["COPAINS"],
    "isHeadOffice": false,
    "nafCode": "56.10C",
    "nafLabel": "Restauration de type rapide",
    "employeeRange": "3 à 5 salariés",
    "address": "29 RUE DES BLANCS MANTEAUX 75004 PARIS",
    "department": "Paris"
}
```

Each run also writes a **`RUN_SUMMARY`** record to the key-value store. It holds the status, the number of rows saved, rows skipped and why, the IDs not found, the dry-run estimate and the exact filters sent to the API. The Console offers three table views: **Overview**, **Locations** and **Finance**.

### Tips for large exports

- **Start with a dry run.** It is free and tells you how many rows a full export has.
- **Use NAF codes rather than keywords** for complete lists. The keyword search ranks by relevance; NAF and location filters are exhaustive.
- **Very large markets** (a whole sector nationwide) are split automatically. If a slice still exceeds 10,000 results, the run summary lists it so you can add a postal-code filter.
- **Revenue is only available** for companies that publish their accounts, often only about half of the rows in a typical search.
- **Speed:** up to about 75 rows per second (the source API is rate-limited), so 100,000 companies take roughly 25–40 minutes. Raise the run timeout for very large exports; an interrupted run resumes where it stopped.
- **Creation-date filters run after download**, because the source API cannot filter by date. They are free (you pay only for rows that pass), but they are slow on broad searches. Combine them with a department and NAF code. Example: a weekly scheduled run of *restaurants in Gironde created after last Monday* makes a cheap **new-business feed**.

### FAQ

#### Is it legal to scrape the French company register?

Yes. This Actor does not scrape websites. It calls the **official public API Recherche d'entreprises** run by DINUM (French government), which publishes SIRENE (INSEE) and RNE (INPI) data under the **Licence Ouverte / Etalab 2.0**, an open licence that allows commercial reuse with attribution. Every run records the source in its summary; keep that attribution when you republish the data.

#### How is personal data handled (GDPR)?

Collecting personal data is avoided by design: **officers who are natural persons are never output** (only their count), there is **no search by person name**, and **sole traders are excluded by default** because their company name is usually the owner's name. If you enable *Include sole traders*, you become responsible for having a lawful basis under the GDPR and for honouring people's right to object to direct marketing.

#### How is this different from Pappers, Societe.com or Infogreffe?

Those sites show one company at a time, or sell bulk exports through subscriptions. This Actor gives you the same core register data in bulk, with filters, for about $2 per 1,000 companies. It does not include paid documents such as full balance sheets, shareholder registers or court filings.

#### How fresh is the data?

The government API is updated daily from INSEE and INPI. Each row includes `dataUpdatedAt`.

#### Why are some companies or fields missing?

Some companies requested **non-diffusion** (*statut de diffusion partielle*), so INSEE hides parts of their data. Financial data appears only when accounts were published. Headcount ranges come from INSEE and can lag by a year.

#### Can I use it through the API, with Make, Zapier, n8n or an AI agent?

Yes. Like every Apify Actor, it can be run through the Apify API, its JS and Python clients, or integrations with Make, Zapier, n8n and Google Sheets, or used as a tool by AI agents via the Apify MCP server.

#### I found a bug or need a feature

Open an issue in the **Issues** tab with your run ID and what you expected.

*Disclaimer: this Actor is not affiliated with INSEE, INPI, DINUM or the French government. Data comes from the API Recherche d'entreprises (recherche-entreprises.api.gouv.fr) under the Licence Ouverte / Etalab 2.0. NAF and legal-form labels are adapted from the open-source search-api project (MIT, © DINUM).*

# Actor input Schema

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

**Search** builds a list of French companies from filters. **Lookup** enriches SIREN/SIRET numbers you already have. **Nearby** finds companies within a radius (≤ 50 km) of a GPS point.

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

Free-text search on company name, trade name and address, e.g. `boulangerie`, `logiciel`, `Lyon`. Leave empty to rely on filters only. Person-name search is intentionally not offered.

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

One or more INSEE NAF rév. 2 codes, e.g. `62.01Z` (software development), `56.10A` (restaurants), `10.71C` (bakeries), `43.22A` (plumbing). Formats `6201Z` and `62.01z` are accepted. [Full list](https://www.insee.fr/fr/information/2406147).

## `nafSections` (type: `array`):

Broad sectors, if you don't need precise NAF codes. Combined with NAF codes using AND.

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

French departments (where at least one establishment is located). Leave empty for all of France.

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

French regions. Leave empty for all of France.

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

5-digit postal codes, e.g. `75011`, `69002`.

## `cityCodes` (type: `array`):

INSEE commune codes (not postal codes), e.g. `75056` (Paris), `69123` (Lyon), `13055` (Marseille).

## `headOfficeLocationOnly` (type: `boolean`):

Company rows only. On: a company is kept only if its **head office** is in the departments, regions, postal codes or cities you chose (what most people expect from 'companies in Lyon'). Off: also keep companies headquartered elsewhere that merely have a branch there.

## `latitude` (type: `number`):

Latitude of the centre point, e.g. `48.8566` for Paris. Used only in Nearby mode.

## `longitude` (type: `number`):

Longitude of the centre point, e.g. `2.3522` for Paris. Used only in Nearby mode.

## `radiusKm` (type: `number`):

Search radius around the point, up to 50 km.

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

INSEE headcount bands of the legal unit (latest declared year).

## `companyCategories` (type: `array`):

INSEE company category.

## `legalFormCodes` (type: `array`):

4-digit INSEE legal-form codes, e.g. `5710` (SAS), `5499` (SARL), `5720` (SASU), `5599` (SA), `9220` (association). [Full list](https://www.insee.fr/fr/information/2028129).

## `minRevenueEur` (type: `integer`):

Latest published revenue (chiffre d'affaires) at least this amount. Only companies that publish accounts can match.

## `maxRevenueEur` (type: `integer`):

Latest published revenue at most this amount.

## `minNetIncomeEur` (type: `integer`):

Latest published net income (résultat net) at least this amount. Can be negative.

## `maxNetIncomeEur` (type: `integer`):

Latest published net income at most this amount.

## `certifications` (type: `array`):

Keep only companies holding ALL selected labels, e.g. RGE installers or Qualiopi training providers.

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

Skip companies that have ceased trading (état administratif = C).

## `createdAfter` (type: `string`):

Only companies (or establishments) created on/after this date (YYYY-MM-DD). Great for new-business lead lists. Applied after download: you pay only for matching records.

## `createdBefore` (type: `string`):

Only companies (or establishments) created on/before this date (YYYY-MM-DD).

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

Off by default for privacy: a sole trader's company name is usually a private person's name. Turn on only if you have a legitimate interest under GDPR.

## `ids` (type: `array`):

9-digit SIREN or 14-digit SIRET numbers. Spaces and dots are ignored; invalid checksums are reported, never charged. Each row keeps your original number in `inputId`.

## `outputLevel` (type: `string`):

**Company**: one row per legal entity with its head office. **Establishment**: one row per matching physical location — ideal for field sales and local marketing (e.g. every bakery shop, not just the owning company).

## `onlyOpenEstablishments` (type: `boolean`):

In establishment mode, skip closed locations.

## `matchEstablishmentActivity` (type: `boolean`):

Establishment rows only. The register filters NAF codes at company level, so a bakery company can also have an office or a café. On: keep only locations whose **own** NAF code matches the codes or sectors you chose. Off: keep every matching location of those companies.

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

Stop after this many records (you pay per record). `0` = no limit. Tip: use a dry run first to see the market size.

## `dryRun` (type: `boolean`):

Only count matching companies and estimate the cost. Nothing is saved to the dataset and nothing is charged. The result is in the `RUN_SUMMARY` record.

## `autoSplit` (type: `boolean`):

The official API returns at most 10,000 results per query. When on, large searches are split automatically by department, sector and size so you can export whole markets in one run.

## `sortBySize` (type: `boolean`):

Sort by number of establishments (largest networks first) instead of relevance.

## `maxRequestsPerSecond` (type: `integer`):

Politeness limit for the public government API (it allows 7/s per IP). Lower it if you see many retries.

## Actor input object example

```json
{
  "mode": "search",
  "nafCodes": [
    "62.01Z"
  ],
  "departments": [
    "69"
  ],
  "headOfficeLocationOnly": true,
  "radiusKm": 5,
  "activeOnly": true,
  "includeSoleTraders": false,
  "ids": [],
  "outputLevel": "companies",
  "onlyOpenEstablishments": true,
  "matchEstablishmentActivity": true,
  "maxResults": 100,
  "dryRun": false,
  "autoSplit": true,
  "sortBySize": false,
  "maxRequestsPerSecond": 3
}
```

# Actor output Schema

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

All records as a table (Overview view).

## `allFields` (type: `string`):

No description

## `summary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mode": "search",
    "query": "",
    "nafCodes": [
        "62.01Z"
    ],
    "departments": [
        "69"
    ],
    "ids": [],
    "maxResults": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("vantum/french-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 = {
    "mode": "search",
    "query": "",
    "nafCodes": ["62.01Z"],
    "departments": ["69"],
    "ids": [],
    "maxResults": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("vantum/french-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 '{
  "mode": "search",
  "query": "",
  "nafCodes": [
    "62.01Z"
  ],
  "departments": [
    "69"
  ],
  "ids": [],
  "maxResults": 100
}' |
apify call vantum/french-company-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,vantum/french-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/a9NsU7JXZoGeGfvif/builds/m2oxO2Yx4MUTiq4zf/openapi.json
