# BODACC Monitor — French Insolvencies, Company Formations and (`dalbian/bodacc-french-company-notices`) Actor

Watch the BODACC, the French official bulletin of civil and commercial legal announcements. Insolvency rulings with their procedure type and date, company formations, sales of businesses with the stated price, amendments, strike-offs and accounts filings — filtered by SIREN, department.

- **URL**: https://apify.com/dalbian/bodacc-french-company-notices.md
- **Developed by:** [Benjamin Jerez](https://apify.com/dalbian) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $40.00 / 1,000 search runs

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

## BODACC Monitor — French Insolvencies, Company Formations and Business Sales

Every legal event in the life of a French business is published in the **BODACC**, the Bulletin officiel des annonces civiles et commerciales: a company is formed, its officers change, it is sold, a court opens insolvency proceedings against it, it files its accounts, it is struck off. The registries of the commercial courts send the notices, DILA publishes them, and nothing happens to a registered French company without appearing there.

This Actor queries the register live and returns the notices flattened into columns you can sort on.

**50 704 155 notices**, from 2 January 2008 to yesterday. 4 034 475 of them in the last twelve months, of which 206 852 were insolvency proceedings.

### The problem this solves

The register is served as JSON, but six of its fields — the six that carry everything worth having — are not JSON objects. They are **strings containing JSON**. The SIREN, the legal form, the stated activity, the court ruling and its date, the sale price, the accounts year: all of it is locked inside `listepersonnes`, `jugement`, `acte`, `depot`, `modificationsgenerales` and `listeetablissements` as escaped text.

This Actor parses them and lifts the values into flat columns. A notice comes back as `siren`, `legalForm`, `rulingType`, `rulingDate`, `salePrice` — not as a wall of backslashes.

### What an insolvency notice returns

A liquidation opened on 14 September 2026, published four days later:

| Field | Value |
| --- | --- |
| `companyName`, `siren` | SMAG · 429982648 |
| `legalForm` | Société à Responsabilité Limitée |
| `activity` | vente et distribution de produits de boulangerie, vente de matériel agroalimentaire |
| `procedureType` | `openingLiquidation` |
| `rulingType` | Jugement d'ouverture de liquidation judiciaire |
| `rulingDate` | 2026-09-14 |
| `cessationOfPaymentsDate` | 2025-03-14 |
| `court`, `department` | Tribunal Mixte de Commerce de Saint-Denis de la Réunion · 974 |
| `rulingDetail` | the full ruling, naming the liquidator and the deadline for filing claims |

`cessationOfPaymentsDate` is the date the court found the company had stopped paying its debts — the start of the période suspecte, during which transactions can be unwound. It is not a field in the register; it is written into the ruling text and pulled out here. On a 1 500-notice sample of liquidation openings, 1 256 mentioned it and all 1 256 parsed.

### What a business sale returns

| Field | Value |
| --- | --- |
| `companyName` → `previousOwner` | Learine ← HEPAB |
| `salePrice`, `saleCurrency` | 140000.0 · EUR |
| `saleCategory` | Achat d'un fonds par une personne morale (insertion provisoire) |
| `establishmentActivity` | café bar restaurant |
| `establishmentAddress` | 38 Rue Guy Moquet 92240 Malakoff |
| `oppositionTerms` | where creditors must object, and within how many days |
| `deedDescription` | the deed, its date and its registration reference |

The price is not a field either. It is a sentence — *"acquis par achat au prix stipulé de 140000.00 euros"* — and the register writes the same number four different ways, `80000.00`, `140000,00`, `290302` and `1 000 000,00`, in the same place. All four are normalised. On a run of 30 sales filtered to bakeries and restaurants, 30 of 30 carried a price.

### What an accounts filing returns

`companyName` GOOGLE FRANCE, `siren` 443061841, `filingType` Comptes annuels et rapports, `filingCloseDate` 2025-12-31, `filingYear` 2025, published 31 August 2026. Where the company filed a confidentiality declaration under article L. 232-25, `filingNote` says so — which is how you find out the accounts exist but are not public.

### The ten notice families

Pick them by name; the Actor maps them to the register's own codes. Counts are the whole register.

| Input value | Register family | Notices |
| --- | --- | --- |
| `accountsFilings` | Dépôts des comptes | 26 405 507 |
| `amendments` | Modifications diverses | 8 521 563 |
| `companyFormations` | Créations | 6 585 407 |
| `deregistrations` | Radiations | 4 224 912 |
| `insolvency` | Procédures collectives | 3 336 372 |
| `salesAndTransfers` | Ventes et cessions | 891 516 |
| `registrations` | Immatriculations | 727 914 |
| `miscellaneous` | Annonces diverses | 4 963 |
| `conciliation` | Procédures de conciliation | 4 312 |
| `professionalRecovery` | Procédures de rétablissement professionnel | 1 281 |

A further 408 notices carry no usable family code and are returned under `inconnue` when no family filter is set.

Accounts filings are half the bulletin. A run with no family filter is mostly them.

### Insolvency ruling types

The register does not expose the procedure as a field — it is a sentence inside the ruling. Ten readable types are offered: liquidation opened, receivership opened, safeguard opened, converted to liquidation, recovery plan approved, business sold as a going concern, plan failed, proceedings closed, director sanctioned, creditor claims filed.

The Actor narrows the query on the bulletin text and then checks the parsed ruling nature on every row, because the text filter also fires on rulings that merely *mention* the phrase. The summary row reports how many rows that check dropped: 7 of 200 on a creditor-claims run, 0 of 100 on an insolvency-openings run.

### Watching specific companies

Put SIRENs in `sirens`, one per line. Spaces are ignored and a fourteen-digit SIRET is cut back to its SIREN, because the register stores both the spaced and the unspaced spelling and neither matches a SIRET.

A notice matches if the company appears in it **in any role**. Searching Orange's SIREN returns the sale in which Orange was the seller, with `companyName` on the buyer and `allSirens` listing both parties. Checked against companies whose registration you can verify yourself: 652014051 returns CARREFOUR at Massy, 443061841 returns GOOGLE FRANCE at 8 rue de Londres, 542107651 returns ENGIE.

### Who uses this

Credit insurers and factoring companies watching their book for the first sign of a redressement judiciaire. Insolvency practitioners and restructuring lawyers tracking openings by court and by department. B2B sales teams working new company formations as a lead list. M\&A and search funds pricing small businesses off the fonds de commerce sales that clear at 7 000 to 300 000 euros. Suppliers running a nightly check on their customer SIRENs. Data vendors and KYC platforms keeping a French company file current between INSEE refreshes.

### Scope and limits

**10 000 rows per query.** The API refuses any request past that point for one set of filters. The Actor stops there rather than returning a quietly truncated set, and the summary row carries `offsetLimitReached` and a note saying how to split the work. A three-day window over accounts filings alone matched 21 781 notices and returned the first 10 000 in 64 seconds; narrowing by department or shortening the window gets the rest.

**Working days only.** The BODACC does not publish at weekends or on public holidays. A one-day window run on a Sunday legitimately returns nothing, and the summary row says so rather than leaving you wondering whether the run failed.

**No PDF link.** Every notice carries `noticeUrl`, the official BODACC page for it, plus `bulletinSeries`, `bulletinIssue` and `noticeNumber` — the three coordinates that identify the notice in the printed bulletin. A direct PDF URL is not published in the dataset and is not invented here.

**Corrections are separate notices.** A `rectificatif` or an `annulation` is its own record, carrying `correctsIssue`, `correctsDate` and `correctsNoticeNumber` pointing at what it fixes; it does not rewrite the original. If you are building an alert, set `noticeTypes` to initial notices only, otherwise a cancellation of a 2022 notice will land in today's batch — which is exactly what happened in testing.

**A notice is a publication, not a state.** Three notices about the same company on the same day are three rows: the conversion to liquidation, the plan de cession, and the resumption of proceedings are separate rulings. The register is a chronicle, and this Actor returns it as one.

### Source and licence

**DILA** — Direction de l'information légale et administrative — through the Opendatasoft Explore v2.1 API at `bodacc-datadila.opendatasoft.com`, the same data DILA also publishes in bulk at `echanges.dila.gouv.fr/OPENDATA/BODACC/`. French public open data under the Licence Ouverte. Free, no key, queried live on every run.

### Frequently asked

**Why is `siren` sometimes missing?**
Because the notice concerns a party with no RCS registration — a sole trader registered only with the chambre de métiers, or an entity named in a court notice. Where an artisan number exists the Actor uses it, since it is the same nine digits.

**Why does a field not appear on a row?**
Because that family of notice does not have it. An accounts filing has no ruling; an insolvency notice has no sale price. Empty fields are dropped rather than returned as blanks, so each row carries only what the notice actually said.

**Can I filter by activity or sector?**
Use `keywords`. They are searched across the name, the stated activity, the ruling and the deed. Note that this search stems words, so *boulangerie* also matches *boulanger*. The family, department, SIREN, name and court filters are literal and do not stem.

**How far back does it go?**
2 January 2008. Leave `publishedWithinDays` blank to search the whole register, subject to the 10 000-row ceiling on any one query.

**Is this the same as the company register?**
No. The RNE and INSEE tell you what a company *is* today. The BODACC tells you what *happened* to it, on the day it was published, with the court's own wording. For monitoring, the second is the one that has a date on it.

# Actor input Schema

## `publishedWithinDays` (type: `integer`):

Only notices published in the last N days. Set it to 1 and schedule the run each morning for a clean daily alert with nothing repeated. The BODACC publishes on working days only, so a one-day window over a weekend or a public holiday is empty by design. Leave it blank to search the whole register back to 2008.

## `noticeFamilies` (type: `array`):

Which families of notice to keep. Leave empty for all of them. The counts are the whole register, not your window. Accounts filings alone are half the bulletin, so a run with no family filter is dominated by them.

## `procedureTypes` (type: `array`):

Narrow insolvency notices to specific court rulings. The register does not expose the ruling type as a field, so the Actor filters the bulletin text and then verifies the parsed ruling nature on every row — the summary reports how many rows the verification dropped. Use this with the insolvency family.

## `noticeTypes` (type: `array`):

Leave empty for all. Choose initial notices only if you are building an alert and do not want a correction to a two-year-old notice landing in today's batch.

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

French department numbers, one per line — 75, 69, 13, 2A, 971. Single digits are padded for you, so 1 and 01 both mean Ain.

## `sirens` (type: `array`):

Watch specific companies, one nine-digit SIREN per line. Spaces are ignored and a fourteen-digit SIRET is cut back to its SIREN. A notice matches if the company appears in it in any role, including as the seller in a business sale.

## `companyNames` (type: `array`):

Keep only notices whose trading name contains these words, one per line. Matching is literal and ignores case and accents; a trailing asterisk works as a wildcard.

## `keywords` (type: `array`):

Free-text words searched across the name, the stated activity, the court ruling and the deed, one per line, combined with OR. Use this to watch a sector — boulangerie, pharmacie, transport — rather than a named company.

## `tribunals` (type: `array`):

Keep only notices from these registries, one per line — Bordeaux, Lyon, Nanterre. Matched against the court name as the bulletin writes it.

## `maxNotices` (type: `integer`):

Cap per run, newest first. The API will not page beyond 10 000 rows for one query; the summary row says so when that ceiling is reached.

## Actor input object example

```json
{
  "publishedWithinDays": 7,
  "noticeFamilies": [
    "insolvency"
  ],
  "procedureTypes": [],
  "noticeTypes": [],
  "maxNotices": 200
}
```

# Actor output Schema

# 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 = {
    "publishedWithinDays": 7,
    "noticeFamilies": [
        "insolvency"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("dalbian/bodacc-french-company-notices").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 = {
    "publishedWithinDays": 7,
    "noticeFamilies": ["insolvency"],
}

# Run the Actor and wait for it to finish
run = client.actor("dalbian/bodacc-french-company-notices").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 '{
  "publishedWithinDays": 7,
  "noticeFamilies": [
    "insolvency"
  ]
}' |
apify call dalbian/bodacc-french-company-notices --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dalbian/bodacc-french-company-notices"
        }
    }
}
```

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/MVjIoy6ZzOWYLKCtB/builds/dZGLXdxlxJ1KrnHED/openapi.json
