# French Company Leads - Sirene API, SIREN/SIRET Data (`lukehunter/french-companies-sirene`) Actor

Find French companies (entreprises) from the official Sirene-based Recherche d'entreprises API. Filter by NAF code, department, headcount and creation date, get only new companies on a schedule, with SIREN/SIRET, officers and Slack alerts, $0.004/company.

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

## Pricing

$4.00 / 1,000 companies

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 Leads - Sirene API, SIREN/SIRET Data

**For sales teams, agencies, recruiters, accountants and data teams who prospect French businesses.** Search **French company data** (*entreprises*) by activity (NAF/APE code), department, region, postal code, headcount, size and legal form, find **newly registered companies**, and get one clean row per company with **SIREN, SIRET**, head-office address and coordinates, officers (*dirigeants*), published financials and a link to the public company page. Run it on a schedule to get only new companies, and send each one to Slack, Discord or Telegram.

**$0.004 per delivered company — 1,000 companies = $4**

It reads the official, free and open **Recherche d'entreprises API** from the French government (the **Sirene API** register of companies, run by the DINUM and INSEE). No scraping, no login, no proxy, no API key. Only companies that pass your filters are delivered, and only delivered companies are charged.

### What you get

One row per company, flattened and ready for a spreadsheet, CRM or enrichment step: SIREN, SIRET of the head office (*siège*), name, acronym, legal form code, main activity (NAF/APE code and section), size category (PME, ETI, GE), **headcount band** as code and readable text, **creation date**, administrative status, the head-office **address, postal code, commune, département, region, latitude and longitude**, number of establishments (total and open), **officers** as the register publishes them, financial figures where published, and the `annuaireEntreprisesUrl` page on annuaire-entreprises.data.gouv.fr.

| You want | Set |
|---|---|
| New restaurants in Paris this month | `activitePrincipale: ["56.10A"]`, `departement: "75"`, `createdWithinDays: 30` |
| IT companies with 10-49 staff in Lyon | `activitePrincipale: ["62.01Z", "62.02A"]`, `departement: "69"`, `trancheEffectif: ["11", "12"]` |
| One postal code | `codePostal: "75011"` |
| A whole region | `region: "84"` (Auvergne-Rhône-Alpes) |
| Mid-size and large companies | `categorieEntreprise: ["ETI", "GE"]` |
| SAS companies only | `natureJuridique: "5710"` |
| Companies created since a date | `createdAfter: "2026-09-01"` |
| Only what is new since yesterday | `onlyNewSinceLastRun: true` on a daily Schedule |
| Search by name or keyword | `q: "boulangerie"` |

### Quick start

```json
{
  "activitePrincipale": ["56.10A"],
  "departement": "75",
  "maxItems": 20
}
```

At least one filter is required (the API needs a query). Companies are active by default (`etatAdministratif: "A"`).

### Recipes

**New restaurants in Paris this month**

```json
{
  "activitePrincipale": ["56.10A"],
  "departement": "75",
  "createdWithinDays": 30,
  "maxItems": 200
}
```

