# French Company Profile (Sirene + Financials) – Legal Entities (`shadow-tools/french-company-profile-sirene`) Actor

Search French companies by name, activity, department, size or turnover, or look them up by SIREN/SIRET: legal form, headcount, seat, latest turnover and net result. Legal entities only, no people (GDPR by design). Unofficial, open data.

- **URL**: https://apify.com/shadow-tools/french-company-profile-sirene.md
- **Developed by:** [Shadow Tools](https://apify.com/shadow-tools) (community)
- **Categories:** Lead generation, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 company profiles

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

## French Company Profile (Sirene + Financials) – legal entities only

Call this Actor to **search French companies or look them up by SIREN/SIRET** in the official public company directory and get, per company: legal name, legal form, NAF activity, size and headcount band, creation date, seat municipality and **the latest published turnover and net result** (plus the history by year), with data-freshness dates. Use it when an AI agent or a human needs to check that a French company exists, build a list of companies by sector, department, size or turnover, or enrich SIREN numbers (for example the winners of public contracts) with their profile and financials. **Legal entities only: never sole traders, never managers or any person's data** (see *Privacy / GDPR by design*), so it cannot answer "who runs this company".
One call = one answer. Typical run: 5-60 s. Empty input returns the 20 biggest active French companies.

> **Unofficial tool.** Not affiliated with, or endorsed by, the French State, INSEE, INPI or data.gouv.fr. It reads the public company directory (*API Recherche d'entreprises*) and adds filters, a fail-closed privacy gate and clean field names.

#### Minimal input per mode

| Mode | Minimal input | What comes back |
|---|---|---|
| `search` | `{"mode": "search", "nafPrefixes": ["62"], "departments": ["31"], "minTurnover": 1000000, "maxResults": 5}` | active IT-services companies in Haute-Garonne with at least 1 M EUR turnover, biggest first |
| `search` (by name) | `{"mode": "search", "query": "boulangerie", "departments": ["75"], "maxResults": 5}` | companies whose own name contains the words |
| `lookup` | `{"mode": "lookup", "ids": ["383474814", "552081317"]}` | one profile per SIREN/SIRET; unknown numbers, sole traders and non-public records are skipped (not charged) and counted in the run `SUMMARY` |

Short output (real record, 5 Nov 2026, shortened): `{"siren": "383474814", "name": "AIRBUS", "status": "active", "legalFormCode": "5710", "legalForm": "SAS (simplified joint-stock company)", "activityCode": "30.30Z", "sizeCategory": "GE", "headcountBand": "10,000 employees or more", "creationDate": "1991-10-18", "seatMunicipality": "BLAGNAC", "seatDepartment": "31", "latestFinancialYear": 2024, "turnoverEur": 57412795000, "netResultEur": 2206027000, "commercialDiffusionOpposition": true, "sourceUpdatedAt": "2026-11-05T09:57:01"}` (full record below; every record also carries `attribution` and `extractedAt`).

#### For AI agents (MCP)

- **One call = one answer.** Default `maxResults` is 20; keep it small and raise it only when the run `SUMMARY` says `capped: true`. Each returned company is billed, nothing else.
- **Pick the mode by what you have.** You have SIREN/SIRET numbers: `lookup` (give `ids`, nothing else). You have criteria: `search`. For a name, use `query` with company-name words (not a number: a 9/14-digit number in `query` is rejected with the hint to use `lookup`).
- **NAF prefixes work** (`"62"`, `"62.0"`, `"56.10A"`); departments are codes (`"75"`, `"2A"`, `"971"`); legal forms, headcount bands and size categories are closed lists (see the input schema).
- **Errors fail fast** in the form `Field X invalid: expected Y, got Z, example W` (for example `Field createdFrom invalid: expected a date YYYY-MM-DD, got "2024/01/01", example 2024-01-31.`). Fix that field and call again; nothing is charged.
- **0 results is not an error.** The run succeeds with an empty dataset and the key-value record `SUMMARY` carries `note: "0 results: <reason / how to widen the search>"` (for example: all matches were removed by the privacy gate, or the query words are not in any company name).
- **Not returned, by design:** managers, owners, employees, sole traders, street addresses, phone, e-mail. Do not call this Actor to find a person.
- **Financials are partial.** About 65 % of the companies returned in our sample have published accounts; micro/small companies may keep their accounts confidential. `latestFinancialYear` and `financials` are `null`/empty when none is published.

### What you get

One record per company (SIREN). Main fields: `siren`, `name`, `status`, `legalFormCode`, `legalForm` (label for the common codes), `activityCode` (NAF rev. 2) and `activityCodeNaf2025`, `activitySection`, `sizeCategory` (PME/ETI/GE), `headcountBandCode` and `headcountBand` (+ `headcountYear`), `creationDate`, `closureDate`, `establishmentsOpen` / `establishmentsTotal`, seat: `seatSiret`, `seatMunicipality`, `seatMunicipalityCode`, `seatPostalCode`, `seatDepartment`, `seatRegion`; `isAssociation`, `isSocialSolidarityEconomy`; financials: `latestFinancialYear`, `turnoverEur`, `netResultEur`, `financials` (all published years, newest first); `commercialDiffusionOpposition`; freshness: `sourceUpdatedAt`, `sireneUpdatedAt`, `registryUpdatedAt`; `directoryUrl` (official page of the company); `attribution`, `extractedAt`.

#### Example output (real run, 5 Nov 2026)

```json
{
  "siren": "383474814",
  "name": "AIRBUS",
  "status": "active",
  "legalFormCode": "5710",
  "legalForm": "SAS (simplified joint-stock company)",
  "activityCode": "30.30Z",
  "activityCodeNaf2025": "30.31Y",
  "activitySection": "C",
  "sizeCategory": "GE",
  "headcountBandCode": "53",
  "headcountBand": "10,000 employees or more",
  "headcountYear": "2024",
  "creationDate": "1991-10-18",
  "closureDate": null,
  "establishmentsOpen": 6,
  "establishmentsTotal": 11,
  "seatSiret": "38347481400100",
  "seatMunicipality": "BLAGNAC",
  "seatMunicipalityCode": "31069",
  "seatPostalCode": "31700",
  "seatDepartment": "31",
  "seatRegion": "76",
  "isAssociation": false,
  "isSocialSolidarityEconomy": false,
  "latestFinancialYear": 2024,
  "turnoverEur": 57412795000,
  "netResultEur": 2206027000,
  "financials": [{ "year": 2024, "turnoverEur": 57412795000, "netResultEur": 2206027000 }],
  "commercialDiffusionOpposition": true,
  "directoryUrl": "https://annuaire-entreprises.data.gouv.fr/entreprise/383474814",
  "sourceUpdatedAt": "2026-11-05T09:57:01",
  "sireneUpdatedAt": "2025-12-06T05:24:56",
  "registryUpdatedAt": "2026-08-25T16:48:26"
}
```

### Who uses it

- **Sales and business-development teams**: build prospect lists by activity, department, size band and turnover (respect `commercialDiffusionOpposition`, see below).
- **Suppliers, credit and KYB checks**: confirm a counterparty exists, is active and what its legal form, size and latest accounts are, from a SIREN or SIRET on an invoice.
- **Market analysts and journalists**: count and rank companies of a sector in a territory, follow new companies (`createdFrom`) or loss-making ones (`maxNetResult`).
- **Data teams and AI agents**: enrich a list of SIREN numbers in one call.

### Quick start

Empty input = the 20 biggest active companies. Examples:

**Profitable mid-size IT companies in Haute-Garonne**

```json
{ "nafPrefixes": ["62"], "departments": ["31"], "headcountBands": ["12", "21", "22"], "minNetResult": 0, "maxResults": 100 }
```

**Restaurants created in 2025 in Paris**

```json
{ "nafPrefixes": ["56"], "departments": ["75"], "createdFrom": "2025-01-01", "createdTo": "2025-12-31", "maxResults": 200 }
```

**Profile of a list of SIREN / SIRET numbers**

```json
{ "mode": "lookup", "ids": ["383474814", "552081317", "35600000000048"] }
```

**Loss-making large companies**

```json
{ "sizeCategories": ["ETI", "GE"], "maxNetResult": -1000000, "maxResults": 100 }
```

#### Filters (search mode)

| Field | Meaning |
|---|---|
| `query` | words that must all appear in the company's own name (accents and case ignored) |
| `nafPrefixes` | NAF/APE codes or prefixes of the main activity: `"62"`, `"62.0"`, `"56.10A"` |
| `departments` | department codes of an establishment: `"75"`, `"2A"`, `"971"` |
| `legalForms`, `headcountBands`, `sizeCategories` | closed lists |
| `createdFrom`, `createdTo` | creation date window `YYYY-MM-DD`, applied after fetching (the directory has no such filter): combine with a department or NAF prefix |
| `onlyActive` | default true |
| `minTurnover`, `maxTurnover`, `minNetResult`, `maxNetResult` | EUR, on the latest published accounts; companies without accounts are then left out |
| `excludeProspectingOptOut` | drop companies flagged `commercialDiffusionOpposition` |
| `maxResults` | default 20, max 10,000. The directory exposes at most 10,000 rows per query: split bigger extractions by department or NAF prefix |

### How it differs from the other company Actors

- **UK Companies House Data** (same publisher) covers the **United Kingdom** from Companies House's monthly data snapshot (with change tracking) and has filing deadlines but no turnover or net result. This Actor covers **France**, calls the live French public directory, and includes turnover and net result when published. Different country, source and fields; no shared data.
- **French Public Contract Awards (DECP)** (same publisher) tells you *who won* a public contract and gives the winner's SIREN. Feed those SIREN numbers to this Actor's `lookup` mode to get the winner's size, activity and latest financials.

### Privacy / GDPR by design

This Actor is deliberately built **not** to return natural persons. The filtering below is applied **on purpose to respect the GDPR**; it is a design choice, not a limitation to work around.

- **Fail closed.** A record is returned only if the directory itself says it is clearly a legal entity. Anything unknown, unreadable or missing is dropped, never guessed. Dropped records are not charged.
- **Rules.** Dropped: legal form category 1 (sole traders, craftsmen, traders, liberal professions, farmers) and 2 (indivisions and de-facto partnerships, which are groups of natural persons); records flagged as sole trader; records whose legal form, flag, public-diffusion status or seat is missing or not "public"; companies whose name contains the surname of one of their own natural-person managers (typically one-person companies named after their owner). Associations, companies and public bodies are kept.
- **Structured fields only.** The output is a fixed whitelist of fields. The directory also sends managers, street addresses and coordinates; they are never copied (managers are read in memory only for the name check above, then discarded). No person's name, address, phone or e-mail is output, and there is no free text. The company name is the legal name of a legal entity.
- **Measured on real data (5 Nov 2026; 10 varied queries by activity, department, size and name; 1,000 directory rows per pass).** Raw directory stream without any filter: **21.4 %** of the rows were sole traders and a further 4.5 % were companies named after a manager (74.1 % kept). With the Actor's own request (it also asks the directory to exclude sole traders): **87.8 % of the 1,000 rows kept, 12.2 % dropped** (11.6 % company named after a manager, 0.6 % no legal personality, none left to drop as sole traders). The share varies by query: restaurants and IT services 97-100 % kept, agriculture 80 % kept (37 % without the server-side exclusion), a common-surname name search 53 % kept.
- **Not guaranteed.** Detection relies on the directory's legal form and flags, which can be wrong or late. A legal entity whose name happens to be a person's name without matching a listed manager (for example a company named after a founder who is no longer a manager) is kept. The seat municipality of a small company can be a manager's home town. You remain responsible for your own use of the data, including prospecting rules: `commercialDiffusionOpposition: true` means the company asked not to be used for commercial prospecting (about half the companies carry it); use `excludeProspectingOptOut` to leave them out.
- **What is stored.** Nothing about you beyond your own run's dataset, key-value record and logs in your Apify account. No cache of results, no requester data.

### Limits and disclaimer

- **Freshness**: the directory is updated daily (`sourceUpdatedAt`); Sirene fields can lag (`sireneUpdatedAt`), published accounts come with a year or more of delay (`latestFinancialYear`). Companies that asked to keep their accounts confidential have none.
- **Not included**: managers/owners, shareholders, addresses of establishments, phone/e-mail, non-public (non-diffusible) companies, companies refused registration, predecessors/successors.
- **Quality and speed**: data is declared by companies and administrations; no warranty, check the official page (`directoryUrl`) before relying on a record. The directory allows about 7 requests/s per IP; the Actor stays below and retries on HTTP 429. Search reads 25 rows per request.
- **Source and licence**: [API Recherche d'entreprises](https://recherche-entreprises.api.gouv.fr) (DINUM, "Annuaire des Entreprises"), built on Sirene (INSEE), the national business register (INPI) and accounts published by INPI. The directory dataset on data.gouv.fr is published under the **Licence Ouverte 2.0** (Etalab). Every record carries the attribution.
- Unofficial service, not endorsed by any public body.

# Actor input Schema

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

"search" = use when you want a list of companies matching criteria (name words, activity, department, legal form, size, creation dates, turnover). "lookup" = use when you already have SIREN or SIRET numbers (for example the winner of a public contract) and want each company's profile and latest financials.

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

Search mode. Words that must all appear in the company name, accents and case ignored, 1 to 120 characters. Example: "boulangerie" or "transports martin". Not for numbers: use lookup mode for SIREN/SIRET.

## `nafPrefixes` (type: `array`):

Search mode. List of NAF/APE activity codes or prefixes of the main activity, each 2 digits or more. Example: \["62"] for IT services, \["56.10A"] for traditional restaurants, \["47.11"] for food retail.

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

Search mode. List of French department codes where the company has an establishment: 2-3 digits, or 2A / 2B. Example: \["75", "92"] for Paris and Hauts-de-Seine, \["971"] for Guadeloupe.

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

Search mode. Closed list of INSEE legal-form codes to keep. Example: \["5710"] for SAS only, \["5499", "5498"] for limited liability companies.

## `headcountBands` (type: `array`):

Search mode. Closed list of INSEE employee bands to keep (employer companies). Example: \["12", "21"] for 20-99 employees.

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

Search mode. Closed list of INSEE size categories to keep: PME (small and medium), ETI (mid-cap), GE (large). Example: \["ETI", "GE"].

## `createdFrom` (type: `string`):

Search mode. Earliest company creation date, format YYYY-MM-DD. Example: 2025-01-01. Applied after fetching (the directory has no date filter), so combine it with a department or NAF prefix to keep it fast.

## `createdTo` (type: `string`):

Search mode. Latest company creation date, format YYYY-MM-DD. Example: 2025-12-31. Applied after fetching, see createdFrom.

## `onlyActive` (type: `boolean`):

Search mode. When true, ceased companies are left out. Set false to include ceased companies (status "ceased" in the output).

## `minTurnover` (type: `integer`):

Search mode. Keep companies whose latest published turnover is at least this amount in euros. Example: 1000000. Companies without published accounts are then left out.

## `maxTurnover` (type: `integer`):

Search mode. Keep companies whose latest published turnover is at most this amount in euros. Example: 50000000.

## `minNetResult` (type: `integer`):

Search mode. Keep companies whose latest published net result is at least this amount in euros (can be negative). Example: 0 for profitable companies.

## `maxNetResult` (type: `integer`):

Search mode. Keep companies whose latest published net result is at most this amount in euros (can be negative). Example: -100000 for loss-making companies.

## `excludeProspectingOptOut` (type: `boolean`):

Both modes. When true, companies flagged commercialDiffusionOpposition (they asked not to be used for commercial prospecting) or with an unknown flag are left out. Default false; about half of the companies carry the flag.

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

Lookup mode. List of SIREN (9 digits) or SIRET (14 digits) identifiers, spaces tolerated, up to 10000. Example: \["383474814", "552081317"]. Unknown numbers, sole traders and non-public records are skipped and never charged.

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

Maximum number of company records to return (each one is billed). Default 20; in lookup mode the default is the number of ids. Example: 200. The directory exposes at most 10,000 rows per query.

## Actor input object example

```json
{
  "mode": "search",
  "query": "",
  "nafPrefixes": [
    "62"
  ],
  "departments": [
    "75",
    "92"
  ],
  "onlyActive": true,
  "excludeProspectingOptOut": false,
  "ids": [
    "383474814",
    "552081317"
  ],
  "maxResults": 20
}
```

# Actor output Schema

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

Main fields of each company: SIREN, name, legal form, activity, size, seat, latest turnover and net result.

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

Every field of every record, including the financial history by year.

# 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": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("shadow-tools/french-company-profile-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 = {
    "mode": "search",
    "query": "",
}

# Run the Actor and wait for it to finish
run = client.actor("shadow-tools/french-company-profile-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 '{
  "mode": "search",
  "query": ""
}' |
apify call shadow-tools/french-company-profile-sirene --silent --output-dataset

```

## MCP server setup

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