/v2/company endpoint is the single entry point for company data, official documents, and ownership graph traversal. It accepts one company identifier, one country, and the datapoints or documents you want.
Use it for company onboarding, KYB verification, shareholder and UBO checks, subsidiary analysis, official document retrieval, and follow-up polling by requestId.
For live country coverage, data block availability, pricing, sources, identifiers, and document catalogs, see Coverage and pricing.
Request shape
Datapoints
Availability varies by country and mode. Use the live pricing pages orGET /v2/pricing for country-specific availability.
The legacy
companyProfile datapoint is still accepted for existing integrations. New integrations should request explicit datapoints. See the migration guide.
Person identities and role entries
entityId identifies a person or company within a request. It links occurrences of the same entity across datapoints, such as legalRepresentatives, shareholders, and ultimateBeneficialOwners. It is not a permanent identifier to match people across separate requests.
An entityId can appear more than once in legalRepresentatives. A person holding several roles can have a separate entry for each appointment, with the same entityId and different role details or appointment dates.
For example, a Belgian director can also be a member of the management committee:
To import one record per person, group entries by
entityId within the request and retain all associated roles and appointment dates. Neither entityId alone nor the combination of entityId and role.standardized is a unique key for a role entry. Different local roles can share a standardized category. If entityId is absent, do not group all entries without an ID into one person.
Choose a mode
/v2/company supports two modes:
- Verification mode is the default and prioritizes authoritative data for compliance.
- Onboarding mode (
mode: "onboarding") prioritizes speed for form prefill and early screening.
Documents
Document retrieval is a two-step flow:- Request
availableDocuments. - Pass selected document IDs in the
documentsarray.
availableDocuments before requesting a download. See Document retrieval.
Response lifecycle
Every request returns arequest object with the current status of each datapoint and document.
The response may be progressive. For example,
company can succeed before legalRepresentatives, documents, or ownership datapoints finish.
Not every failed is an outage
Two error.code values mean the datapoint is not something we return for this
request, rather than something that went wrong:
Both carry
retryable: false. Handle them the way you would handle a successful
“nothing to report” answer: don’t retry, don’t alert, don’t block your flow waiting
for them. Filter on the code or on retryable. error.message is human-readable and
safe to show your own users.
To know which datapoints a country returns before you request them, see
Coverage and pricing or GET /v2/pricing.
An empty list is an answer
The list-shaped fields —legalRepresentatives, otherKeyPersons,
establishments, shareholders, subsidiaries, ultimateBeneficialOwners —
follow one rule, in both the API response and the webhook payload:
So a datapoint whose
dataStatus says succeeded always carries its list. You
never have to disambiguate “succeeded with nothing attached” from “never ran” —
succeeded plus a missing key cannot happen.
An empty list means the register holds no such record, which is not always
the same as the entity has none. Some registers only publish part of a
category: the Dutch KVK, for example, registers a shareholder only when a
company has a single 100% holder, so a BV with several shareholders returns
shareholders: []. Country pages document these limits — see
Netherlands.Polling
Use therequestId to fetch the latest result. This is free and does not create a new billable request.
succeeded or failed). In production, use webhooks when possible.
Branch on the status itself rather than enumerating the non-terminal ones. A poller
that waits for anything other than succeeded or failed will hang if a new
intermediate status is ever introduced.
PDF extract
Any request can also be returned as a single-file PDF extract, suitable for attaching to a case file or handing to a reviewer.Requesting before a request has finished
By default the extract renders whatever has arrived, exactly asGET /v2/company/{requestId} returns partial results while a request is still running.
A partial extract says so on its own face, so it can never be mistaken for a complete one:
- The seal reads PARTIAL instead of VERIFIED.
- A Data completeness section lists every requested datapoint and whether it was included, is still being retrieved, or failed — with the reason.
- The
X-Topograph-Data-Statusresponse header carriescompleteorpartial, so you can branch without opening the file.
requireComplete:
409 while any requested datapoint is still running, naming what it is waiting on:
Only datapoints decide completeness. Documents are delivered as separate files and never appear in the extract, so a document still downloading does not hold the PDF back.
Seal states
Viewing in a browser
The response defaults toContent-Disposition: attachment. Pass disposition=inline to render it in place instead: