The timeline of a company: each change the register recorded about the legal entity or
one of its establishments, and each notice the legal gazette published about the legal
entity, as one event. source says where it comes from: sirene_daily or monthly_stock
for the register (INSEE Sirene), bodacc for the gazette (the BODACC). subject says
which record it is about: legal_entity with its registry number, or establishment with
its establishment number. A legal entity in the register with no event yet answers an empty
list. A registry number neither the register nor this log knows, an unknown country
included, is a 404 not_found, answered before the filters are read: an unknown number with
a malformed filter is a 404, not a 400.
removed is true when the legal entity is no longer in the register and this log records
its removal (legal_entity.removed_from_registry): its record answers 404 not_found, but
its timeline is still served, with the events recorded before and including its removal. It
is false for every entity still in the register, and for a registry number with no record
that this log knows only through other events — its establishments', or the gazette's
notices about it — with no removal recorded: nothing says it was removed. Branch on
removed rather than on a 404 from the record. A gazette's
legal_entity.struck_off is a different fact, removal from the trade register, and does
not set removed.
Events are ordered by occurred_on, newest first, then by id. occurred_on is the date
of the change in the source's own terms; recorded_at is when this API recorded it, and
can be weeks later — years, for the gazette's history. So an event recorded today can land
below events you have already read, not at the top: to pick up what is new, keep the ids
you have seen and skip them, rather than stopping at the first one you recognise. id is
unique per event.
The register's kinds:
kind | severity |
|---|---|
legal_entity.ceased | critical |
legal_entity.reactivated | critical |
legal_entity.disclosure_restricted | critical |
legal_entity.disclosure_lifted | critical |
legal_entity.renamed | notable |
legal_entity.legal_form_changed | notable |
legal_entity.activity_changed | notable |
legal_entity.head_office_moved | notable |
legal_entity.employer_status_changed | informational |
legal_entity.mission_or_ess_changed | informational |
legal_entity.workforce_changed | informational |
legal_entity.size_category_changed | informational |
legal_entity.removed_from_registry | notable |
establishment.opened | notable |
establishment.closed | notable, critical on the head office |
establishment.reopened | notable |
establishment.moved | notable |
establishment.became_head_office | notable |
establishment.renamed | informational |
establishment.activity_changed | informational |
establishment.removed_from_registry | notable |
The register has no creation kind for a legal entity: a new company appears as its first
establishment.opened. The contract types kind as a string, not an enum: treat one you
do not recognise as one to ignore.
On the register's events, payload depends on kind. A change of value carries the values
on either side as from and to; establishment.opened carries head_office instead, the
two disclosure kinds and legal_entity.removed_from_registry carry {},
establishment.removed_from_registry carries legal_entity_number alone, and every
establishment event carries legal_entity_number. The keys inside from and to are not
part of the published contract — payload is typed as an open object — so branch on
kind, and read the legal entity for the current value.
The gazette's kinds are about the legal entity only, never an establishment. The BODACC
publishes notices for companies in the trade register (RCS) alone, so an association or a
sole trader outside it has none of these events, and an empty answer for it says nothing
about its legal situation. Every one carries bulletin (A, B or C), published_on
(the bulletin's date) and url (the notice on the BODACC's site) in payload, plus the
keys below, and its source_ref is the notice's id, such as A202601882044. payload
stays an open object in the contract; these are the keys served today.
kind | severity | payload, beyond the three above |
|---|---|---|
legal_entity.insolvency.opened | critical | nature, procedure |
legal_entity.insolvency.converted | critical | nature, procedure (the new one) |
legal_entity.insolvency.plan_adopted | critical | nature, plan |
legal_entity.insolvency.closed | critical | nature, procedure when named, reason |
legal_entity.insolvency.reopened | critical | nature, procedure |
legal_entity.conciliation | critical | nature |
legal_entity.personal_recovery | critical | nature |
legal_entity.business_acquired | critical | counterparties (the sellers), category |
legal_entity.business_sold | critical | counterparties (the buyers), category |
legal_entity.struck_off | critical | reason |
legal_entity.registered | informational | origin, category, registered_on |
legal_entity.accounts_filed | informational, off by default | closing_on, accounts |
legal_entity.legal_notice_published | informational | family, and nature when there is a judgment |
procedure is safeguard, accelerated_safeguard, reorganisation (the French
redressement judiciaire), liquidation or crisis_exit; plan is reorganisation,
safeguard, sale or crisis_exit. The closing reason is insufficient_assets,
liabilities_extinguished or null; the strike-off reason is ex_officio,
liquidation_closed or null. origin is creation for a new business, transfer for a
company registered at another court after moving its head office — not a new company — or
other. accounts is annual or consolidated, and closing_on the last day of the
fiscal year filed. legal_entity.insolvency.reopened is a liquidation closed for
insufficient assets and resumed: the same proceeding, not a new one. counterparties is a list of registry numbers: one sale gives the buyer
legal_entity.business_acquired and the seller legal_entity.business_sold, each naming
the other. nature, category and family are the court's and the registry's labels, in
French, as published.
The kind is read from the notice's structured fields alone, never from its text. A notice
those fields do not place is legal_entity.legal_notice_published, not a guess: mostly
changes to a company's details (the modification family, whose content is prose), but
also claims lists, sanctions against a director, judgments that modify a plan, the
retraction of a pronounced liquidation (the notice does not say whether it undoes an
opening or a conversion), and a company named on a notice about another one outside a sale,
such as a previous owner on a registration. That was
15.8 % of the gazette's events in October 2026, so open url when the notice matters to
you. occurred_on is the judgment's date when the notice gives one, and the bulletin's
otherwise; a judgment is published a week or two after it is pronounced.
legal_entity.accounts_filed is off by default: a list without kind leaves it out, and
so do its two corrections. It was 52 % of the gazette's events in October 2026, one a year
for most companies. Name it in kind to read it.
The gazette never edits a notice. It publishes a correction or a cancellation, and each
kind above has two variants for it, with the same severity: <kind>.corrected replaces
the earlier notice, <kind>.cancelled withdraws it — legal_entity.struck_off.cancelled,
for instance. Its payload is the kind's, plus corrects: notice_id, the source_ref of
the event it corrects, and that notice's published_on. notice_id is null when the
gazette did not identify the earlier notice in full.
One cancellation names no notice at all. A court that retracts its own opening judgment on
a third party's objection publishes a judgment of its own, served as
legal_entity.insolvency.opened.cancelled with nature and no corrects: it withdraws the
company's latest opening before it.
This list is the raw log. A corrected or cancelled event stays in it, next to the
.corrected or .cancelled event that names it, and nothing is removed or merged. Apply
the corrections yourself, or read the legal fields of enrich,
the only place they are applied. A kind filter names the variants too:
kind=legal_entity.insolvency.opened,legal_entity.insolvency.opened.cancelled.
Some of the gazette's events carry no values: those of a company that was
partially disclosed in the register when the notice was read, or
that the register did not hold at that moment, since whether its notice may be
republished could not be checked. Their payload holds only withheld, which says
which case it is (restricted, unknown or unretypable, below), and corrects on a
correction, so that a cancellation still names what it withdraws; the kind, dates and source_ref stay, unless
the company is partially disclosed or has no record today, which withholds more (below).
An unknown event is filled in once the company appears in the register, after the
next daily update or monthly stock: the same event, with the same id and recorded_at,
then carries its values — or withheld: "restricted" if the company is partially
disclosed. It is the only event whose payload changes, so do not count it among the ids
you skip: read it again on your next pass and replace what you stored under its id.
Where its notice can no longer be typed, it stays masked as withheld: "unretypable",
with reason set to notice_missing or kind_changed, and does not change again. A
restricted event is never filled in: it keeps its empty payload after the company has
its disclosure lifted. The notice is still at
https://www.bodacc.fr/pages/annonces-commerciales-detail/?q.id=id: followed by
source_ref.
Filter with kind (one kind, or several separated by commas), severity (a floor:
critical, notable or informational, where notable returns notable and critical
events), and occurred_from / occurred_to (YYYY-MM-DD, both included, on
occurred_on). An unknown kind or severity, a date in any other form than
YYYY-MM-DD, an include_bulk other than true, false, 1 or 0, or a cursor this API
did not issue is refused with 400 invalid_request rather than ignored, so a typo never reads as
"nothing happened".
Events marked bulk are left out unless you pass include_bulk=true, and three things mark
them. A run that changed an unusually large part of the register at once marks every event
it wrote, genuine ones included: a company that ceased on that day has its
legal_entity.ceased marked bulk too. Every event of the monthly reconciliation below is
bulk. And so is the gazette's history — its notices since January 2008, loaded at once
rather than read day by day — so without include_bulk=true a company's notices from
before the daily read began are not listed, a liquidation of 2019 included. To answer "has
this company ever been in insolvency", or whenever you must not miss an event, pass
include_bulk=true and filter on severity instead.
Once a month, when the register's full monthly file is loaded, a change the daily updates
missed and that the file still shows is recorded late. The file holds only the current
state of each record, so a cessation or a closure keeps its own date, but a change of value
is dated by the day the register last processed the record, which can be later than the
change itself. recorded_at can be weeks after either. A change the file no longer shows,
such as a value changed and changed back within the month, is not recovered.
The two removed_from_registry kinds come only from this monthly pass, so only with
include_bulk=true: the record is no longer in the register's monthly file. That is not a
cessation, and no legal_entity.ceased or establishment.closed comes with it. Its
occurred_on is the date of that file. From then on the record itself answers
404 not_found, while this list keeps answering with removed: true. Because the removal
event is bulk, a removed entity read without include_bulk=true can answer an empty
events list with removed: true: the entity left the register, and nothing else matched
the filters. An establishment.removed_from_registry stays on its legal entity's timeline.
This list pages with a cursor, not with page: pass pagination.next_cursor back as
cursor, with the same filters, until it is null. The cursor names the last event of the
page, so the next page starts below it whatever has been recorded since — no event is read
twice. per_page defaults to 20 and is clamped to 1–100, never rejected.
For a subject that is partially disclosed today, events keep their
kind, dates and provenance, but payload is withheld: {} on the legal entity's events,
legal_entity_number alone on an establishment's — including events recorded before the
record was masked. On the gazette's events that takes url and corrects with it, and
source_ref is null: the notice id is the link. The kind and dates stay. Every event of
a legal entity with no record — one that answers removed: true, or one this log knows only
through other events — is withheld the same way, gazette events included, whatever it was
disclosed as: with no record left, nothing says whether the register restricts it today. Each page read is one call against your quota; a 400 is not counted.
The key travels as an Authorization header with the read scope.