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

  1. 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.
  2. The system processes the order by fetching KVK Handelsregister extracts for the target organization and any intermediate entities in the ownership chain.
  3. Poll the order status until the phase is succeeded (or failed).
  4. Fetch the result, which contains a graph of entities, their connections, and the UBO classification.
  5. 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: xxx

API 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

https://api.company.info

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:

FieldTypeRequiredDescription
data.typestringMust be "orders"
data.attributes.organization.idstring8-digit KVK number
data.attributes.dataSources.documents.extract.fromDatedateOnly include documents dated from this date (YYYY-MM-DD)
data.attributes.dataSources.documents.extract.orderIfChangedbooleanRe-order the extract if it has changed since the last retrieved. Defaults to false
data.attributes.referencestringSearchable 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:

ParameterTypeRequiredDescription
referencestringFilter 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:

PhaseDescription
queuedThe order has been accepted and is waiting to be processed
processingThe investigation is actively running
succeededInvestigation completed successfully — result is ready to fetch
failedInvestigation failed — check status.reason and status.message
cancelledThe order was canceled

When phase is Failed, additional fields are included:

FieldDescription
status.reasonOne of: timeout, invalidDocument, documentOrderingFailed, profileFetchFailed, internalError
status.messageHuman-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
      }
    }
  }
}
FieldDescription
extracts[].type: "ordered"Number of new KVK extracts fetched for this investigation
extracts[].type: "reused"Number of previously cached extracts reused
profiles.organizationsNumber 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:

TypeDescription
organizationA Dutch-registered legal entity (BV, NV, etc.)
individualA natural person
foreignOrganizationA legal entity registered outside the Netherlands
unknownEntity 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 optional

The links.profile and links.dataSource fields 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" }
      ]
    }
  }
]
FieldDescription
fromUUID of the entity holding the role
toUUID of the entity being connected to
isCircleWhether the connection leads to a circle
meta.roles[].typeRole type code (e.g., GEVOLMACHTIGDE, ENIGAANDEELHOUDER)
meta.roles[].startRoleDateDate from which the role is effective (YYYY-MM-DD), when available
📘

Role type localization

Role type codes are returned in Dutch by default. To receive role types in another language, add the Accept-Language header 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:

PhaseDescription
doneClassification completed successfully
failedClassification could not be completed — see reason and message

Failure reasons:

ReasonDescription
governmentalCompanyThe organization is a government entity, which is exempt from UBO registration
noPersonFoundNo natural person could be identified as a UBO
unknownAn unexpected error occurred during classification

UBO classification labels:

LabelDescription
UBOA confirmed Ultimate Beneficial Owner — a natural person who directly or indirectly owns or controls the organization
UBOGatewayAn intermediary entity or person through whom ownership passes, but who is not the final UBO
UBOSuspectA 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:

StatusDescription
201 CreatedOrder was created successfully
200 OKRequest succeeded
400 Bad RequestInvalid request body or parameters — check detail for specifics
404 Not FoundThe requested order does not exist
500 Internal Server ErrorAn unexpected server-side error occurred

Endpoints Summary

MethodPathDescription
POST/nl/organizations/ubo-investigations/v1/ordersCreate a new investigation order
GET/nl/organizations/ubo-investigations/v1/ordersList 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}/receiptGet resource usage receipt for a completed order
GET/nl/organizations/ubo-investigations/v1/orders/{id}/resultDownload the full investigation result

Glossary

TermDefinition
UBOUltimate 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 GatewayA person or entity that is not the final UBO but through whom ownership passes (an intermediary holding entity or proxy).
UBO SuspectA person who may be a UBO but could not be fully confirmed due to incomplete data.
EntityAny node in the ownership graph: an organization, individual, foreignOrganization, or unknown.
ConnectionA directed relationship between two entities, with one or more role types (e.g., shareholder, director).
OrderAn investigation request. Identified by a UUID, it tracks the async processing lifecycle.
ReceiptA summary of the resources consumed by an order: documents ordered/reused and profiles visited.


Did this page help you?