Nexus Tools / Data guides

French company data as JSON or CSV: the recherche-entreprises (SIRENE) API, its limits, a Python example and a free sample

How to pull French company records from the official open API yourself, which limits and filter traps to expect, what to do about directors and sole traders under the GDPR, and when a normalized feed is worth paying for.

Updated: November 2026. API behaviour below was tested live on 5 November 2026.

The short version

1. The recherche-entreprises API

Base URL: https://recherche-entreprises.api.gouv.fr. The interactive documentation is at /docs/ and the OpenAPI file at /openapi.json (it declares API version 1.0.0 and the MIT licence for the API software). No key or login.

curl -s "https://recherche-entreprises.api.gouv.fr/search?q=buffalo+grill&per_page=1"

Limits and errors, as we saw them on 5 November 2026

Filters

GoalParameterTrap
Activityactivite_principale=62.01Z,62.02AExact NAF rev. 2 codes only. 56.1 returns HTTP 400 and the error lists the valid codes. No prefix search, and NAF 2025 codes are not accepted (the response has both: activite_principale and activite_principale_naf25).
Locationdepartement, region, code_postal, code_communeMatches companies with any establishment there; the head office can be elsewhere.
Sizetranche_effectif_salarie, categorie_entreprise (PME, ETI, GE)Workforce band codes, not numbers.
Status and formetat_administratif=A (active) or C (ceased), nature_juridique-
Revenueca_min, ca_max, resultat_net_min, resultat_net_maxOnly companies that filed accounts have figures.
Flagsest_ess, est_association, est_entrepreneur_individuel, est_rge, est_qualiopi and others-
Output sizeminimal=true&include=siege,finances,dirigeantsWithout it, every record is large.

There is no creation-date filter: date_creation is an output field only, so "companies created last month" cannot be asked of this API.

What the records look like

2. DIY: companies to CSV in Python

This script (tested on 5 November 2026: 10,000 matches for two software NAF codes in Paris, 100 written) pages through results under the rate limit, retries on 429 and 5xx, leaves sole traders out and flattens the head-office address and the latest revenue. It needs pip install requests. Directors are deliberately not read.

import csv
import time

import requests

URL = "https://recherche-entreprises.api.gouv.fr/search"
# activite_principale takes EXACT NAF rev. 2 codes (e.g. 62.01Z). "62" or "62.0" is HTTP 400
# and the error lists the 732 valid codes. NAF 2025 codes are not accepted.
NAF = ["62.01Z", "62.02A"]
PARAMS = {
    "activite_principale": ",".join(NAF),
    "departement": "75",                       # matches companies with ANY establishment in Paris, not only head offices
    "etat_administratif": "A",                 # active only
    "est_entrepreneur_individuel": "false",    # leave sole traders out: their business name is a person's name
    "per_page": 25,                            # 1-25, above is HTTP 400
}
MAX_WINDOW = 10_000                            # page * per_page must not exceed this, whatever total_results says

rows, page = [], 1
while page * PARAMS["per_page"] <= MAX_WINDOW and len(rows) < 100:     # demo: 100 companies
    for attempt in range(5):
        r = requests.get(URL, params={**PARAMS, "page": page}, timeout=30)
        if r.status_code in (429, 500, 502, 503, 504):
            time.sleep(int(r.headers.get("Retry-After", 2 ** attempt)))
            continue
        r.raise_for_status()                   # 400 = JSON {"erreur": "..."}
        break
    data = r.json()
    if page == 1:
        print(data["total_results"], "matches (capped at 10000)")
    for c in data["results"]:
        s = c.get("siege") or {}
        fin = (c.get("finances") or {})
        last = max(fin) if fin else None       # {"2024": {"ca": ..., "resultat_net": ...}}
        rows.append({
            "siren": c["siren"], "name": c["nom_complet"], "naf": s.get("activite_principale"),
            "legal_form": c.get("nature_juridique"), "employees_band": c.get("tranche_effectif_salarie"),
            "category": c.get("categorie_entreprise"), "created": c.get("date_creation"),
            "hq_city": s.get("libelle_commune"), "hq_postcode": s.get("code_postal"),
            "revenue": fin[last].get("ca") if last else None, "revenue_year": last,
            "url": f"https://annuaire-entreprises.data.gouv.fr/entreprise/{c['siren']}",
        })
    if page >= data["total_pages"]:
        break
    page += 1
    time.sleep(0.2)                            # stay far below 7 requests per second per IP

