Skip to content
firmus.shdocs

Every page's text, headings and title. Code samples are not indexed.

List events

What changed about one legal entity and its establishments, newest first.

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:

kindseverity
legal_entity.ceasedcritical
legal_entity.reactivatedcritical
legal_entity.disclosure_restrictedcritical
legal_entity.disclosure_liftedcritical
legal_entity.renamednotable
legal_entity.legal_form_changednotable
legal_entity.activity_changednotable
legal_entity.head_office_movednotable
legal_entity.employer_status_changedinformational
legal_entity.mission_or_ess_changedinformational
legal_entity.workforce_changedinformational
legal_entity.size_category_changedinformational
legal_entity.removed_from_registrynotable
establishment.openednotable
establishment.closednotable, critical on the head office
establishment.reopenednotable
establishment.movednotable
establishment.became_head_officenotable
establishment.renamedinformational
establishment.activity_changedinformational
establishment.removed_from_registrynotable

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.

kindseveritypayload, beyond the three above
legal_entity.insolvency.openedcriticalnature, procedure
legal_entity.insolvency.convertedcriticalnature, procedure (the new one)
legal_entity.insolvency.plan_adoptedcriticalnature, plan
legal_entity.insolvency.closedcriticalnature, procedure when named, reason
legal_entity.insolvency.reopenedcriticalnature, procedure
legal_entity.conciliationcriticalnature
legal_entity.personal_recoverycriticalnature
legal_entity.business_acquiredcriticalcounterparties (the sellers), category
legal_entity.business_soldcriticalcounterparties (the buyers), category
legal_entity.struck_offcriticalreason
legal_entity.registeredinformationalorigin, category, registered_on
legal_entity.accounts_filedinformational, off by defaultclosing_on, accounts
legal_entity.legal_notice_publishedinformationalfamily, 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.

GET/v1/{country_code}/legal-entities/{registry_number}/eventsScope read

Parameters

ParameterInTypeRequiredExample
country_codepathstringYesfr
registry_numberpathstringYes552032534
cursorquerystringNoMjAyNi0wNi0xNXwxMDAy
include_bulkquerybooleanNotrue
kindquerystringNolegal_entity.renamed
occurred_fromquerystringNo2026-03-01
occurred_toquerystringNo2026-06-15
per_pagequeryintegerNo1
severityquerystringNonotable

Request

bash
curl -H "Authorization: Bearer $FIRMUS_KEY" \
  "https://api.firmus.sh/v1/fr/legal-entities/552032534/events"

Fields

  • eventsobject[]
    • []objectoptional
      • idinteger
      • kindstring
      • severitystring
      • occurred_onstring
      • recorded_atstring
      • sourcestring
      • source_refstringnullable
      • bulkboolean
      • subjectobject
        • kindstring
        • numberstring
      • payloadobject
  • paginationobject
    • per_pageinteger
    • next_cursorstringnullable
  • removedboolean

Responses

The timeline of one legal entity: the dated, sourced changes the registry (INSEE Sirene) recorded about it and its establishments, and the notices the BODACC legal gazette published about it (source `bodacc`: insolvency proceedings, sales of a business, removal from the trade register, registration, other legal notices, their corrections and cancellations), newest first. Cursor-paginated: pass pagination.next_cursor back as cursor. Bulk events (a mass reclassification, the monthly reconciliation of what the daily updates missed, or the BODACC's history loaded at once) are excluded unless include_bulk is set. Filed accounts (`legal_entity.accounts_filed` and its corrections) are served only when `kind` names them.

{
  "events": [
    {
      "id": 1003,
      "kind": "legal_entity.workforce_changed",
      "severity": "informational",
      "occurred_on": "2026-09-30",
      "recorded_at": "2026-10-02T06:00:00Z",
      "source": "sirene_daily",
      "source_ref": "france_sirene_syncs:1",
      "bulk": false,
      "subject": {
        "kind": "legal_entity",
        "number": "552032534"
      },
      "payload": {
        "to": {
          "workforce_range_code": "42"
        },
        "from": {
          "workforce_range_code": "41"
        }
      }
    }
  ],
  "pagination": {
    "per_page": 1,
    "next_cursor": "MjAyNi0wOS0zMHwxMDAz"
  },
  "removed": false
}

Try it

Calls the real API with a demo key. No account, no signup.