Newest registrations come first. Chain the result to [Company Contact Scraper](https://apify.com/lukehunter/company-contact-scraper) to find each new restaurant's website email.

**IT companies with 10-49 staff in Lyon**

```json
{
  "activitePrincipale": ["62.01Z", "62.02A"],
  "departement": "69",
  "trancheEffectif": ["11", "12"],
  "maxItems": 500
}
```

Headcount bands can also be written as ranges: `["10-19", "20-49"]`. Note that many companies declare no headcount band, so they are not returned when you filter on it.

**Daily new company alerts to Slack**

```json
{
  "activitePrincipale": ["56.10A", "56.30Z"],
  "region": "11",
  "createdWithinDays": 14,
  "onlyNewSinceLastRun": true,
  "maxItems": 100,
  "slackWebhookUrl": "https://hooks.slack.com/services/<T>/<B>/<token>"
}
```

Save it as a Task, add a daily Schedule, and each morning Slack gets only the companies registered since the last run. The first run is the baseline and sends what matches now.

**SIREN/SIRET lookup by name**

```json
{
  "q": "Le Petit Zéphyr",
  "departement": "75",
  "maxItems": 5
}
```

### Alerts: Discord, Telegram, Slack, Teams, Google Chat, phone push or any app

Add one or more destinations in the **Notifications (optional)** section and each run sends the companies it delivered. It is a monitor that notifies you: it only reads a public register, and never contacts a company, a person or any third party.

| Channel | Fill in | What you get |
|---|---|---|
| Discord | `discordWebhookUrl` | One card per company, 10 per message |
| Telegram | `telegramBotToken` + `telegramChatId` | Up to 10 companies per message, one line each |
| Slack | `slackWebhookUrl` | Block Kit message, up to 10 companies per message |
| Mattermost, Rocket.Chat | `slackCompatibleWebhookUrl` | A Markdown list |
| Microsoft Teams | `teamsWebhookUrl` | Adaptive Card from a Teams Workflows webhook |
| Google Chat | `googleChatWebhookUrl` | Card in a space |
| ntfy (phone push, no account) | `ntfyTopic` (optional `ntfyServer`, `ntfyToken`) | A push per company, up to 10, then one "...and N more" |
| Pushover (phone push) | `pushoverUserKey` + `pushoverAppToken` | A push per company, up to 10, then one "...and N more" |
| Zapier, Make, n8n, Pipedream | `webhookUrl` | One JSON POST per 100 delivered rows with the full dataset rows |

Each message reads like `New company: LE PETIT ZEPHYR — 75011 PARIS 11E ARRONDISSEMENT`, with activity, headcount, creation date, address, SIREN and a link to the public company page. Officers' names are never put in notifications. Nothing is sent when a run delivers nothing, a failing channel never fails the run, and notifications are free: you pay only for delivered companies. Webhook URLs and tokens are stored as secret inputs.

`maxNotifications` (default 25, max 100) caps how many companies go to chat and phone channels per run; the rest are still in the dataset. Use `onlyNewSinceLastRun` for alerts, otherwise a scheduled run repeats the same companies.

### Input

| Field | Default | What it does |
|---|---:|---|
| `q` | `""` | Free text on company name, officer name or address. |
| `activitePrincipale` | `[]` | NAF/APE codes, format `NN.NNL`, e.g. `56.10A`. A malformed code stops the run with an error; `5610a` is normalised to `56.10A`. |
| `departement` | `""` | Département code (`75`, `69`, `2A`, `971`); commas for several, e.g. `75,92,93,94`. |
| `region` | `""` | INSEE region code (`11`, `84`, `93`, `76` ...). |
| `codePostal` | `""` | 5-digit postal code; commas for several. |
| `trancheEffectif` | `[]` | Headcount band codes (`11` = 10-19, `12` = 20-49 ...) or ranges (`"10-19"`). |
| `categorieEntreprise` | `[]` | `PME`, `ETI`, `GE`. |
| `etatAdministratif` | `A` | `A` active, `C` ceased, `all` both. |
| `natureJuridique` | `""` | 4-digit legal category, e.g. `5710` (SAS), `5499` (SARL), `1000` (sole trader). |
| `createdWithinDays` | none | Only companies registered in the last N days (1 to 3650). |
| `createdAfter` | none | Only companies registered on or after `YYYY-MM-DD`. Overrides `createdWithinDays`. |
| `maxItems` | `50` | Hard cap on delivered companies, 1 to 5000. |
| `onlyNewSinceLastRun` | `false` | Deliver and charge only companies not delivered before for this same set of filters. |
| `stateStoreName` | `france-company-leads-seen-companies` | Named store holding the alert memory. |
| notification fields | none | `discordWebhookUrl`, `telegramBotToken`, `telegramChatId`, `slackWebhookUrl`, `slackCompatibleWebhookUrl`, `teamsWebhookUrl`, `googleChatWebhookUrl`, `ntfyTopic`, `ntfyServer`, `ntfyToken`, `pushoverUserKey`, `pushoverAppToken`, `webhookUrl`, `maxNotifications`. |

Wrong values fail early with a message that says what to fix, for example `"activitePrincipale" entry "restaurants" is not valid. Use a NAF/APE code such as 56.10A`.

#### How "new companies" works

The API has no creation-date filter, so `createdWithinDays` and `createdAfter` are applied by the Actor on each company's `dateCreation` after the pages are downloaded. To return the newest companies first, the Actor reads every page of your query (up to the API's limit below) before it delivers. That is quick with a narrow query (one department and one NAF code is a few pages) and slower with a broad one. Combine the date filter with a department, postal code or NAF code.