with open("companies_fr.csv", "w", newline="", encoding="utf-8") as f:
    w = csv.DictWriter(f, fieldnames=rows[0].keys())
    w.writeheader()
    w.writerows(rows)
print(len(rows), "companies written")

3. When the Actor saves time

For a one-off list, the script is enough and free. The Apify Actor France Company Search (by Nexus Scrapers) wraps the same official API. It pays off when you would otherwise maintain that code:

Pricing is pay per result; the Actor page shows the current price.

Limits: it inherits the API's 10,000-result window (split by department or NAF to go beyond), the establishment-level location filter, the lack of a creation-date filter and the absence of non-diffusible companies. It has no beneficial-owner data and no filed accounts documents. For a single list, use the script.

4. Real sample: 20 normalized records

These 20 records were produced on 5 November 2026 by running the Actor's own code locally on live API responses (no Apify platform involved): 12 software-programming companies (NAF 62.01Z) with an establishment in Paris and 50 to 249 employees, 4 restaurant companies (56.10A) with an establishment in the Rhône and 4 supermarket companies (47.11D) with an establishment in Occitanie, largest first. Because of the establishment-level location filter, several head offices are elsewhere, and the workforce band is that of the company, so a few show no employees at all. They are the first matches in that order, not hand-picked for quality.

No natural-person data. Sole traders were excluded with the Actor's own filter, natural-person directors are dropped by default (the only directors kept are legal entities), and there are no contacts. A scrub pass over all text fields found no e-mail address or phone number. The names are company names; the head-office address is the registered business address.

Download: sample.json (full records, UTF-8) and sample.csv (flattened, lists joined with | , opens in Excel). Free to use under the licence in section 5.

