GET /company/report
Complete due diligence on a French company in one paid response, by SIREN: official identity (Sirene) + dated legal events (BODACC) + live VAT validation (VIES) + Peppol e-invoicing reachability + the global GLEIF identity and its ultimate consolidating parent - five blocks, each carrying its own provenance. This is the showcase of the “Company” family and of the whole pre-action checks suite: the unit endpoints consolidated into a single settlement.
The counterparty pre-action check. Before you invoice, pay or onboard:
an agent about to act with a company gets, in one paid call, the facts that
matter - is it real and still active, is there an open insolvency proceeding,
is its VAT number valid right now, can it receive an e-invoice on Peppol, and
which group consolidates it. No account, no API key, no Creditsafe/Pappers subscription. See the
live /catalog for the authoritative endpoint listing and
price.
The value is in the crossing. Take SAN MARINA (real store example below):
its Sirene status alone reads active, but the report shows the judicial
liquidation opened at the BODACC right beside it. Two sourced facts served
side by side - never fused into a verdict. That juxtaposition is the pitch.
Parameters
The report is by SIREN: siren only - no siret=, no vat=, no search
by name on this route.
| Parameter | Type | Required | Description |
|---|---|---|---|
siren | string | yes | 9-digit French SIREN (Luhn-checked) |
include | string | no | CSV subset of identity,events,vat,peppol,lei (default: all). identity is always served (the base), even if not listed |
GET /company/report?siren=333285633
GET /company/report?siren=321875205&include=identity,events,peppol
include=selects which blocks to build. Omit it and you get all five.- Without
vat, the report is 100% offline - zero network at call time (VIES is the service’s only outbound call).include=identity,events,peppol,leianswers in milliseconds. - An unknown value in
include=is a400 INVALID_INPUT(not billed).
The base identity is what makes the report exist
The identity block is the base, and its presence is the condition of the
report. A well-formed SIREN that is unknown to the Sirene register is a
404 NOT_FOUND, not billed - the gateway does not settle, and no empty
report is ever served or charged.
This is the deliberate difference with the unit endpoints
/company/events and
/company/peppol taken in isolation, where an
absence (no gazette entry, not on Peppol) is itself a paid 200 answer. A
report with no identity has no object - so here the absence of identity is a
404, while the absence of a secondary fact is a served, honest block.
x402 golden rule and the status matrix
The agent pays for due diligence that ran, in a single settlement - including a degraded or partial report. Only requests the service cannot answer leave the 200 range, and none of those are billed.
| Case | Result |
|---|---|
| Known SIREN | 200, billed - report served, even degraded (a block unavailable/unverifiable) or partial (include=) |
| Well-formed SIREN unknown to the register | 404 NOT_FOUND, not billed - no empty report |
siren missing / not 9 digits / Luhn fails / bad include= | 400, not billed (see Errors) |
Provenance per block - the central contract
The heart of this endpoint: each block carries its own provenance, and
they are never smoothed under one date. The five sources are dated
differently - Sirene is a month-end snapshot, BODACC an extraction date,
Peppol an export date, VIES a live check - and the response says so, block
by block. The root provenance reflects the identity base
(insee-sirene).
200 response - UnifiedResponse
{
"data": {
"siren": "…",
"identity": { "…": "exact shape of /company/resolve, own provenance" },
"events": { "…": "exact shape of /company/events, own provenance" },
"vat": { "…": "exact shape of /company/vat, own provenance" },
"peppol": { "…": "exact shape of /company/peppol, own provenance" },
"lei": { "…": "global GLEIF identity + ultimate parent, own provenance" },
"summary": { "…": "mechanically-derived facts, not a score" },
"coverage": { "complete": true }
},
"provenance": {
"source": "insee-sirene",
"fetched_at": "2026-07-12T21:17:29Z",
"freshness": { "kind": "snapshot", "as_of": "2026-06-30T00:00:00Z" }
}
}
Each block has exactly the shape of its unit endpoint - so the field-level documentation of a block is the documentation of the corresponding endpoint:
| Block | Shape / detail doc | Own provenance source |
|---|---|---|
identity | GET /company/resolve | insee-sirene (snapshot) |
events | GET /company/events | dila-bodacc (snapshot) |
vat | GET /company/vat | vies + pure-computation (live) |
peppol | GET /company/peppol | peppol-directory (snapshot) |
lei | GET /company/lei + /company/ownership | gleif (snapshot) |
Secondary blocks are best-effort - never a 5xx
Once identity succeeds, the secondary blocks are best-effort. A missing
dataset or a VIES outage degrades a block, it never fails the report:
- Dataset not ingested (BODACC, Peppol or GLEIF) → the block becomes
{ "unavailable": "bodacc_dataset_unavailable" }(resp."peppol_dataset_unavailable","gleif_dataset_unavailable"), the report is served anyway, and the absence is stated bycoverage.unavailable- never silent. - VIES outage → the
vatblock isstatus: "unverifiable"with areason, its provenance reduced topure-computation(only the local syntax check is claimed). A200, never a5xx(real example below). - Sirene never ingested (the base is impossible) →
503 DATA_UNAVAILABLE. This is distinct from a missed refresh, where the last good snapshot is served with its honestas_of- staleness is never turned into a 5xx.
Everything is said by coverage: complete, unavailable (degraded blocks),
excluded (blocks dropped by include=) - never a silent absence.
summary - mechanically-derived facts, not a score
summary is a synthesis derived mechanically from the served blocks:
| Field | Source | Meaning |
|---|---|---|
status | Sirene | active / ceased |
has_open_insolvency_announcement | BODACC | open insolvency proceeding, yes/no |
vat_status | VIES | valid / invalid / unverifiable |
peppol_reachable | Peppol | reachable on the directory, yes/no |
lei | GLEIF | the attached LEI, only when it is unique |
It is not a score. Never a rating, a recommendation, or a “risk score” -
this is the house rule on provenance and truthfulness (scoping decision
2026-07-11). A field absent from summary means the block was excluded by
include= or unavailable - said by coverage, never silent.
Example - full report, VIES live
GET /company/report?siren=333285633 (EQUIPTEC - all five blocks served,
coverage.complete: true, ~0.3 s dominated by the live VIES check; production
store, Sirene 2026-06-30 / GLEIF 2026-07-28):
{
"data": {
"siren": "333285633",
"identity": {
"siren": "333285633",
"name": "EQUIP'TEC",
"status": "active",
"legal_form": { "code": "5710", "label": "SAS, société par actions simplifiée" },
"main_activity": { "code": "46.69B", "label": "Commerce de gros …", "nomenclature": "NAFRev2" },
"created_on": "1985-08-01",
"headquarters": {
"siret": "33328563300033",
"status": "active",
"address": { "line": "1 RUE DE L’INDUSTRIE", "postal_code": "62220", "city": "CARVIN", "country": null }
},
"coverage": { "missing": [] },
"provenance": {
"source": "insee-sirene",
"fetched_at": "2026-07-12T21:17:29.335151695Z",
"freshness": { "kind": "snapshot", "as_of": "2026-06-30T00:00:00Z" }
}
},
"events": {
"siren": "333285633",
"company": { "name": "EQUIP'TEC", "natural_person": null, "status": "active" },
"events": [
{
"family": "sale",
"nature": "Achat d'un fonds par une personne morale (insertion provisoire)",
"published_on": "2009-05-06",
"gazette_issue": "20090087",
"court": "GREFFE DU TRIBUNAL DE COMMERCE DE ROUBAIX-TOURCOING"
}
],
"total": 1,
"truncated": false,
"flags": {
"has_open_insolvency_announcement": false,
"is_deregistered": false,
"latest_event": { "family": "sale", "date": "2009-05-06" }
},
"coverage": { "window": { "from": "2008-01-01", "to": "2026-07-12" } },
"provenance": {
"source": "dila-bodacc",
"fetched_at": "2026-07-12T21:17:29.335151695Z",
"freshness": { "kind": "snapshot", "as_of": "2026-07-12T00:00:00Z" }
}
},
"vat": {
"vat_number": "FR20333285633",
"country": "FR",
"syntax_valid": true,
"status": "valid",
"name": "SAS EQUIP'TEC",
"derived_from_siren": "333285633",
"checked_at": "2026-07-12T21:17:29.632129817Z",
"provenance": {
"source": "vies + pure-computation",
"fetched_at": "2026-07-12T21:17:29.632129817Z",
"freshness": { "kind": "live" }
}
},
"peppol": {
"reachable": true,
"participants": [
{ "id": "0009:33328563300033", "scheme": "0009", "value": "33328563300033", "country": "FR", "names": ["EQUIPTEC"], "registered_on": "2023-03-27", "document_types": ["… declared document types, see /company/peppol"] }
],
"company": { "name": "EQUIP'TEC", "natural_person": null, "status": "active" },
"coverage": {
"directory_as_of": "2026-07-12",
"note": "reachability reflects the public Peppol directory export dated directory_as_of, not a live SMP lookup"
},
"provenance": {
"source": "peppol-directory",
"fetched_at": "2026-07-12T21:17:29.335151695Z",
"freshness": { "kind": "snapshot", "as_of": "2026-07-12T00:00:00Z" }
}
},
"lei": {
"lei": "969500EQMDAO9YAZN902",
"legal_name": "EQUIP'TEC",
"entity_status": "ACTIVE",
"registration_status": "ISSUED",
"verified_against_sirene": true,
"total_matches": 1,
"ultimate_parent": {
"status": "reporting_exception",
"link": null,
"exception": { "category": "ULTIMATE_ACCOUNTING_CONSOLIDATION_PARENT",
"reasons": ["NATURAL_PERSONS"] }
},
"limits": "Relationships are self-declared … NOT beneficial ownership under AML/KYC rules …",
"provenance": {
"source": "gleif",
"fetched_at": "2026-07-29T15:50:39Z",
"freshness": { "kind": "snapshot", "as_of": "2026-07-28T00:00:00Z" }
}
},
"summary": {
"status": "active",
"has_open_insolvency_announcement": false,
"vat_status": "valid",
"peppol_reachable": true,
"lei": "969500EQMDAO9YAZN902"
},
"coverage": { "complete": true }
},
"provenance": {
"source": "insee-sirene",
"fetched_at": "2026-07-12T21:17:29.335151695Z",
"freshness": { "kind": "snapshot", "as_of": "2026-06-30T00:00:00Z" }
}
}
Note the provenance per block: five sources, four different snapshot
dates plus one live check - never smoothed under a single date. EQUIPTEC holds
a LEI, and Level 2 says why it declares no consolidating parent
(NATURAL_PERSONS: it is held by individuals, who have no LEI). The root
provenance is that of the identity base.
Example - include= partial, 100% offline (the crossing value)
GET /company/report?siren=321875205&include=identity,events,peppol (SAN
MARINA - the vat block is dropped, so zero network, answered in ~4 ms;
the real BODACC timeline of 36 notices is abridged here to the two most
significant, the real response carries them all; production store,
2026-07-26):
{
"data": {
"siren": "321875205",
"identity": {
"siren": "321875205",
"name": "SAN MARINA",
"status": "active",
"…": "exact shape of /company/resolve, provenance insee-sirene snapshot 2026-06-30"
},
"events": {
"siren": "321875205",
"company": { "name": "SAN MARINA", "natural_person": null, "status": "active" },
"events": [
{
"family": "insolvency",
"nature": "Jugement de conversion en liquidation judiciaire",
"effective_on": "2023-02-20",
"published_on": "2023-02-23",
"court": "Greffe du Tribunal de Commerce de Marseille"
},
{
"family": "insolvency",
"nature": "Dépôt de l'état des créances",
"effective_on": "2023-08-25",
"published_on": "2023-09-05",
"court": "Greffe du Tribunal de Commerce de Marseille"
}
],
"total": 36,
"truncated": false,
"flags": {
"has_open_insolvency_announcement": true,
"is_deregistered": false,
"latest_event": { "family": "sale", "date": "2024-02-01" }
},
"coverage": { "window": { "from": "2008-01-01", "to": "2026-07-26" } },
"provenance": {
"source": "dila-bodacc",
"fetched_at": "2026-07-26T18:43:41.814096541Z",
"freshness": { "kind": "snapshot", "as_of": "2026-07-26T00:00:00Z" }
}
},
"peppol": {
"reachable": false,
"participants": [],
"company": { "name": "SAN MARINA", "natural_person": null, "status": "active" },
"coverage": {
"directory_as_of": "2026-07-26",
"note": "reachability reflects the public Peppol directory export dated directory_as_of, not a live SMP lookup"
},
"provenance": {
"source": "peppol-directory",
"fetched_at": "2026-07-26T18:43:41.814096541Z",
"freshness": { "kind": "snapshot", "as_of": "2026-07-26T00:00:00Z" }
}
},
"summary": {
"status": "active",
"has_open_insolvency_announcement": true,
"peppol_reachable": false
},
"coverage": { "complete": false, "excluded": ["vat"] }
},
"provenance": {
"source": "insee-sirene",
"fetched_at": "2026-07-26T18:43:41.814096541Z",
"freshness": { "kind": "snapshot", "as_of": "2026-06-30T00:00:00Z" }
}
}
Two things to read here. The value of the crossing: the Sirene status
alone says active, the BODACC says the judicial liquidation is open
(summary.has_open_insolvency_announcement: true) - two sourced facts served
side by side, never fused into a verdict. The include= contract: the
vat block is absent, so is summary.vat_status, and
coverage = { complete: false, excluded: ["vat"] } says it explicitly - never
a silent absence. Note also that flags.latest_event names a sale that is
not among the two notices excerpted above: the flags are derived from the
complete 36-notice timeline, never from what an excerpt - or a filtered view -
happens to show.
The values above are those of the 2026-07-26 snapshot. An example served
from a snapshot ages with the store: a newly gazetted announcement can move
latest_event, so read the numbers as an illustration for the as_of shown -
only the derivation rule is a contract.
The lei block - global identity and who consolidates the counterparty
The lei block carries the GLEIF attachment of the SIREN and
ultimate_parent, the consolidating group head. That parent is the point of
the block: a spotless French counterparty owned by a sanctioned entity is
exactly the case an endpoint-by-endpoint check walks past.
{
"lei": {
"lei": "1VUV7VQFKUOQSJ21A208",
"legal_name": "CREDIT AGRICOLE CORPORATE AND INVESTMENT BANK",
"entity_status": "ACTIVE",
"registration_status": "ISSUED",
"verified_against_sirene": true,
"total_matches": 1,
"ultimate_parent": {
"status": "declared",
"link": {
"lei": "969500TJ5KRTCJQWXH05",
"entity": { "legal_name": "CREDIT AGRICOLE SA", "legal_country": "FR", "…": "…" },
"relationship_status": "ACTIVE",
"period": { "start": "2018-01-01", "end": null }
},
"exception": null
},
"limits": "Relationships are self-declared … NOT beneficial ownership under AML/KYC rules …",
"provenance": {
"source": "gleif",
"freshness": { "kind": "snapshot", "as_of": "2026-07-28T00:00:00Z" }
}
}
}
Four things this block does not say:
- ⚠️
ultimate_parentis the accounting consolidation parent, never the ultimate beneficial owner under AML/KYC rules, and Level 2 publishes no ownership percentage. The response repeats it itself inlimits- the same fixed sentence asGET /company/ownership, where the distinction is spelled out in full. ultimate_parentis absent when the attachment is ambiguous or non-existent: walking the control chain of one LEI picked at random among several would name a wrong group head.total_matches: 0is an answer (“this company has no LEI”), not an unavailability - so the block is served, not markedunavailable. It is the case of the vast majority of French companies (169,049 SIREN bridged at the 2026-07-28 image).- The identity fields follow the same rule as the
leiblock ofGET /company/resolve:total_matchesis always told, the rest is filled in only when the LEI is unique.
The block is 100% offline: include=identity,events,peppol,lei is a report
with zero outbound network - VIES remains the service’s only outbound call.
Example - VIES outage = degraded block, never a 5xx
VIES_BASE_URL pointed at a closed port, full call through the gateway -
200 in ~18 ms, only the vat block degraded (e2e E-402, 2026-07-12):
{
"vat": {
"vat_number": "FR20333285633",
"country": "FR",
"syntax_valid": true,
"status": "unverifiable",
"reason": "network_unreachable",
"derived_from_siren": "333285633",
"provenance": { "source": "pure-computation", "freshness": { "kind": "live" } }
}
}
summary.vat_status: "unverifiable", the three other blocks intact,
coverage.complete: true (the block was served, degraded honestly) - the
block’s provenance claims only the local computation, never a VIES result it
did not get.
Pricing - the whole report at the flat grid price
/company/report sits on Invoket’s uniform flat grid, same price as any
unit endpoint - yet it bundles four consolidated offline lookups plus one live
check in a single settlement, a composite answer that would otherwise be
five separate calls. The exact amount is served by the live
/catalog and is never hard-coded here; the report’s
value is the consolidation and the cross-check.
Freshness
Each block carries its own freshness. identity is a month-end Sirene
snapshot, events a BODACC extraction snapshot, peppol a dated
directory export, lei a dated GLEIF Golden Copy image, vat a
live VIES check. The root provenance mirrors
the identity base. A missed refresh keeps serving the last good snapshot
with its honest as_of - staleness is never a 5xx.
Limits
Stated plainly, so the agent knows what the report does and does not claim:
- By SIREN only - no
siret=, novat=, no search by name on this route. - Each block inherits its unit endpoint’s limits: BODACC window 2008+, a dated Peppol photo (not a live SMP lookup), VIES availability varying by member state, GLEIF relationships that are self-declared accounting consolidation, not beneficial ownership.
- The five sources are dated differently - which is exactly why provenance is per block, never smoothed.
summarystates sourced facts, not an opinion - no rating, no score, no recommendation.
Errors
Only requests the service cannot answer leave the 200 range - none are
billed. Note the difference from the unit endpoints: an unknown SIREN here
is a 404 (no empty report), whereas on /company/events or /company/peppol
an absence is a paid 200.
| Status | code | Case |
|---|---|---|
| 400 | MISSING_PARAMETER | siren absent |
| 400 | INVALID_INPUT | siren not 9 digits / non-digits; unknown value in include= |
| 400 | INVALID_CHECKSUM | siren fails its Luhn check - a probable typo the agent should fix |
| 404 | NOT_FOUND | Well-formed SIREN unknown to the Sirene register (no empty report); unknown routes |
| 503 | DATA_UNAVAILABLE | The Sirene dataset has never been ingested - the base cannot be built |
| 500 | INTERNAL | Internal error (detail logged, not exposed) |
{ "error": "unknown value in 'include=': expected a subset of identity,events,vat,peppol,lei", "code": "INVALID_INPUT" }
Sources and licences
Each block carries its own source, dated in its own provenance:
identity- INSEE Sirene register (Licence Ouverte / Etalab, month-end image).events- BODACC / DILA (Licence Ouverte / Etalab, extraction date).vat- VIES, the European Commission’s public VAT validation service (live, no key).peppol- the public Peppol directory export, data published by the network’s participants, attribution OpenPeppol (export date).lei- the GLEIF Level 1 and Level 2 Golden Copy (CC0 1.0, publication date of the ingested image).
See also
The report is the “counterparty onboarding” suite. Need just one fact? Each
block is its own unit endpoint, at the same flat grid price - see the
/catalog:
GET /company/resolve- the official identity card behind a SIREN/SIRET.GET /company/events- the dated BODACC legal timeline (insolvency, deregistration, sales).GET /company/vat- live intra-EU VAT validation against VIES.GET /company/peppol- Peppol e-invoicing reachability, by identifier and document type.GET /company/lei- the global GLEIF identity, by LEI, BIC, ISIN, SIREN or exact name plus country.GET /company/ownership- the full control chain: direct parent, ultimate parent, direct subsidiaries.
Then, verify the company, screen the account, check the contact before you act:
GET /iban/screen- OFAC/EU/UN sanctions screening on the counterparty’s IBAN before you pay it.GET /phone/validate- is the contact number plausible and well-formed.
And the counterparty vs. the document - the full French 2026-2027 invoicing cycle:
-
POST /invoice/validate- deterministic EN 16931 validation of the invoice document. -
POST /invoice/generate- generate a conformant EN 16931 e-invoice. -
For agents - discovery surfaces, the live
/catalogand how settlement works.