#### How "only new" works

With `onlyNewSinceLastRun`, the Actor remembers each delivered company by its SIREN in a named key-value store, per set of filters (changing a NAF code starts a fresh baseline; changing `maxItems` does not, and a rolling `createdWithinDays` stays one watch). Only companies actually delivered are remembered, so anything held back by `maxItems` or your spending limit turns up on the next run.

### Example output

```json
{
  "siren": "900000001",
  "siret": "90000000100011",
  "nomComplet": "LE PETIT ZEPHYR (ZEPHYR)",
  "sigle": "ZEPHYR",
  "natureJuridique": "5710",
  "activitePrincipale": "56.10A",
  "activitePrincipaleLabel": null,
  "sectionActivite": "I",
  "sectionActiviteLabel": "Hébergement et restauration",
  "categorieEntreprise": "PME",
  "trancheEffectif": "11",
  "trancheEffectifLabel": "10 to 19 employees",
  "trancheEffectifAnnee": 2024,
  "dateCreation": "2026-09-22",
  "dateFermeture": null,
  "etatAdministratif": "A",
  "statutDiffusion": "O",
  "adresse": "12 RUE DES LILAS 75011 PARIS",
  "complementAdresse": "BAT B",
  "codePostal": "75011",
  "commune": "75111",
  "libelleCommune": "PARIS 11E ARRONDISSEMENT",
  "departement": "75",
  "region": "11",
  "latitude": 48.8597,
  "longitude": 2.3801,
  "nombreEtablissements": 2,
  "nombreEtablissementsOuverts": 1,
  "dirigeants": [
    { "type": "personne physique", "nom": "DUPONT-EXEMPLE", "prenoms": "Camille Marie", "qualite": "Président" },
    { "type": "personne morale", "siren": "900000099", "denomination": "HOLDING EXEMPLE SAS", "qualite": "Directeur général" }
  ],
  "finances": [
    { "year": 2024, "chiffreAffaires": 410000, "resultatNet": 12500 },
    { "year": 2023, "chiffreAffaires": 380000, "resultatNet": -4000 }
  ],
  "chiffreAffaires": 410000,
  "resultatNet": 12500,
  "exerciceFinancier": 2024,
  "annuaireEntreprisesUrl": "https://annuaire-entreprises.data.gouv.fr/entreprise/900000001",
  "scrapedAt": "2026-10-10T12:00:00.000Z"
}
```

This sample is illustrative (an invented company and invented people), shaped like the API's response. Anything the register does not publish is `null` (or an empty list), never guessed. `activitePrincipaleLabel` is filled only when the API provides a label; the NAF section name is added from the official nomenclature. **Officers:** legal entities are kept with their SIREN and name; for natural persons only name, first names and role are output, with no birth date and no nationality.

### Use with AI agents (MCP)

