# Sirene French Company Scraper — SIREN, NAF, Directors (`scrapersdelight/sirene-company-scraper`) Actor

Scrape the official French Sirene company register: SIREN, SIRET, NAF activity code, head-office address with GPS, headcount band, VAT number, creation date and registered directors. Filter by activity, department, postcode or creation date. No login, no API key.

- **URL**: https://apify.com/scrapersdelight/sirene-company-scraper.md
- **Developed by:** [Scrapers Delight](https://apify.com/scrapersdelight) (community)
- **Categories:** Lead generation, Business, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$4.00 / 1,000 per company returneds

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## 🇫🇷 Sirene French Company Scraper — SIREN, NAF, address, directors

Turn the **official French company register** into a clean B2B list. Pick an activity code, a
department or a creation-date window and get one row per company: **SIREN, SIRET, NAF/APE code,
head-office address with GPS, headcount band, VAT number, creation date** and the **registered
directors** from the RNE.

Straight from the French government's own open API — **no login, no API key, no scraping wall.**

### What does this actor do?

It searches the Sirene base (every registered French company) and returns flat, joinable rows:

- 🏢 **`siren` / `siret`** — the 9-digit company id and the 14-digit head-office id
- 🏷️ **`companyName` / `legalName` / `tradeName`** — full name, legal name, trading name
- 🧾 **`vatNumber`** — the intra-community VAT number (`FR…`)
- 🏭 **`nafCode` / `nafSection`** — activity code, e.g. `10.71C` bakery, `62.01Z` software
- 👥 **`employeeBand`** — the INSEE headcount code decoded to a readable range (`10-19`, `250-499`).
  Roughly half of all companies have no band on file and come back as `Non renseigné`
- 📍 **`addressFull`, `postalCode`, `city`, `department`, `region`, `latitude`, `longitude`**
- 📅 **`dateCreated`** — the registration date, so you can build a **new-business feed**
- 🚪 **`dateClosed` + `isActive`** — or flip it around and build a **business-closures feed**
- 👤 **`directors[]` / `primaryDirector`** — registered officers with role and birth year
- 🗂️ **`establishments[]`** — optionally the establishments that MATCH your search, each with its
  own SIRET + GPS. The API returns at most 10 per company and only the sites matching your filters,
  so this is not a full site list for multi-branch companies (use `establishmentCount` for the true
  total)
- 🔗 **`profileUrl`** — the public annuaire-entreprises page

### Example input

```json
{
  "nafCodes": ["56.10C"],
  "departments": ["75", "13"],
  "createdAfter": "2026-01-01",
  "employersOnly": true,
  "maxItems": 500
}
```

Every restaurant with a site in Paris or Bouches-du-Rhône registered since January that has
employees. Note: the department filter matches any establishment, but each row carries the
company's HEAD-OFFICE address — so a chain with a Paris branch and a head office elsewhere is
returned with its out-of-region address (about 13% of rows on a single-department search).

### Who is this for?

French SDR and growth teams building territory lists, expert-comptables and insurers prospecting
newly registered companies, banks and merchant-services vendors, KYB and credit teams needing
firmographics, and researchers who want a SIREN-keyed dataset they can join to other open data.

### Field coverage — measured, not promised

Measured on the actor's own full run of one search — every bakery registered in Paris, 2,334
companies (run `LsvSyg4tkZgnDgu2m`). Two address rows below are quoted from the 200-company default
sample of that same search (run `AK5gC3NfusdINsLs3`) and are marked as such. We do not headline the
200-row sample: the API returns its biggest companies first, so a first-page sample reads 10-20
points high.

| Field | Fill | Note |
|---|---|---|
| `siren`, `siret`, `companyName`, `addressFull`, `nafCode`, `dateCreated`, `isActive`, `legalForm`, `profileUrl` | **100%** | the core row |
| `postalCode`, `city`, `department`, `region` | **99.5%** | on the 200-company sample |
| `latitude`, `longitude` | **99.0%** | government geocoding misses a few addresses (200-company sample; 99.8% on the 2,334-company run) |
| `isEmployer` | **99%** | |
| `employeeBand` | **100% present / 59% a real range** | INSEE returns `Non renseigné` for the rest (200-company sample; 48% a real range on the 2,334-company run) |
| `directors`, `legalName` | **86%** | |
| `primaryDirector` | **79%** | |
| `companySize` | **73%** | INSEE has not assigned a catégorie d'entreprise to every record |
| `vatNumber` | **62%** | VAT is not issued to every micro-entreprise |
| `employeeBandYear` | **51%** | INSEE does not date every headcount band |
| `tradeName` | **26%** | most companies simply never register a separate trading name |
| `acronym` | **1%** | a `sigle` is genuinely rare |
| `dateClosed` | **0% / 98%** | null by definition on active companies; **39 of 40** on a `companyStatus: "closed"` run |
| `establishments` | **off by default** | populated for most filter-based searches when `includeEstablishments` is on; empty for some searches (e.g. a bare SIREN lookup), and capped at 10 sites per company by the API |

### Honest limits

- **A single search is capped at 10,000 companies.** That is the API's ceiling, not ours — it
  reports `total_results: 10000` for any broader query. To go past it, slice the search: one run per
  NAF code, per department, or per creation-date window. The actor already runs each activity code ×
  department combination as its own search.
- **Date filters need a companion.** The API rejects a date-only query, so `createdAfter` must be
  paired with an activity code, department, postcode or search term.
- **Non-diffusible records are skipped.** INSEE lets a company opt out of redistribution; those rows
  are excluded unless you explicitly set `includeNonDiffusible`. The run log tells you how many were
  skipped.
- **Directors are personal data.** They come from a public register, but GDPR still applies to what
  you do with them. Birth *dates* are deliberately not emitted — only the birth year — because a
  lead list has no use for them.

### Pricing

Pay per result — you are charged for the companies you actually receive, and nothing else.

| What | Price |
|---|---|
| Per company returned | **$0.004** |

A 1,000-company territory list costs **$4**.

### FAQ

**Do I need an INSEE API key?**
No. This uses the open `recherche-entreprises.api.gouv.fr` service, which needs no key and no account.

**Can I get companies created last month?**
Yes — set `createdAfter` and `createdBefore`, together with an activity code or department. That is
the standard new-business lead feed.

**Can I find companies that shut down?**
Yes. Set `companyStatus` to `closed` and you get a closures feed with `dateClosed` populated.

**What is a NAF code?**
The French activity classification (APE). `10.71C` is bakery, `56.10C` fast food, `62.01Z` computer
programming. Pass as many as you like — each is searched separately.

**How do I get more than 10,000 companies?**
Split the search. One run per department, or per NAF code, or per creation-date window. Each
combination gets its own 10,000-row window.

**Are the addresses geocoded?**
Yes, `latitude` and `longitude` come from the government's own geocoding — 99.8% fill on a
2,334-company run; a handful of addresses the register cannot geocode come back null.

**Does it return every establishment, or just the head office?**
Head office by default. Set `includeEstablishments` to add the establishments that matched your
search, each with its own SIRET and GPS — the API returns up to 10 per company, not the full branch
list. `establishmentCount` always carries the true total.

**Is the data up to date?**
Each row carries `lastUpdated` from the register. Sirene is refreshed continuously by INSEE.

**Can I filter out one-person shell companies?**
Set `employersOnly` to keep only companies registered as having employees.

**What happens if my search returns nothing?**
The run ends successfully with a status message explaining why, and you are charged nothing.

**Is scraping this legal?**
The Sirene database is French open data, published for reuse under an open licence. This actor reads
only the official public API and honours the register's own non-diffusion flag. You remain
responsible for using the data lawfully, including GDPR where director names are involved.

### Data source and fair use

Data comes from the French government's open company-search API over the INSEE Sirene base and the
RNE. Only publicly published register records are returned, the register's own opt-out flag is
respected, and no login or paywall is bypassed.

# Actor input Schema

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

Free-text search: company name, trade name, SIREN or SIRET. Combine with the filters below or use it on its own.

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

French activity codes, e.g. 10.71C (bakery), 56.10C (fast food), 62.01Z (software). Each code is searched separately, so several codes multiply the run.

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

Two-digit French department codes, e.g. 75 (Paris), 13 (Bouches-du-Rhone), 2A (Corse-du-Sud). Each is searched separately.

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

Exact postal codes, e.g. 75001. Used only when no department is given.

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

YYYY-MM-DD. Combine with an activity code, department or search term to get a new-business feed. The API rejects a date-only query.

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

YYYY-MM-DD.

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

Active companies (default), companies that have closed (a business-closures feed, with the closure date), or both.

## `employersOnly` (type: `boolean`):

Keep only companies registered as having employees. Filters out the very large tail of one-person micro-entreprises.

## `includeDirigeants` (type: `boolean`):

Add the company's registered officers (name, role, birth year) from the RNE. These are public register records but still personal data — use them lawfully.

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

Add every matching establishment (SIRET, address, GPS) as a nested array, not just the head office. Makes rows much larger.

## `includeNonDiffusible` (type: `boolean`):

INSEE lets a company opt out of redistribution. Those records are skipped by default. Only switch this on if you have a lawful basis.

## `maxItems` (type: `integer`):

Stop after this many companies. 0 = unlimited. Note the API caps ANY single search at 10,000 results — slice by activity code, department or creation date to go beyond that.

## `proxyConfiguration` (type: `object`):

Optional. This is an open government API with no anti-bot, so a proxy is not needed and only adds cost. Leave empty unless your network requires one.

## Actor input object example

```json
{
  "query": "boulangerie",
  "nafCodes": [
    "10.71C"
  ],
  "departments": [
    "75"
  ],
  "postalCodes": [],
  "createdAfter": "",
  "createdBefore": "",
  "companyStatus": "active",
  "employersOnly": false,
  "includeDirigeants": true,
  "includeEstablishments": false,
  "includeNonDiffusible": false,
  "maxItems": 100
}
```

# Actor output Schema

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

The dataset of scraped companies (one item per company).

# 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 = {
    "query": "",
    "nafCodes": [
        "10.71C"
    ],
    "departments": [
        "75"
    ],
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapersdelight/sirene-company-scraper").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 = {
    "query": "",
    "nafCodes": ["10.71C"],
    "departments": ["75"],
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("scrapersdelight/sirene-company-scraper").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 '{
  "query": "",
  "nafCodes": [
    "10.71C"
  ],
  "departments": [
    "75"
  ],
  "maxItems": 100
}' |
apify call scrapersdelight/sirene-company-scraper --silent --output-dataset

```

## MCP server setup

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

```

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/V8Rw41gavP2YHr5rS/builds/oa7aaXKaBhP1NJx2I/openapi.json
