# France Companies Likely to Hire: La Bonne Boite Leads (`datacraft-studio/france-companies-likely-to-hire`) Actor

Find French companies most likely to hire in the next 6 months, by job, NAF code and area. Official France Travail La Bonne Boite data: SIRET, size, sector, hiring score, plus a free labour market tension score (1-5). Pay per company.

- **URL**: https://apify.com/datacraft-studio/france-companies-likely-to-hire.md
- **Developed by:** [Yahya Nouali](https://apify.com/datacraft-studio) (community)
- **Categories:** Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$5.00 / 1,000 company likely to hires

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

## France Companies Likely to Hire: La Bonne Boite Leads

Find the French companies **most likely to hire in the next 6 months** for a given job, in a given area. Data comes from **La Bonne Boite**, the official France Travail service that scores every establishment on its hiring potential from past hiring (DPAE declarations) and its sector trends.

Search by job in plain French words (`développeur`, `plombier`, `aide-soignant`), by ROME job code or by NAF activity code, in departments, regions, cities or postcodes. Every row has the SIRET, company name, NAF activity, headcount band, hiring score, matched jobs, address area and GPS position, plus a **labour market tension score**: how hard it is to recruit for that job in that department (1 = very low to 5 = very high), with the reasons behind it. You pay **$0.005 per company delivered**, nothing for filtered or repeated companies.

No France Travail account is needed: the Actor uses its own API access. You can also plug in your own free francetravail.io credentials.

### New: labour market tension score (free)

For job searches (`jobKeywords` or `romeCodes`), each company also gets the official **recruitment difficulty indicator** built by France Travail and DARES for its matched job in its department, from the France Travail **Marché du travail** API. It is on by default (`addLabourMarketTension`) and costs nothing extra.

- `tensionScore` 1 to 5 and `tensionLabel` (`very low` ... `very high`). When a company matches several jobs, the highest tension wins; `tensionByJob` lists them all.
- `tensionDrivers`: the 7 factors behind it, each 1 (lowers tension) to 5 (raises tension): `hiringIntensity`, `labourShortage`, `workingConditions`, `jobNonDurability`, `trainingJobLink`, `geographicMismatch`, `wageAttractiveness`.
- `tensionPeriod` (reference year), `tensionDataDate` (France Travail update date), `tensionSource` and `tensionLicence` on every row.

Why it matters: a company with a high hiring score **and** a high tension score is likely to hire and likely to struggle to find candidates. That is the best moment to offer recruitment, staffing, training or HR services. Tension fields are `null` for NAF-only searches and check mode (the indicator exists per job, not per sector), and when France Travail has no figure for a job and department.

### Use cases

- **Recruiters and staffing agencies:** find employers likely to hire developers, nurses or drivers in your area before they post an offer.
- **Sales and business development:** target companies that are growing (payroll, HR software, training, recruitment, workwear, mutuelles).
- **Job seekers and career coaches:** build a shortlist for spontaneous applications. `acceptsSpontaneousApplications` shows where France Travail holds a contact.
- **Check mode:** score a list of SIRETs from your CRM for hiring potential.

### Input

| Field | Example | Notes |
| --- | --- | --- |
| `jobKeywords` | `["développeur", "comptable"]` | Matched to official ROME job codes. The match is shown in the run summary (`resolvedKeywords`). |
| `romeCodes` | `["M1805", "J1501"]` | Exact ROME codes. |
| `nafCodes` | `["6202A", "43.22A"]` | Company activity codes. Searched separately from jobs. |
| `departments` | `["69", "2A", "974"]` or `["ALL"]` | `ALL` = whole of France. |
| `regions` | `["84"]` | INSEE region codes. |
| `cityCodes` / `postcodes` | `["33063"]` / `["44000"]` | With `distanceKm` (default 10, max 100). Paris, Lyon and Marseille use district codes (75101, 69381, 13201). |
| `sirets` | `["53337361900113"]` | Check mode: returns the hiring score of each listed establishment. |
| `minHeadcount` | `10` | Keeps companies whose headcount band reaches this size. |
| `onlyHighPotential` / `minHiringPotential` | `true` / `60` | Score filters. |
| `maxItems` | `200` | Hard cap on delivered and charged companies. Best scores first. |
| `addLabourMarketTension` | `true` | Default `true`. Adds the free tension score per job and department. `maxTensionLookups` (default 300) caps the lookups. |
| `onlyNew` + `stateStoreName` | `true` | For scheduled runs: only companies never delivered before are pushed and charged. |
| `franceTravailClientId` / `franceTravailClientSecret` | | Optional, secret fields. See below. |

A search needs at least one job (`jobKeywords`, `romeCodes` or `nafCodes`) and one location. Example: [examples/input.json](examples/input.json).

```json
{ "jobKeywords": ["développeur"], "departments": ["69"], "cityCodes": ["33063"], "minHeadcount": 10, "maxItems": 50 }
```

### Output

One row per establishment (merged across jobs when it matches several), sorted by high potential, then score. A `run_summary` row comes last.

```json
{
  "recordType": "company",
  "siret": "34503824400017",
  "siren": "345038244",
  "companyName": "INSAVALOR",
  "nafCode": "7219Z",
  "nafLabel": "Recherche-développement en autres sciences physiques et naturelles",
  "headcountRange": "100-199",
  "hiringPotential": 67.22,
  "isHighPotential": false,
  "matchedRomeCodes": ["H1206"],
  "matchedRomeLabels": ["Ingénieur / Ingénieure R&D en industrie"],
  "acceptsSpontaneousApplications": true,
  "city": "Villeurbanne",
  "postcode": "69100",
  "departmentNumber": "69",
  "region": "Auvergne-Rhône-Alpes",
  "latitude": 45.7865,
  "longitude": 4.88068,
  "companyUrl": "https://annuaire-entreprises.data.gouv.fr/etablissement/34503824400017",
  "source": "France Travail - La Bonne Boite API v2",
  "sourceLicence": "Licence Ouverte / Etalab 2.0 (France Travail)",
  "retrievedAt": "2026-10-26T08:12:15.299Z",
  "tensionScore": 4,
  "tensionLabel": "high",
  "tensionRomeCode": "H1206",
  "tensionDepartment": "69",
  "tensionDrivers": { "hiringIntensity": 3, "labourShortage": 4, "workingConditions": 1, "jobNonDurability": 1, "trainingJobLink": 5, "geographicMismatch": 3, "wageAttractiveness": 2 },
  "tensionByJob": [{ "romeCode": "H1206", "score": 4, "label": "high" }],
  "tensionPeriod": "2025",
  "tensionDataDate": "2026-09-23",
  "tensionSource": "France Travail - Marché du travail API (Data Emploi, DARES / France Travail recruitment difficulty indicator)",
  "tensionLicence": "Licence Ouverte / Etalab 2.0 (France Travail)"
}
```

La Bonne Boite does not publish e-mails or phone numbers. Use `siret` with an enrichment Actor or `companyUrl` for the public company record.

### Pricing

Pay per event: **$0.005 per company delivered** ($5 per 1,000). The tension score is included at no extra cost. Not charged: companies removed by filters, companies already delivered when `onlyNew` is on, the run summary. Set `maxItems` or a maximum cost per run to control spend; the Actor stops cleanly when the limit is reached.

### Your own France Travail credentials (optional)

The Actor works out of the box. If you prefer your own API quota, create a free application on [francetravail.io](https://francetravail.io), subscribe it to **La Bonne Boite v2** and **ROME 4.0 - Métiers** (and **Marché du travail** for the tension score), and paste the client ID and secret in the two optional fields. Both are secret input fields: Apify stores them encrypted, and the Actor never logs them or writes them to the output.

### Schedule it

Create an Apify schedule (for example every Monday at 07:00) with `onlyNew: true` and a dedicated `stateStoreName`. Each run delivers only the companies that newly appear in La Bonne Boite for your search.

### Automate with Make, Zapier or n8n

Put the **Apify token** in the integration credentials, never in the Actor input.

#### Make

App **Apify**, module **Run an Actor and Get Dataset**.

1. Scheduled scenario, every Monday.
2. **Run an Actor and Get Dataset**, Actor `france-companies-likely-to-hire`, input from [examples/input.json](examples/input.json).
3. Filter: `recordType` = `company`.
4. Add rows to Google Sheets or create companies in HubSpot/Pipedrive with `siret`, `companyName`, `city`, `hiringPotential`.

#### Zapier

App **Apify**.

1. Trigger: Schedule by Zapier, weekly.
2. Action: **Run Actor** with the JSON input, wait for finish.
3. Action: **Get Dataset Items**, then Filter by Zapier: `recordType` is `company`.
4. Action: Google Sheets, a CRM or Slack.

#### n8n

Official node [`@apify/n8n-nodes-apify`](https://docs.apify.com/platform/integrations/n8n). Resource **Actors**, operation **Run an Actor and Get Dataset**. Choose your Apify credential, set the Actor to `france-companies-likely-to-hire`, paste the JSON input, then add an IF node on `recordType` = `company` before Google Sheets, a CRM or email.

### Source and licence

Data: **France Travail, La Bonne Boite API v2** ([francetravail.io](https://francetravail.io/produits-partages/catalogue/la-bonne-boite-v2)), open access under the **Licence Ouverte / Etalab 2.0**. Each row carries its source and its retrieval date (`retrievedAt`).

Tension score: **France Travail, Marché du travail API** ([francetravail.io](https://francetravail.io/produits-partages/catalogue/marche-travail), Data Emploi; indicator built by France Travail and DARES from France Travail, ACOSS, CCMSA and DARES data), open access under the **Licence Ouverte / Etalab 2.0**. Each row carries `tensionSource`, `tensionPeriod` and the France Travail data date `tensionDataDate` (latest release: 2025 figures, updated 23 September 2026). Hiring scores are statistical estimates made by France Travail, not job offers or commitments to hire. This Actor is independent and is not endorsed by France Travail. It does not use the restricted "Offres d'emploi" API.

### En français

Cet Actor trouve les **entreprises françaises qui vont probablement recruter dans les 6 prochains mois**, à partir de **La Bonne Boite** (France Travail). Cherchez par métier en mots simples (`développeur`, `plombier`), code ROME ou code NAF, dans des départements, régions, villes ou codes postaux. Chaque ligne contient le SIRET, la raison sociale, l'activité NAF, la tranche d'effectif, le score de potentiel d'embauche et les métiers concernés, ainsi qu'un **indicateur de tension du marché du travail** gratuit (difficulté de recrutement de 1 à 5 pour le métier dans le département, avec ses 7 facteurs, source France Travail / DARES, API Marché du travail). Mode vérification : donnez une liste de SIRET pour obtenir leur potentiel d'embauche. **0,005 $ par entreprise livrée**, rien pour les entreprises filtrées ou déjà livrées (`onlyNew`). Aucun compte France Travail n'est nécessaire ; vous pouvez aussi saisir vos propres identifiants francetravail.io (champs secrets, chiffrés). Sources : France Travail, La Bonne Boite et Marché du travail, Licence Ouverte Etalab 2.0 (date des données dans `retrievedAt` et `tensionDataDate`). Actor indépendant, non approuvé par France Travail.

### Local development

```bash
npm install
npm test
FRANCE_TRAVAIL_CLIENT_ID=... FRANCE_TRAVAIL_CLIENT_SECRET=... npm start
```

# Changelog

This Actor's version history is a separate document: https://apify.com/datacraft-studio/france-companies-likely-to-hire/changelog.md

# Actor input Schema

## `jobKeywords` (type: `array`):

Job titles in French, e.g. "développeur", "plombier", "aide-soignant". Each is matched to official ROME job codes (shown in the run summary). Accents and case do not matter.

## `romeCodes` (type: `array`):

Official ROME codes such as M1805 (software developer), D1102 (baker), J1501 (care assistant). Use this for exact control.

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

5-character NAF codes of the companies, e.g. 6202A or 62.02A. Searched separately from jobs.

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

Department codes such as 75, 69, 2A, 974. Use ALL for the whole of France.

## `regions` (type: `array`):

INSEE region codes: 11 Ile-de-France, 84 Auvergne-Rhone-Alpes, 93 Provence-Alpes-Cote d'Azur, 75 Nouvelle-Aquitaine, 76 Occitanie, 32 Hauts-de-France, 44 Grand Est, 52 Pays de la Loire, 53 Bretagne, 28 Normandie, 27 Bourgogne-Franche-Comte, 24 Centre-Val de Loire, 94 Corse.

## `cityCodes` (type: `array`):

INSEE city codes, searched with the radius below. Paris, Lyon and Marseille use district codes (75101, 69381, 13201).

## `postcodes` (type: `array`):

5-digit postcodes, searched with the radius below.

## `distanceKm` (type: `integer`):

Radius around each city or postcode.

## `sirets` (type: `array`):

Check mode: 14-digit SIRETs of establishments. Returns their hiring potential score when La Bonne Boite lists them.

## `minHeadcount` (type: `integer`):

Keep only establishments whose headcount band reaches at least this number of employees. Companies with unknown headcount are dropped when set.

## `onlyHighPotential` (type: `boolean`):

Keep only establishments flagged by France Travail as high hiring potential.

## `minHiringPotential` (type: `integer`):

Keep only establishments with a hiring potential score at least this high.

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

Hard cap on delivered (and charged) companies. Best scores first.

## `maxResultsPerQuery` (type: `integer`):

Each job batch x location is one query. Raise this for large areas when you want more than the best few hundred companies.

## `onlyNew` (type: `boolean`):

For scheduled runs: skip (and do not charge) SIRETs delivered by an earlier run that used the same state store.

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

Named key-value store that remembers delivered SIRETs when onlyNew is on. Use one per search profile.

## `addLabourMarketTension` (type: `boolean`):

Adds, for each company, how hard it is to recruit for its matched job in its department (1 = very low to 5 = very high), with the 7 drivers behind it. Official France Travail / DARES indicator from the Marché du travail API. Free: no extra charge.

## `maxTensionLookups` (type: `integer`):

Cap on job x department lookups for the tension score. Companies beyond the cap get null tension fields.

## `franceTravailClientId` (type: `string`):

Optional. The Actor works without it. Add your own free francetravail.io application credentials (subscribed to La Bonne Boite v2, ROME 4.0 - Metiers and, for the tension score, Marché du travail) if you want your own API quota.

## `franceTravailClientSecret` (type: `string`):

Optional, goes with the client ID. Stored encrypted by Apify and never logged or written to the output.

## Actor input object example

```json
{
  "jobKeywords": [
    "développeur"
  ],
  "departments": [
    "69"
  ],
  "distanceKm": 10,
  "minHeadcount": 0,
  "onlyHighPotential": false,
  "maxItems": 200,
  "maxResultsPerQuery": 1000,
  "onlyNew": false,
  "stateStoreName": "france-likely-to-hire-state",
  "addLabourMarketTension": true,
  "maxTensionLookups": 300
}
```

# Actor output Schema

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

One row per company, best hiring score first, then a run summary.

## `summary` (type: `string`):

Matched ROME codes, counts, filters and price.

# 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 = {
    "jobKeywords": [
        "développeur"
    ],
    "departments": [
        "69"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("datacraft-studio/france-companies-likely-to-hire").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 = {
    "jobKeywords": ["développeur"],
    "departments": ["69"],
}

# Run the Actor and wait for it to finish
run = client.actor("datacraft-studio/france-companies-likely-to-hire").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 '{
  "jobKeywords": [
    "développeur"
  ],
  "departments": [
    "69"
  ]
}' |
apify call datacraft-studio/france-companies-likely-to-hire --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datacraft-studio/france-companies-likely-to-hire"
        }
    }
}
```

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/hDNM9gkU0fchJnAMR/builds/HZwjjMvCLv8wWFXuf/openapi.json