This Actor works as a tool for Claude, ChatGPT, Cursor and other MCP clients through [Apify's MCP server](https://mcp.apify.com). Every input is optional except that at least one filter must be set, so a call can be as small as a NAF code and a département.

**Claude Desktop** (`claude_desktop_config.json`), with your own token from Apify Console > Settings > API & Integrations:

```json
{
  "mcpServers": {
    "apify-french-company-leads": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "https://mcp.apify.com?tools=lukehunter/france-company-leads",
        "--header", "Authorization: Bearer ${APIFY_TOKEN}"
      ],
      "env": { "APIFY_TOKEN": "<YOUR_APIFY_TOKEN>" }
    }
  }
}
```

Clients that support OAuth (Claude.ai, VS Code) can connect with just the URL `https://mcp.apify.com?tools=lukehunter/france-company-leads` and sign in to Apify. Never paste a real token into a shared file or chat.

**Example.** You ask: "Which software companies were registered in Lyon in the last 60 days, and who runs them?" The agent calls the tool `lukehunter--france-company-leads` with:

```json
{
  "activitePrincipale": ["62.01Z", "62.02A"],
  "departement": "69",
  "createdWithinDays": 60,
  "maxItems": 25
}
```

It is charged $0.004 per delivered company, capped by `maxItems`. Each input property description is short and carries an example, so agents fill it in correctly.

### Pricing

Pay-per-event: **$0.004 per delivered company.** A company is charged only after it is accepted into the dataset, and only if it passed your filters (and, in alert mode, was not delivered before).

| Companies delivered | Cost |
|---:|---:|
| 20 | $0.08 |
| 50 (default cap) | $0.20 |
| 1,000 | $4.00 |
| 5,000 (maximum) | $20.00 |

`maxItems` (hard maximum 5,000) and your Apify per-run spending limit both stop delivery before the cap is passed. Reading the API, filtering and sending notifications cost nothing extra. Price changes follow Apify's notice rules; the Pricing tab always shows the rate you are charged.

### Limitations

- **Official open data, Licence Ouverte 2.0.** The data comes from the public API Recherche d'entreprises (Sirene register and related public registers) and is re-used under the [Licence Ouverte / Open Licence 2.0](https://www.etalab.gouv.fr/licence-ouverte-open-licence/) published by Etalab. If you republish the data, attribute the source: "Source: API Recherche d'entreprises, DINUM / INSEE, Licence Ouverte 2.0."
- **Not affiliated with the French government.** This is an independent Actor reading a public API. For legal or contractual purposes confirm a company on the official sources (the `annuaireEntreprisesUrl` page, INSEE, the commercial court registers).
- **10,000 results per query.** The API exposes only the first 10,000 results of any query (400 pages of 25). If your filters match more, the run says so in its status message; narrow them (department, postal code, NAF code, headcount, or a shorter date window) and run again. With a creation-date filter and a broad query, the newest companies may sit beyond that window until you narrow it.
- **Creation date is filtered after download.** The API has no such filter, so the Actor applies it to `dateCreation`; companies with no creation date are excluded while it is set.
- **Partial diffusion is respected.** Some entrepreneurs (mostly sole traders) have asked the register to hide personal details. Those values come back masked and are output as `null`; the Actor never tries to unmask them, and records the API flags as non-diffusible are not output.
- **Headcount and finances are often missing.** Many companies declare no headcount band and most small companies publish no accounts; those fields are `null` or empty.
- **Head office only.** Address and coordinates are those of the *siège*. Other establishments are counted (`nombreEtablissements`) but not listed.
- **Personal data.** Officer names are public register data. Use them in line with the GDPR and French rules on prospecting (CNIL); for marketing to individuals you need a lawful basis. Sole-trader company names can be a person's name.
- **Rate limits.** The API allows about 7 requests per second; this Actor sends about 2 to 3, one at a time, and retries 429 and 5xx responses with backoff. If the API stays unavailable the run fails with a clear message and nothing is charged. A run stops reading after 10 minutes and says so.

### Use it from your code, Make, Zapier or n8n

Built for automated pipelines: small runs, stable field names, one row per item, and you pay only for rows actually delivered.

**One API call that runs the Actor and returns the data** (replace `$APIFY_TOKEN` with your token from Apify Console → Settings → Integrations):

```bash
curl -s -X POST "https://api.apify.com/v2/acts/lukehunter~france-company-leads/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"activitePrincipale": ["56.10A"], "departement": "75", "maxItems": 20}'
```

**JavaScript** (`npm i apify-client`):

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('lukehunter~france-company-leads').call({
  "activitePrincipale": [
    "56.10A"
  ],
  "departement": "75",
  "maxItems": 20
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

**Python** (`pip install apify-client`):

```python
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('lukehunter~france-company-leads').call(run_input={"activitePrincipale": ["56.10A"], "departement": "75", "maxItems": 20})
items = client.dataset(run['defaultDatasetId']).list_items().items
```

**Schedules, webhooks and no-code tools:** save your input as a Task, add a Schedule (e.g. hourly or daily), and attach a webhook or one of the Integrations tab's connectors (Make, Zapier, n8n, Google Sheets, Slack) to push each run's results into your own system.

**Only new items each run:** set `"onlyNewSinceLastRun": true` on a scheduled Task and every run after the first delivers, and charges for, only items it hasn't delivered before for that same input. That makes it a ready-made change feed.

**Feedback:** an honest rating on the Store page, good or bad, helps others decide if this Actor fits their needs. Missing a field or found a problem? Open an issue on the Actor page.

### FAQ

**Is this the official Sirene API?** It reads the official Recherche d'entreprises API, which is built on the Sirene register of INSEE and the national company registers. It is free and keyless; this Actor adds filtering, creation-date search, new-since-last-run, alerts and flat rows.

**What is the difference between SIREN and SIRET?** SIREN (9 digits) identifies the company; SIRET (14 digits) identifies one establishment. The row's `siret` is the head office's.

**What is a NAF/APE code?** The French activity classification. `56.10A` is traditional restaurants, `62.01Z` software programming, `47.11B` convenience stores, `69.20Z` accounting. Enter codes in `NN.NNL` form.

**Why is a company I know missing?** Check that it is active (`etatAdministratif`), that its head office is in your département or postal code, whether a headcount band or creation date filter excluded it, and whether it is non-diffusible.

**Can I get new French companies in Slack every morning?** Yes: set `createdWithinDays`, `onlyNewSinceLastRun`, add a Slack destination and a daily Schedule. See the recipes above.

**Does it contact companies or people?** No. It only reads the register and reports.

### Related Actors

Other data tools from the same developer, built to the same standard: official or public sources, hard cost caps, and honest documentation of limits.

- **[Website Contact Scraper](https://apify.com/lukehunter/company-contact-scraper)**: emails, phone numbers and social profile links from any list of company domains, with the page each came from and a changed-contacts-only mode for scheduled runs.
- **[Impressum Scraper](https://apify.com/lukehunter/company-imprint-scraper)**: legal entity data from the imprint of any company website in Germany, Austria and Switzerland: legal name and form, managing directors, HRB/HRA or FN register, VAT id and address, with a changed-data-only mode for scheduled runs.
- **[Website Tech Stack Detector](https://apify.com/lukehunter/website-tech-stack-detector)**: the technologies a website runs (CMS, ecommerce platform, analytics, ad pixels, chat, payments, CDN, frameworks) from its home page, with the evidence for each match and a changed-technologies-only mode for scheduled runs.
- **[Google Maps Email Extractor & Lead Enricher](https://apify.com/lukehunter/lead-enricher)**: emails, phones, social links, named people and the tech stack of every business in your Google Maps Scraper results, one enriched row per business, with filters such as only Shopify stores with an email.
- **[Federal Register Rule Effective-Date Radar](https://apify.com/lukehunter/federal-rule-effective-date-radar)**: final federal rules about to take effect, with citations, dockets and urgency.
- **[UK Tenders Monitor](https://apify.com/lukehunter/uk-tenders-monitor)**: new UK public-sector tenders from Contracts Finder and Find a Tender, filtered by CPV code, value, region and buyer, with Slack, Discord and Telegram alerts.
- **[Chicago Contract Recompete & Extension Radar](https://apify.com/lukehunter/chicago-contract-expiration-radar)**: expiring City of Chicago contracts with extension history, for recompete prospecting.
- **[Bank Branch Closings & Merger Radar (FDIC)](https://apify.com/lukehunter/bank-branch-merger-radar)**: new US bank branch closings, openings and mergers from the FDIC.

# Actor input Schema

## `q` (type: `string`):

Free-text search on company name, officer name or address, e.g. boulangerie or Dupont. Optional when another filter is set. Combine with NAF code and location to narrow results.

## `activitePrincipale` (type: `array`):

NAF (APE) activity codes, format NN.NNL, e.g. \["56.10A", "62.01Z"]. 56.10A = restaurants, 62.01Z = software programming. A malformed code stops the run with an error. Leave empty for any activity.

## `departement` (type: `string`):

Département code, e.g. 75 (Paris), 69 (Rhône), 2A or 971. Several can be separated by commas, e.g. 75,92,93,94. Matches the registered head office (siège). Leave empty for all of France.

## `region` (type: `string`):

INSEE region code, e.g. 11 (Île-de-France), 84 (Auvergne-Rhône-Alpes), 93 (Provence-Alpes-Côte d'Azur), 76 (Occitanie). Commas separate several. Leave empty for any region.

## `codePostal` (type: `string`):

5-digit postal code of the head office, e.g. 75011, or several separated by commas, e.g. 69001,69002. Leave empty for any postal code.

## `trancheEffectif` (type: `array`):

Employee headcount bands as codes or ranges, e.g. \["11", "12"] or \["10-19", "20-49"]. Codes: 01 = 1-2, 02 = 3-5, 03 = 6-9, 11 = 10-19, 12 = 20-49, 21 = 50-99, 22 = 100-199, 32 = 250-499, 53 = 10,000+. Many companies declare none. Leave empty for any size.

## `categorieEntreprise` (type: `array`):

Official size category, e.g. \["PME"]. PME = small and medium enterprise, ETI = mid-cap, GE = large enterprise. Leave empty for all categories.

## `etatAdministratif` (type: `string`):

A = active companies (default, e.g. for lead lists), C = ceased companies, all = both. Choose all only for research on closed businesses.

## `natureJuridique` (type: `string`):

4-digit INSEE legal category code, e.g. 5710 (SAS), 5499 (SARL), 1000 (sole trader / entrepreneur individuel), 9220 (association). Commas separate several, e.g. 5710,5499. Leave empty for any legal form.

## `createdWithinDays` (type: `integer`):

Only companies registered in the last N days, 1 to 3650, e.g. 30 for the past month. Applied on dateCreation after download, because the API has no such filter. Ignored when Created after is set. Broad filters read more pages.

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

Only companies registered on or after this day, written YYYY-MM-DD, e.g. 2026-09-01. Overrides Created within days. Applied on dateCreation after download, so combine with department, NAF code or postal code to keep the query narrow.

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

Hard cap on delivered companies, 1 to 5000, e.g. 50. At $0.004 per delivered company this caps the result charge (50 companies = $0.20). The API itself exposes at most 10,000 results per query.

## `onlyNewSinceLastRun` (type: `boolean`):

Deliver and charge only companies not delivered before for this same set of filters, e.g. on a daily Schedule with Created within days. The first run creates the baseline and delivers what matches now. Pair with a Slack or Discord destination below.

## `stateStoreName` (type: `string`):

Named key-value store that remembers delivered companies between runs, used only when alerts are on. Example: my-paris-restaurants. Use a different name to keep separate histories. Letters, numbers and hyphens only.

## `discordWebhookUrl` (type: `string`):

Post results to a Discord channel. In Discord: Server Settings -> Integrations -> Webhooks -> New Webhook -> choose the channel -> Copy Webhook URL. Example: https://discord.com/api/webhooks/<id>/<token>. Leave empty to skip Discord.

## `telegramBotToken` (type: `string`):

Post results to Telegram. Create a bot by chatting with @BotFather on Telegram (send /newbot) and paste the token it gives you, e.g. 123456789:AA.... Needs "Telegram chat ID" below. Leave empty to skip Telegram.

## `telegramChatId` (type: `string`):

Where the bot should post: a numeric chat id (e.g. 123456789, or -1001234567890 for a group or channel) or a public @channelusername. The bot must be added to that chat or channel first (as an administrator for a channel), and for a private chat you must press Start on the bot. Needs "Telegram bot token" above.

## `slackWebhookUrl` (type: `string`):

Post results to a Slack channel (Block Kit cards, up to 10 per message). Create an incoming webhook at api.slack.com/apps -> Create New App -> Incoming Webhooks -> Add New Webhook to Workspace. Example: https://hooks.slack.com/services/T000/B000/XXXX. Leave empty to skip Slack.

## `slackCompatibleWebhookUrl` (type: `string`):

Post results to a Mattermost or Rocket.Chat incoming webhook, which accept Slack-style webhook payloads. Must be a public https:// address, e.g. https://chat.example.com/hooks/abc123 (no localhost, private IP or .local/.internal hosts). These apps do not render Slack Block Kit, so they get a plain Markdown list. For real Slack use "Slack webhook URL" above. Leave empty to skip.

## `teamsWebhookUrl` (type: `string`):

Post results to a Teams channel as an Adaptive Card. In Teams: channel -> ... -> Workflows -> "Post to a channel when a webhook request is received" -> copy the URL. The host must end in .logic.azure.com or .powerplatform.com, e.g. https://prod-12.westeurope.logic.azure.com/workflows/... The retired Office 365 connector webhooks are not supported. Leave empty to skip Teams.

## `googleChatWebhookUrl` (type: `string`):

Post results to a Google Chat space. In the space: Apps & integrations -> Webhooks -> Add webhook -> copy the URL. Example: https://chat.googleapis.com/v1/spaces/<space>/messages?key=...\&token=.... Leave empty to skip Google Chat.

## `ntfyTopic` (type: `string`):

Get a phone push with no account via ntfy (ntfy.sh). Install the ntfy app, subscribe to a topic name, and enter the same name here. Anyone who knows the topic can read it, so pick a long, unguessable name (letters, numbers, - and \_), e.g. acme-leads-7k2x9q. At most 10 individual pushes per run, then one "...and N more". Leave empty to skip ntfy.

## `ntfyServer` (type: `string`):

Only used with "ntfy topic". Leave as https://ntfy.sh, or enter the public https:// address of your own ntfy server, e.g. https://ntfy.example.com.

## `ntfyToken` (type: `string`):

Only used with "ntfy topic", for a self-hosted server or a reserved topic that needs a login. An access token from ntfy (starts with tk\_, e.g. tk_abc123...). Leave empty for open topics.

## `pushoverUserKey` (type: `string`):

Get a phone push via Pushover. Your user key (30 characters, e.g. uQiRzpo4DXghDmr9QzzfQu27cmVRsG) is shown on the Pushover dashboard (pushover.net). Needs "Pushover app token" below. At most 10 individual pushes per run, then one "...and N more". Leave empty to skip Pushover.

## `pushoverAppToken` (type: `string`):

The API token of a Pushover application you create at pushover.net/apps/build (name it after this Actor), e.g. azGDORePK8gMaC0QOYAMyEEuzJnyUi. Needs "Pushover user key" above.

## `webhookUrl` (type: `string`):

POST the delivered rows as JSON to any public https:// URL: {source, actor, runId, count, items}. At most 100 rows per POST; every delivered row is sent regardless of the max-notifications cap. For example, route results to email, a spreadsheet or any app. Localhost, private IP and .local/.internal addresses are rejected. Leave empty to skip.

## `maxNotifications` (type: `integer`):

Caps how many results are sent to chat and phone channels per run (Discord, Telegram, Slack, Teams, Google Chat, ntfy, Pushover), 1-100, default 25 (e.g. 10). Extra results are still in the dataset. The generic webhook is not capped. Only used when a destination above is set.

## Actor input object example

```json
{
  "activitePrincipale": [
    "56.10A"
  ],
  "departement": "75",
  "etatAdministratif": "A",
  "maxItems": 20,
  "onlyNewSinceLastRun": false,
  "stateStoreName": "france-company-leads-seen-companies",
  "ntfyServer": "https://ntfy.sh",
  "maxNotifications": 25
}
```

# Actor output Schema

## `companies` (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 = {
    "activitePrincipale": [
        "56.10A"
    ],
    "departement": "75",
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("lukehunter/french-companies-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 = {
    "activitePrincipale": ["56.10A"],
    "departement": "75",
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("lukehunter/french-companies-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 '{
  "activitePrincipale": [
    "56.10A"
  ],
  "departement": "75",
  "maxItems": 20
}' |
apify call lukehunter/french-companies-sirene --silent --output-dataset

```

## MCP server setup

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