# SIREN/SIRET Lookup & French Company Enrichment (`atesen-software/french-company-enrichment-sirene`) Actor

Paste SIREN, SIRET, VAT numbers or company names and get CRM-ready French company data from the official SIRENE open data: legal name, VAT, NAF (incl. NAF 2025), headcount, address, finances. Pay only for companies found.

- **URL**: https://apify.com/atesen-software/french-company-enrichment-sirene.md
- **Developed by:** [Atesen Software](https://apify.com/atesen-software) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## SIREN/SIRET Lookup & French Company Enrichment

Turn a column of **SIREN, SIRET or French VAT numbers — or plain company names** — into a clean, CRM-ready table of French company data from the official **SIRENE** open data: legal name, VAT number, NAF/APE code (including the new **NAF 2025**), legal form, headcount range, head-office or establishment address with GPS coordinates, status, latest revenue and net income, labels (RGE, Qualiopi, ESS…) and, if you want, directors.

**You only pay for rows that come back with company data.** Typos, duplicates, unknown numbers and uncertain name matches are free, and a free preview mode checks your whole list before you spend anything (only Apify's tiny per-run start fee applies).

### What can this Actor do?

- 🔢 **Bulk SIREN / SIRET / VAT lookup** — paste thousands of identifiers at once; spaces, dots and dashes are ignored.
- ✅ **Check-digit validation** — every SIREN and SIRET is checked (Luhn, including the special La Poste rule) and numeric VAT keys are verified *before* any lookup, so typos are reported, not charged.
- 🔎 **Company name → SIREN matching** — "Boulangeries Paul | 75004" finds the right company *and* the local establishment, with a **match confidence score**, an **ambiguity flag** and the other candidates listed.
- 🏷️ **NAF rév. 2 and NAF 2025 side by side** — on **1 January 2027** NAF 2025 becomes the official APE nomenclature; both codes and labels are returned so your segments keep working through the switch.
- 🧾 **VAT number** for every company (official DGFiP value when available, otherwise computed and labelled as such).
- 🧹 **De-duplication** — the same identifier entered twice (e.g. a SIREN and that company's VAT number, or the same name + location) is looked up and charged once.
- 📊 **One flat row per input line, in your order** — exports straight to CSV, Excel, Google Sheets or your CRM.
- 🛡️ **Privacy by default** — directors are opt-in; birth dates and nationalities are never returned; companies that opted out of public diffusion stay masked.

### Why use it instead of calling the API yourself?

The French government publishes this data for free, but using it in bulk is fiddly: the API is throttled (HTTP 429), identifiers must be cleaned and validated, company names need fuzzy matching, and the output is deeply nested. This Actor handles all of that with **no code, no API key and no server**, and you can run it from the Apify Console, on a schedule, via the Apify API, or from Apify's integrations (Make, Zapier, n8n and others).

### How to use it

1. Paste your **SIREN / SIRET / VAT numbers** into the first field (use **Bulk edit** to paste a whole spreadsheet column), and/or **company names** into the second field.
2. Optionally add a location to a name after a vertical bar: a postal code (`Michelin | 63000`) or a department (`Decathlon | 59`).
3. (Optional) Tick **Free preview** to validate and de-duplicate the list without any lookup or charge.
4. Click **Start**. Download the results as CSV, Excel or JSON, or use the **All fields (CRM export)** view.

#### Input example

```json
{
    "identifiers": ["552032534", "356 000 000 24221", "FR27552032534", "55203253400646"],
    "companyNames": ["Boulangeries Paul | 75004", "Decathlon | 59"],
    "minConfidence": 60,
    "includeFinances": true,
    "includeDirectors": false
}
```

### Output

One row per input line, always in the same order and with the same columns. Shortened example:

```json
{
    "rowNumber": 1,
    "input": "552032534",
    "inputType": "siren",
    "status": "found",
    "siren": "552032534",
    "siret": "55203253400703",
    "isHeadOffice": true,
    "name": "DANONE",
    "vatNumber": "FR27552032534",
    "vatNumberSource": "api",
    "companyStatus": "active",
    "legalForm": "SA à conseil d'administration (s.a.i.)",
    "nafCode": "70.10Z",
    "nafLabel": "Activités des sièges sociaux",
    "nafCode2025": "70.10Y",
    "employeeRange": "1 000 à 1 999 salariés",
    "companyCategory": "GE",
    "address": "59-61 RUE LA FAYETTE 75009 PARIS",
    "postalCode": "75009",
    "city": "PARIS",
    "department": "Paris",
    "region": "Île-de-France",
    "latitude": 48.8763,
    "longitude": 2.3435,
    "financialYear": 2025,
    "revenue": 27376000000,
    "netIncome": 2100000000,
    "annuaireUrl": "https://annuaire-entreprises.data.gouv.fr/entreprise/552032534"
}
```

#### How complete is the data?

Measured on 450 real companies (software/IT firms in the Rhône department, October 2026):

| Field | Filled |
|---|---|
| Name, VAT number, NAF + NAF 2025 code and label, legal form, headcount range, creation date | 100% |
| Address, department, region | 98% |
| GPS coordinates | 96% |
| Company size category (PME/ETI/GE) | 77% |
| Revenue / net income | 42% — only companies with public accounts |

VAT numbers came from the official DGFiP list for 71% of companies and were computed from the SIREN for the rest (`vatNumberSource` tells you which).

#### Row statuses

| Status | Meaning | Charged? |
|---|---|---|
| `found` | SIREN / SIRET / VAT found | Yes |
| `matched` | Company name matched at or above your minimum confidence | Yes |
| `low_confidence` | Best name match is below your minimum confidence — candidate SIRENs are listed in `matchAlternatives` | No |
| `not_found` | Valid identifier or name, but nothing in the public data | No |
| `invalid` | Wrong check digit, wrong length or wrong VAT key — `statusMessage` says why | No |
| `duplicate` | Same company as an earlier row | No |
| `error` | The government API kept failing for this row (re-run it later), or rejected the query (fix the input) — `statusMessage` says which | No |
| `valid` | Free preview mode only | No |

A run summary (counts, duration, API statistics and any failed rows) is saved as `OUTPUT` in the run's key-value store.

### Pricing

**$2.00 per 1,000 enriched rows** (pay per event: one event per `found` or `matched` row), plus Apify's small standard run-start fee. Higher Apify plans may get a lower per-row price — the exact price for your plan is always shown on this page. Everything else — invalid, duplicate, not-found, low-confidence and failed rows, and the free preview — costs nothing beyond the run-start fee. Note: two *different* names that turn out to be the same company are two separate matches and are both charged.

Examples: 500 found companies ≈ $1.00 · 10,000 found companies ≈ $20.00.

You stay in control: set a **maximum cost per run** in the run options and the Actor stops cleanly when it is reached, telling you how many rows are left.

### Speed — please read

The government API is free and shared by everyone, so it is rate-limited: officially up to 7 requests per second per IP, but in practice it throttles much harder (HTTP 429 with a `Retry-After` delay), especially under sustained use. The Actor follows those delays automatically and never hammers the service — and it deliberately does **not** rotate IP addresses to get around the limit. Each row needs one API call.

Measured on Apify's cloud (October 2026): **about 35 rows per minute — 200 rows in under 6 minutes, 1,000 rows in roughly 30 minutes**. When the API is busy it can drop to 10–30 rows per minute (we measured that from a home connection). Small lists (under ~50 rows) finish in a minute or two. You don't need to keep the page open: rows appear in the dataset as they are processed, the status line shows progress and how often the API is throttling, and compute cost stays tiny because the Actor mostly waits.

### Tips for name matching

- Use the **legal name** when you have it ("Manufacture Française des Pneumatiques Michelin" matches with confidence 1.0; "Michelin" alone is ambiguous between dozens of group companies and is flagged).
- Add a **postal code or department** — it narrows the search and returns the local establishment's SIRET and address.
- Check `matchAmbiguous` and `matchAlternatives` before importing name matches into a CRM. Raise **Minimum match confidence** to be stricter.

### Data source, freshness and licence

Data comes from the **API Recherche d'entreprises**, run by the French interministerial digital agency (DINUM) and also used by annuaire-entreprises.data.gouv.fr. It aggregates INSEE's SIRENE register (updated daily), the national business register RNE (INPI) for directors, DGFiP for VAT numbers, and published annual accounts where available. The data is published under the **Licence Ouverte / Open Licence 2.0**, which allows commercial reuse with attribution — please keep the source mention ("Source: INSEE Sirene / API Recherche d'entreprises, DINUM") when you republish it.

This Actor is an independent tool and is **not affiliated with or endorsed by INSEE, INPI or DINUM**.

### Privacy and GDPR

- The Actor sends only the identifiers and names you provide to the government API; results are stored in **your** Apify run storage. The developer does not receive or keep your data.
- **Sole traders** (entrepreneurs individuels) are natural persons: their name and business address are personal data even with directors switched off. Process them under GDPR like any B2B contact data.
- **Directors are personal data** and are **off by default**. Turn them on only if you have a lawful basis (e.g. B2B prospecting under legitimate interest, with the information and opt-out duties that come with it). Birth dates and nationalities are never output.
- Companies (mostly sole traders) that opted out of public diffusion are returned with their protected fields empty and `partiallyDiffusible: true`, as required by the data publishers.

### Limitations

- Only French companies registered in SIRENE are covered.
- Name matching looks at the top 5 search candidates; very generic names may need a location or a fuller name.
- Financial figures exist only for companies whose accounts are public — many small companies have none.
- One row per input: the Actor does not list all establishments of a company.
- Throughput depends on the government API (see *Speed*).

### FAQ

**Do I need an API key?** No.

**Can I run it on a schedule or from my own code?** Yes — use Apify schedules, the Apify API, or the Make / Zapier / n8n integrations available on Apify.

**What is NAF 2025?** INSEE's new activity nomenclature. From 1 January 2027 it replaces NAF rév. 2 for the APE codes of active companies. This Actor already returns both, so you can map your segments now.

**Why is a valid SIREN "not\_found"?** It may belong to a company that opted out of public diffusion, or it was deleted from the register. Check it on annuaire-entreprises.data.gouv.fr.

**What happens if the run is interrupted?** Progress is saved after every row. If the Apify platform migrates the run to another server, it resumes where it stopped and finished rows are not charged again. If you abort a run, you can resurrect it to continue.

### Support

Questions, bugs or feature requests: open an issue on the **Issues** tab or email **support@atesensoftware.com** — we usually reply within one business day.

Built by **Atesen Software**.

# Changelog

This Actor's version history is a separate document: https://apify.com/atesen-software/french-company-enrichment-sirene/changelog.md

# Actor input Schema

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

One per line. 9-digit SIREN, 14-digit SIRET or French VAT number (FR + 11 characters). Spaces, dots and dashes are ignored. Use 'Bulk edit' to paste a whole column from Excel or Google Sheets.

## `companyNames` (type: `array`):

One company name per line. Optionally add a postal code or department after a vertical bar to narrow the search, e.g. 'Decathlon | 59' or 'Boulangeries Paul | 59700'. Each row gets a match confidence score.

## `minConfidence` (type: `integer`):

Name matches below this score are returned as 'low\_confidence' with the candidate SIRENs listed, and are not charged. Lower it to accept fuzzier matches.

## `onlyActiveCompanies` (type: `boolean`):

When matching names, ignore companies that have ceased trading.

## `includeFinances` (type: `boolean`):

Latest published revenue (chiffre d'affaires) and net income, when the company filed public accounts. Many small companies have none.

## `includeDirectors` (type: `boolean`):

Adds company officers from the national business register (RNE). This is personal data: only enable it if you have a lawful basis under GDPR. Birth dates and nationalities are never output.

## `validateOnly` (type: `boolean`):

Checks every identifier (check digits, VAT key), removes duplicates and shows what would be looked up — without calling the registry and without any charge.

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

Upper bound for calls to the government API (its official limit is 7/s per IP, and it throttles harder under load). The Actor slows down automatically when throttled; you rarely need to change this.

## Actor input object example

```json
{
  "identifiers": [
    "552032534",
    "356 000 000 24221",
    "FR27552032534"
  ],
  "companyNames": [
    "Decathlon | 59"
  ],
  "minConfidence": 60,
  "onlyActiveCompanies": false,
  "includeFinances": true,
  "includeDirectors": false,
  "validateOnly": false,
  "maxRequestsPerSecond": 2
}
```

# Actor output Schema

## `results` (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 = {
    "identifiers": [
        "552032534",
        "356 000 000 24221",
        "FR27552032534"
    ],
    "companyNames": [
        "Decathlon | 59"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("atesen-software/french-company-enrichment-sirene").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": [
        "552032534",
        "356 000 000 24221",
        "FR27552032534",
    ],
    "companyNames": ["Decathlon | 59"],
}

# Run the Actor and wait for it to finish
run = client.actor("atesen-software/french-company-enrichment-sirene").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": [
    "552032534",
    "356 000 000 24221",
    "FR27552032534"
  ],
  "companyNames": [
    "Decathlon | 59"
  ]
}' |
apify call atesen-software/french-company-enrichment-sirene --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,atesen-software/french-company-enrichment-sirene"
        }
    }
}
```

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/BExiBkk3fybp1rJmd/builds/HEhHd67QJedysO2OJ/openapi.json
