UBO Investigation
Purpose of the API
The UBO Investigation API allows you to automatically identify the Ultimate Beneficial Owners (UBOs) of Dutch organizations. Given a KVK registration number, the API traverses a company's ownership structure, fetches official trade register extracts, maps entities and their relationships, and classifies who ultimately controls or benefits from the organization.
This is an asynchronous API. You submit an order, the system processes it in the background, and you poll for the result when it is ready.
How It Works
- Submit an order for a Dutch organization using its KVK number. Optionally set a date filter and whether to re-order documents if they have changed.
- The system processes the order by fetching KVK Handelsregister extracts for the target organization and any intermediate entities in the ownership chain.
- Poll the order status until the phase is succeeded (or failed).
- Fetch the result, which contains a graph of entities, their connections, and the UBO classification.
- Optionally fetch the receipt to see how many documents were ordered or reused and how many profiles were visited.
Getting Started
Before You Start
You will need:
Access to the UBO Investigation API
An API Key — contact your Account Manager to have one created for your company
A valid KVK registration number (8 digits) for the Dutch organization you want to investigate
Authentication
Include your API key in the X-API-Key header with every request.
curl 'https://api.company.info/nl/organizations/ubo-investigations/v1/orders' -H 'X-API-Key: xxxAPI Format
The API communicates using JSON API format for all endpoints.
Errors follow the RFC 9457 Problem Details format with content type application/problem+json.
Base URL
Orders
Create an Order
Submits a new UBO investigation for a Dutch organization. The order is processed asynchronously — check the status.phase field to track progress.
POST /nl/organizations/ubo-investigations/v1/orders
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
data.type | string | ✅ | Must be "orders" |
data.attributes.organization.id | string | ✅ | 8-digit KVK number |
data.attributes.dataSources.documents.extract.fromDate | date | ✅ | Only include documents dated from this date (YYYY-MM-DD) |
data.attributes.dataSources.documents.extract.orderIfChanged | boolean | ❌ | Re-order the extract if it has changed since the last retrieved. Defaults to false |
data.attributes.reference | string | ❌ | Searchable charge code or reference, max 250 characters |
Example request:
curl -X POST 'https://api.company.info/nl/organizations/ubo-investigations/v1/orders' \
-H 'X-API-Key: xxx' \
-H 'Content-Type: application/json' \
-d '{
"data": {
"type": "orders",
"attributes": {
"reference": "my-charge-code",
"organization": {
"id": "33302047"
},
"dataSources": {
"documents": {
"extract": {
"fromDate": "2024-10-02",
"orderIfChanged": true
}
}
}
}
}
}'Example response (201 Created):
{
"data": {
"type": "orders",
"id": "3e02855b-6c6d-44da-8d8f-42137f54eaf7",
"attributes": {
"reference": "my-charge-code",
"organization": {
"id": "33302047"
},
"dataSources": {
"documents": {
"extract": {
"fromDate": "2024-10-02",
"orderIfChanged": true
}
}
},
"status": {
"phase": "queued"
}
}
}
}The id returned is the Order ID (UUID) you will use for all subsequent calls.
List Orders
Returns all investigation orders for your account. Optionally filter by reference.
GET /nl/organizations/ubo-investigations/v1/orders
Query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
reference | string | ❌ | Filter orders by reference value (max 250 characters) |
Example request:
curl 'https://api.company.info/nl/organizations/ubo-investigations/v1/orders?filter[reference]=my-charge-code' -H 'X-API-Key: xxx'The response returns an array under data, each item following the same structure as a single order response.
Get an Order
Retrieves a single order by its UUID. Use this to poll the processing status.
GET /nl/organizations/ubo-investigations/v1/orders/{id}
Example request:
curl -X GET 'https://api.company.info/nl/organizations/ubo-investigations/v1/orders/3e02855b-6c6d-44da-8d8f-42137f54eaf7' \
-H 'X-API-Key: xxx'Order status phases:
| Phase | Description |
|---|---|
queued | The order has been accepted and is waiting to be processed |
processing | The investigation is actively running |
succeeded | Investigation completed successfully — result is ready to fetch |
failed | Investigation failed — check status.reason and status.message |
cancelled | The order was canceled |
When phase is Failed, additional fields are included:
| Field | Description |
|---|---|
status.reason | One of: timeout, invalidDocument, documentOrderingFailed, profileFetchFailed, internalError |
status.message | Human-readable details about the failure |
Example response (failed order):
{
"data": {
"type": "orders",
"id": "3e02855b-6c6d-44da-8d8f-42137f54eaf7",
"attributes": {
"organization": {
"id": "33302047",
"name": "CompanyInfo B.V."
},
"dataSources": {
"documents": {
"extract": {
"fromDate": "2024-10-02",
"orderIfChanged": true
}
}
},
"status": {
"phase": "failed",
"reason": "timeout",
"message": "document retrieval timed out after 30s"
}
}
}
}Receipt
Once an order's status.phase is Succeeded, you can fetch the receipt and the full result.
Get the Receipt
The receipt gives a summary of resources consumed during the investigation — useful for cost reconciliation and audit purposes.
GET /nl/organizations/ubo-investigations/v1/orders/{id}/receipt
Example request:
curl -X GET 'https://api.company.info/nl/organizations/ubo-investigations/v1/orders/3e02855b-6c6d-44da-8d8f-42137f54eaf7/receipt' \
-H 'X-API-Key: xxx'Example response:
{
"data": {
"type": "receipt",
"attributes": {
"dataSources": {
"documents": {
"extracts": [
{ "type": "ordered", "count": 2 },
{ "type": "reused", "count": 1 }
]
}
},
"profiles": {
"organizations": 3
}
}
}
}| Field | Description |
|---|---|
extracts[].type: "ordered" | Number of new KVK extracts fetched for this investigation |
extracts[].type: "reused" | Number of previously cached extracts reused |
profiles.organizations | Number of organization profiles traversed |
Download the Result
Returns the full investigation output: a graph of entities and their connections, plus the UBO classification.
GET /nl/organizations/ubo-investigations/v1/orders/{id}/result
Example request:
curl -X GET 'https://api.company.info/nl/organizations/ubo-investigations/v1/orders/3e02855b-6c6d-44da-8d8f-42137f54eaf7/result' \
-H 'X-API-Key: xxx'The response has three sections under the attributes: entities, connections, and classification.
Entities
A map of UUID → entity object, where each UUID is a stable internal identifier for that person or organization within this investigation.
Entity types:
| Type | Description |
|---|---|
organization | A Dutch-registered legal entity (BV, NV, etc.) |
individual | A natural person |
foreignOrganization | A legal entity registered outside the Netherlands |
unknown | Entity type could not be determined |
Organization entity example:
"86125a3a-fe8b-45bd-9437-8a2764034062": {
"type": "organization",
"source": {
"kind": "document",
"category": "standardExtract"
},
"attributes": {
"id": "33302047",
"name": "Company.Info B.V.",
"isActive": true,
"legalForm": "Besloten Vennootschap",
"sbi": [
{
"code": "62100",
"isMain": true,
"system": "SBI",
"source": "tradeRegister",
"description": "Ontwerpen van computerprogramma's"
}
],
"contact": {
"address": {
"formatted": "Laan op Zuid 2 3071AA Rotterdam",
"street": "Laan op Zuid",
"houseNumber": 2,
"postalCode": "3071AA",
"country": "Rotterdam",
"registrationDate": "2011-12-16"
}
},
},
"links": {
"profile": "https://api.company.info/v1/organizations/33302047",
"dataSource": "https://api.company.info/v1/documents/MDFLUlg2NlpaS..."
}
}Individual entity example:
"1914bd64-7e3d-4aa9-92f1-676da47c08aa": {
"type": "individual",
"dataSource": {
"kind": "document",
"category": "standardExtract"
},
"attributes": {
"firstNames": "Mildred",
"lastName": "Litz-Hutten",
"fullName": "Mildred Stefanie Litz-Hutten",
"dateOfBirth": "1974-12-11"
},
"links": {
"dataSource": "https://api.company.info/v1/documents/MDFLUlg2NlpaS..."
}
}
Links are optionalThe
links.profileandlinks.dataSourcefields are optional and may not be present for every entity, depending on data availability.
Connections
An array of directed relationships between entities, identified by their UUIDs.
"connections": [
{
"from": "1914bd64-7e3d-4aa9-92f1-676da47c08aa",
"to": "86125a3a-fe8b-45bd-9437-8a2764034062",
"isCircle": false,
"meta": {
"roles": [
{ "type": "GEVOLMACHTIGDE", "startRoleDate": "2026-03-01" }
]
}
},
{
"from": "db82dafb-1c4e-483d-af3e-4e91e4a49fbc",
"to": "86125a3a-fe8b-45bd-9437-8a2764034062",
"isCircle": false,
"meta": {
"roles": [
{ "type": "ENIGAANDEELHOUDER" }
]
}
}
]| Field | Description |
|---|---|
from | UUID of the entity holding the role |
to | UUID of the entity being connected to |
isCircle | Whether the connection leads to a circle |
meta.roles[].type | Role type code (e.g., GEVOLMACHTIGDE, ENIGAANDEELHOUDER) |
meta.roles[].startRoleDate | Date from which the role is effective (YYYY-MM-DD), when available |
Role type localizationRole type codes are returned in Dutch by default. To receive role types in another language, add the
Accept-Languageheader to your request (e.g.,Accept-Language: en).
Classification
The classification section contains the output of the UBO algorithm — which entities have been identified as UBOs and in what capacity.
"classification": {
"status": {
"phase": "done"
},
"result": [
{
"from": "1914bd64-7e3d-4aa9-92f1-676da47c08aa",
"to": "86125a3a-fe8b-45bd-9437-8a2764034062",
"functionType": ["GEVOLMACHTIGDE"],
"label": "UBOGateway"
}
]
}Classification status phases:
| Phase | Description |
|---|---|
done | Classification completed successfully |
failed | Classification could not be completed — see reason and message |
Failure reasons:
| Reason | Description |
|---|---|
governmentalCompany | The organization is a government entity, which is exempt from UBO registration |
noPersonFound | No natural person could be identified as a UBO |
unknown | An unexpected error occurred during classification |
UBO classification labels:
| Label | Description |
|---|---|
UBO | A confirmed Ultimate Beneficial Owner — a natural person who directly or indirectly owns or controls the organization |
UBOGateway | An intermediary entity or person through whom ownership passes, but who is not the final UBO |
UBOSuspect | A likely UBO that could not be confirmed with the available data |
Full Result Example
{
"data": "result",
"id": "19343166-d74b-4af8-8875-53783a7fd2b7",
"attributes": {
"entities": {
"86125a3a-fe8b-45bd-9437-8a2764034062": {
"type": "organization",
"dataSource": { "kind": "Document", "category": "standardExtract" },
"attributes": {
"id": "33302047",
"name": "Company.Info B.V.",
"isActive": true,
"legalForm": "Besloten Vennootschap"
},
"links": {
"profile": "https://api.company.info/v1/organizations/33302047",
"dataSource": "https://api.company.info/v1/documents/MDFLUlg2NlpaS..."
}
},
"1914bd64-7e3d-4aa9-92f1-676da47c08aa": {
"type": "individual",
"dataSource": { "kind": "Document", "category": "standardExtract" },
"attributes": {
"firstNames": "Mildred",
"lastName": "Litz-Hutten",
"fullName": "Mildred Stefanie Litz-Hutten",
"dateOfBirth": "1974-12-11"
}
}
},
"connections": [
{
"from": "1914bd64-7e3d-4aa9-92f1-676da47c08aa",
"to": "86125a3a-fe8b-45bd-9437-8a2764034062",
"meta": {
"roles": [{ "type": "GEVOLMACHTIGDE", "startRoleDate": "2026-03-01" }]
}
}
],
"classification": {
"status": { "phase": "done" },
"result": [
{
"from": "1914bd64-7e3d-4aa9-92f1-676da47c08aa",
"to": "86125a3a-fe8b-45bd-9437-8a2764034062",
"functionType": ["GEVOLMACHTIGDE"],
"label": "UBOGateway"
}
]
}
}
}Error Handling
All errors follow the RFC 9457 Problem Details format.
Example error response:
{
"type": "https://api.company.info/problems/not-found",
"title": "Not Found",
"status": 404,
"detail": "Order with ID 3e02855b-6c6d-44da-8d8f-42137f54eaf7 was not found"
}HTTP status codes:
| Status | Description |
|---|---|
201 Created | Order was created successfully |
200 OK | Request succeeded |
400 Bad Request | Invalid request body or parameters — check detail for specifics |
404 Not Found | The requested order does not exist |
500 Internal Server Error | An unexpected server-side error occurred |
Endpoints Summary
| Method | Path | Description |
|---|---|---|
POST | /nl/organizations/ubo-investigations/v1/orders | Create a new investigation order |
GET | /nl/organizations/ubo-investigations/v1/orders | List all orders (filter by reference) |
GET | /nl/organizations/ubo-investigations/v1/orders/{id} | Get a single order and its status |
GET | /nl/organizations/ubo-investigations/v1/orders/{id}/receipt | Get resource usage receipt for a completed order |
GET | /nl/organizations/ubo-investigations/v1/orders/{id}/result | Download the full investigation result |
Glossary
| Term | Definition |
|---|---|
| UBO | Ultimate Beneficial Owner — the natural person(s) who ultimately own or control a legal entity, typically through shareholding or other means of control. |
| UBO (label) | A confirmed UBO: a natural person with a direct or indirect ownership stake or control position. |
| UBO Gateway | A person or entity that is not the final UBO but through whom ownership passes (an intermediary holding entity or proxy). |
| UBO Suspect | A person who may be a UBO but could not be fully confirmed due to incomplete data. |
| Entity | Any node in the ownership graph: an organization, individual, foreignOrganization, or unknown. |
| Connection | A directed relationship between two entities, with one or more role types (e.g., shareholder, director). |
| Order | An investigation request. Identified by a UUID, it tracks the async processing lifecycle. |
| Receipt | A summary of the resources consumed by an order: documents ordered/reused and profiles visited. |
Updated about 23 hours ago