SIRENNameNAFLegal formSizeHead officeRevenue
387495799VISIATIV SOLUTIONS ENTREPRISE62.01ZSASGECHARBONNIERES-LES-BAINS84,495,737 EUR (2024)
851035329CHAPSVISION62.01ZSASETISURESNES156,671,000 EUR (2024)
519037253TRUSTTEAM (TRUSTTEAM)62.01ZSASPMEMAXEVILLE8,904,988 EUR (2022)
823393764CLUB EMPLOYES62.01ZSASPMESAINTE-FOY-LES-LYON76,199,037 EUR (2025)
439737222ORISHA PROPERTY MANAGEMENT (O…62.01ZSASETISAINT-DENIS33,767,618 EUR (2025)
820334951LITTLE WORKER62.01ZSASPMEBORDEAUX21,698,113 EUR (2021)
487549693ALTRAN PROTOTYPES AUTOMOBILES62.01ZSASGEISSY-LES-MOULINEAUX44,021,000 EUR (2025)
518892211SILAE62.01ZSASETIAIX-EN-PROVENCE56,508,017 EUR (2022)
813754389UNITY TECHNOLOGIES SARL62.01ZSociété à responsabil…PMEPARIS19,496,273 EUR (2025)
817451313GALADRIM62.01ZSASPMEPARIS-
400300190GLOBANT FRANCE (PENTALOG FRAN…62.01ZSASETIPARIS66,074,854 EUR (2024)
752946863LEARNINGSHELTER62.01ZSA à conseil d'admini…PMEPARIS16,398,933 EUR (2025)
318906443BUFFALO GRILL56.10ASASETIMONTROUGE305,303,715 EUR (2025)
305836033SERARE56.10ASAS-EVRY-COURCOURONNES189,805,347 EUR (2018)
888796430NEW COURT56.10ASASETIMONTROUGE119,852,026 EUR (2022)
311160592SODEXO SPORTS ET LOISIRS56.10ASASGEGUYANCOURT196,083,975 EUR (2025)
343262622LIDL (LIDL)47.11DSociété en nom collec…GECHATENAY-MALABRY-
410409015AUCHAN SUPERMARCHE47.11DSASGEVILLENEUVE-D'ASCQ3,016,900,000 EUR (2024)
493318067ALDI MARCHE TOULOUSE47.11DSociété à responsabil…GESAINT-SULPICE-LA-POINTE726,383,284 EUR (2024)
929781524A+SUPER47.11DSASGELILLE-

One record in full. Note that the head office of this "Paris" company is in the Rhône, because the department filter matches any establishment:

{
  "schemaVersion": "1.0",
  "siren": "387495799",
  "name": "VISIATIV SOLUTIONS ENTREPRISE",
  "legalName": "VISIATIV SOLUTIONS ENTREPRISE",
  "acronym": null,
  "legalFormCode": "5710",
  "legalForm": "SAS, société par actions simplifiée",
  "nafCode": "62.01Z",
  "nafLabel": "Programmation informatique",
  "naf2025Code": "62.20H",
  "naf2025Label": "Gestion d'installations informatiques et maintenance de systèmes et d'applications informatiques",
  "activitySection": "J",
  "activitySectionLabel": "Information et communication",
  "creationDate": "1992-05-04",
  "closureDate": null,
  "status": "active",
  "employeeBandCode": "22",
  "employeeBand": "100 à 199 salariés",
  "employeeBandYear": 2024,
  "category": "GE",
  "categoryYear": 2024,
  "isEmployer": false,
  "establishmentsCount": 48,
  "openEstablishmentsCount": 15,
  "headOffice": {
    "siret": "38749579900067",
    "address": "26 RUE BENOIT BENNIER 69260 CHARBONNIERES-LES-BAINS",
    "postalCode": "69260",
    "city": "CHARBONNIERES-LES-BAINS",
    "communeCode": "69044",
    "department": "69",
    "region": "84",
    "latitude": 45.776120571,
    "longitude": 4.7489782507,
    "departmentName": "Rhône",
    "regionName": "Auvergne-Rhône-Alpes",
    "tradeNames": null
  },
  "latestFinancialYear": 2024,
  "latestRevenue": 84495737,
  "latestNetIncome": 3817639,
  "financials": [
    {
      "year": 2024,
      "revenue": 84495737,
      "netIncome": 3817639
    }
  ],
  "labels": [
    "QUALIOPI",
    "ORGANISME_FORMATION"
  ],
  "isSoleTrader": false,
  "isAssociation": false,
  "isPublicService": null,
  "collectiveAgreements": [
    "1486"
  ],
  "vatNumber": "FR27387495799",
  "diffusionStatus": "full",
  "commercialUseOpposition": true,
  "corporateDirectors": [
    {
      "siren": "395008246",
      "name": "VISIATIV",
      "role": "Président de SAS"
    }
  ],
  "updatedAt": "2026-11-04T11:24:43",
  "sourceUrl": "https://annuaire-entreprises.data.gouv.fr/entreprise/387495799",
  "source": "recherche-entreprises.api.gouv.fr",
  "scrapedAt": "2026-11-05T07:50:40+00:00"
}

5. Data licence and terms

The underlying register data is open data. The SIRENE dataset on data.gouv.fr (publisher: INSEE) is under the Licence Ouverte / Open Licence 2.0 (Etalab): free reuse, commercial included, if you credit the source and the date of the last update. The API's own page on api.gouv.fr says "Licence non renseignée", and its OpenAPI file declares MIT for the software, so the data licence is the one of the sources, not of the API. Credit "INSEE, base Sirene" and the Annuaire des Entreprises, and say when you downloaded the data.

Two obligations sit outside the licence. Diffusion restrictions: the API already hides what owners asked to hide, and you must not try to recover it from other fields. Personal data: a sole trader's name and the names and birth dates of directors are personal data under the GDPR even though they are public; reuse needs your own lawful basis and information duties. Businesses may also object to commercial prospecting (opposition_diffusion_commerciale); respect it when you build marketing lists. This is a summary, not legal advice.

Links