Relations
Overview
The Relations endpoint retrieves ownership, beneficial ownership, key person roles, and corporate structure relationships for one or more companies. You can search by Valu8 ID, organisation number, national identification number, or country with update-date filters.
Each result is a RelationsCompany containing the company profile plus Parents and Children relationship trees.
Authentication
All requests require authentication. Include your access token in the Authorization header:
Authorization: Bearer <access-token>
If authentication fails, the endpoint returns HTTP 401 Unauthorized.
Request
Request Body
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
SearchParameters | object | ✅ Yes | — | Dictionary of search filters. Each key is a parameter name and each value is an array of filter values. See Section 3.2. |
PageSize | integer | No | 10 | Number of companies per page. Valid range: 1–500. |
Cursor | string | No | null | Cursor-based pagination for large result sets (up to 100,000 companies). See Section 3.3. |
Example request — search by organisation number:
{
"SearchParameters": {
"OrgNo": ["556000-1234"]
},
"PageSize": 10
}Example request — search by country with date filter:
{
"SearchParameters": {
"CountryCode": ["SE"],
"RelationsUpdatedAt": ["2024-01-01", "2024-12-31"]
},
"PageSize": 100
}Search Parameters
The SearchParameters field is a dictionary where each key is a filter name and each value is an array of one or more filter values.
Key rules:
- At least one search parameter is required.
- Parameter names are case-insensitive.
CountryCodevalues must match your authorized countries.NationalIdentificationNumberrequiresCountryCodeto also be specified.- Organisation numbers and national IDs are normalized (whitespace and hyphens removed).
- Date parameters use format
yyyy-MM-ddand accept one value (from date) or two values (from and to date).
| Parameter | Type | Description |
|---|---|---|
Valu8Id | integer | Search by one or more Valu8 internal IDs. Maximum 500 IDs per request. |
OrgNo | string | Organisation/registration number. Hyphens and whitespace are stripped. |
NationalIdentificationNumber | string | Natural persons national ID (for person entities). Requires CountryCode. |
CountryCode | string | ISO country code (e.g., "SE", "NO"). Must be in your authorized set. |
ContentUpdatedAt | date | Filter by content update date. One or two values (yyyy-MM-dd). |
RelationsUpdatedAt | date | Filter by relations update date. One or two values (yyyy-MM-dd). |
Tip: Call
GET /v2/relations/search-parametersto get the up-to-date list of available parameters.
Pagination: Cursor
Relations uses cursor-based pagination only (there is no PageNumber). Use cursor mode when you need to walk through more than a single page of results—for example, a country-wide export or syncing all companies that match your filters.
How cursor pagination works
Each page is a separate POST /v2/relations call. The API returns up to PageSize companies (max 500) and an opaque cursor token in the X-Pagination response header. That token encodes the position in the result set; pass it back on the next request to continue where the previous call left off.
| Step | What to do |
|---|---|
| 1. First request | Set Cursor to "*" (start of result set). Use the same SearchParameters you want for the full run. Prefer PageSize: 500 to minimize the number of round trips. |
| 2. Read response | Parse the X-Pagination header (JSON). See Section 4.2. Append each non-empty Relations array to your local store. |
| 3. Next request | Copy the Cursor value from X-Pagination into the request body. Keep SearchParameters and PageSize unchanged—only the cursor advances. |
| 4. Repeat | Continue until a page returns an empty Relations array, or until X-Pagination.Cursor is null. |
First request example:
{
"Cursor": "*",
"PageSize": 500,
"SearchParameters": {
"CountryCode": ["SE"]
}
}Next request example — use the cursor from the previous response header (value truncated for readability):
{
"Cursor": "eyJTdGFydERDSUQiOjEwMSwiSXRlbUNvdW50ZXIiOjUwMH0=",
"PageSize": 500,
"SearchParameters": {
"CountryCode": ["SE"]
}
}Example X-Pagination header on an intermediate page:
{
"Count": 500,
"TotalCount": 125000,
"PageSize": 500,
"TotalPages": 250,
"Cursor": "eyJTdGFydERDSUQiOjUwMSwiSXRlbUNvdW50ZXIiOjUwMH0="
}On the last page with data, Count may be less than PageSize. When there are no more companies, you typically receive an empty Relations array and Cursor is null in the header.
Integration tips
- Do not invent or modify cursor tokens—they are opaque and validated server-side. A bad token returns
Cursor has not a valid value.(HTTP 400). TotalCountinX-Paginationreflects how many companies match the search; you can use it for progress UI, but always use cursor + emptyRelationsto detect completion.- Small lookups (a few
OrgNoorValu8Idvalues) may omitCursoron the first call and still receive aCursorinX-Paginationif more matches exist. For explicit, full iteration over large sets, always start with"*"and loop until done. - Rate limits apply per request; use
PageSize: 500and reasonable backoff if you receive HTTP 429.
Maximum iteration limit
Cursor pagination is capped at 100,000 companies per search (across all pages in one cursor run). If you keep requesting pages after that cumulative limit, the API returns HTTP 400:
You are not allowed to iterate more than 100000 via cursor.
The limit applies to the same SearchParameters and cursor chain—not per HTTP call. To continue beyond 100,000, start a new search with narrower filters (for example, split by RelationsUpdatedAt date ranges or by region if your use case allows), or use batch files.
Need more than 100,000 companies? If your integration needs a larger dataset—a full-country relations export, periodic full sync, or anything above the cursor cap—use the Batch Files API instead. Batch files are pre-generated bulk exports (JSON Lines, Brotli-compressed) scoped to your account, with no cursor iteration limit. List available files with
GET /v2/batches/batch-files, then download viaGET /v2/batches/batch-file/{batchFileId}. Contact Valu8 support for batch types and schemas that include relations data.
Response
Success Response (HTTP 200)
Returns a GetCompaniesRelationsByCountryCodeOrDcidsResponse JSON body and an X-Pagination header. An empty Relations array is a valid success response when no companies match.
Pagination Header (X-Pagination)
Every successful response includes an X-Pagination HTTP response header:
| Field | Type | Description |
|---|---|---|
Count | integer | Number of companies in the current response. |
TotalCount | integer | Total number of companies matching the search. |
PageSize | integer | The requested page size. |
TotalPages | integer | Total number of pages available. |
Cursor | string | Cursor token for the next request. null when no more results. |
Example header:
{
"Count": 100,
"TotalCount": 3542,
"PageSize": 100,
"TotalPages": 36,
"Cursor": "eyJTdGFydERDSUQiOjEwMSwiSXRlbUNvdW50ZXIiOjEwMH0="
}Validation Error Response (HTTP 400)
{
"type": "https://datatracker.ietf.org/doc/html/rfc9110#name-400-bad-request",
"status": 400,
"title": "One or more validation errors occurred.",
"errors": {
"parameters": [
"Searchparameters are missing."
]
}
}Common validation errors:
| Error Message | Cause |
|---|---|
Searchparameters are missing. | SearchParameters is null or empty. |
Pagesize is invalid (Maximum pagesize: 500). | PageSize exceeds 500. |
Cursor has not a valid value. | Malformed cursor token. |
You are not allowed to iterate more than 100000 via cursor. | Cursor iteration limit reached. |
{param} is an invalid parameter. | Unrecognized search parameter name. |
{value} is an unauthorized country code. | Country not in your authorized set. |
Valu8Ids can max be set to 500. | Too many Valu8 IDs in one request. |
CountryCode is required when searching with NationalIdentificationNumber. | Missing country for national ID search. |
Invalid date format in ContentUpdatedAt: {value}. | Date not in yyyy-MM-dd format. |
ContentUpdatedAt can only maximum contain two dates. | More than two date values provided. |
Invalid date format in RelationsUpdatedAt: {value}. | Date not in yyyy-MM-dd format. |
RelationsUpdatedAt can only maximum contain two dates. | More than two date values provided. |
Unauthorized Response (HTTP 401)
Returned with an empty body when authentication fails.
Response Body: GetCompaniesRelationsByCountryCodeOrDcidsResponse
| Field | Type | Description |
|---|---|---|
Relations | RelationsCompany[] | Array of companies with their relationship data. See Section 6. |
Note:
ValidationResultsis only included on the HTTP 400 path. On success it is omitted.
RelationsCompany Object
Each item in the Relations array represents a company and its relationship graph.
| Field | Type | Condition | Description |
|---|---|---|---|
Valu8Id | integer | Always | Unique Valu8 identifier. |
Name | string | Omitted when null | Company name. |
OrgNo | string | Omitted when null | Organisation/registration number. |
CountryCode | string | Omitted when null | ISO country code. |
LegalForm | integer | Omitted when 0 | Legal form code. See _v2_companies.md – LegalForm. |
OperationalStatus | integer | Omitted when 0 | Operational status code. See _v2_companies.md – OperationalStatus. |
TotalNumberOfShares | double | Omitted when null | Total issued shares. |
TotalNumberOfVotes | double | Omitted when null | Total voting rights. |
Parents | Relation[] | Omitted when null | Entities that own or control this company. See Section 7. |
Children | Relation[] | Omitted when null | Entities owned or controlled by this company. See Section 7. |
UBODetails | UBODetails | Omitted when null | Ultimate Beneficial Owner registration details. See Section 8. |
Relation Object
Represents a related entity (company or person) in the ownership or control graph. Relations appear in both Parents and Children arrays.
| Field | Type | Condition | Description |
|---|---|---|---|
Valu8Id | integer | Always | Valu8 identifier for the related entity. |
Name | string | Omitted when null | Full name (person or company). |
FirstName | string | Omitted when null | First name (person). |
LastName | string | Omitted when null | Last name (person). |
OrgNo | string | Omitted when null | Organisation number (company). |
BirthDate | string | Omitted when null | Date of birth (person). Masked as "Protected Identity" for protected persons. |
NationalIdentificationNumber | string | Omitted when null | Personal national ID. Masked for protected persons without hidden-person access. |
Gender | string | Omitted when null | Gender (person). |
Citizenships | string[] | Omitted when null | Citizenship country codes. |
CountryOfResidences | string[] | Omitted when null | Country of residence codes. |
Addresses | Address[] | Omitted when null | Registered addresses. See Section 7.4. |
CountryCode | string | Omitted when null | Country code. |
IsCompany | boolean | Omitted when null | true if the entity is a company, false if a person. |
IsSearchableEntity | boolean | Omitted when null | Whether the entity can be searched in Valu8. |
IsProtected | boolean | Omitted when null | Whether the person has a protected identity. |
BeneficialOwnerships | BeneficialOwnership[] | Omitted when null | UBO records. Requires subscription authorization. See Section 7.2. |
Ownerships | Ownership[] | Omitted when null | Direct ownership records. See Section 7.1. |
UltimateOwnerships | Ownership[] | Omitted when null | Ultimate ownership records. |
CompanyStructureOwners | Ownership[] | Omitted when null | Corporate structure ownership records. |
KeyPersonRoles | Role[] | Omitted when null | Board, CEO, and other key person roles. See Section 7.3. |
History | Relation[] | Omitted when null | Historical relationship records. Requires subscription authorization. |
RegistrationDate | datetime | Omitted when null | Entity registration date. |
UpdatedAt | datetime | Omitted when default | Last update timestamp. |
Ownership
| Field | Type | Condition | Description |
|---|---|---|---|
OwnershipStake | double | Omitted when null | Ownership percentage. |
MinOwnershipStake | double | Omitted when null | Minimum ownership percentage (range). |
MaxOwnershipStake | double | Omitted when null | Maximum ownership percentage (range). |
NumberOfShares | double | Omitted when null | Number of shares held. |
NumberOfVotes | double | Omitted when null | Number of votes held. |
MinVotes | double | Omitted when null | Minimum votes (range). |
MaxVotes | double | Omitted when null | Maximum votes (range). |
ShareClass | string | Omitted when null | Share class identifier. |
ProtocolDate | datetime | Omitted when default | Date of the ownership protocol/document. |
InDate | datetime | Omitted when default | Date the ownership became effective. |
OutDate | datetime | Omitted when null | Date the ownership ended (historical). |
UpdatedAt | datetime | Omitted when default | Last update timestamp. |
BeneficialOwnership
Extends Ownership with UBO-specific registration fields.
| Field | Type | Condition | Description |
|---|---|---|---|
| (all Ownership fields) | See Section 7.1. | ||
CaseNo | string | Omitted when null | Registration case number. |
RegistrationId | string | Omitted when null | Registration identifier. |
StatusCode | string | Omitted when null | Registration status code. |
SuspicionDate | string | Omitted when null | Date suspicion was registered. |
SuspicionLevel | string | Omitted when null | Suspicion level. |
SuspicionCaseNo | string | Omitted when null | Suspicion case number. |
SuspicionIssueID | string | Omitted when null | Suspicion issue identifier. |
ProxyCompanyRegistrationNumber | string | Omitted when null | Proxy company registration number. |
ProxyCompanyName | string | Omitted when null | Proxy company name. |
Text | string | Omitted when null | Descriptive text for the UBO record. |
Role (Key Person)
| Field | Type | Condition | Description |
|---|---|---|---|
Id | integer | Always | Role type identifier. |
Text | string | Omitted when null | Role title (e.g., "CEO", "Board Member"). |
Category | string | Omitted when null | Role category. |
InDate | datetime | Omitted when default | Date the role became effective. |
OutDate | datetime | Omitted when null | Date the role ended (historical). |
UpdatedAt | datetime | Omitted when default | Last update timestamp. |
Address
| Field | Type | Description |
|---|---|---|
Street | string | Street name and number. |
ZipCode | string | Postal / zip code. |
City | string | City or town. |
CountryCode | string | Country code. |
UBODetails
Company-level UBO registration summary on RelationsCompany.
| Field | Type | Condition | Description |
|---|---|---|---|
HasReportedMissingUBO | boolean | Always | true if the company has reported missing UBO data. |
CaseNo | string | Omitted when null | Registration case number. |
RegistrationId | string | Omitted when null | Registration identifier. |
Status | string | Omitted when null | Registration status. |
SuspicionLevel | string | Omitted when null | Suspicion level. |
SuspicionDate | string | Omitted when null | Suspicion registration date. |
SuspicionCaseNo | string | Omitted when null | Suspicion case number. |
IsUBOExcluded | boolean | Omitted when null | Whether UBO is excluded from registration. |
Authorization and Data Filtering
The fields returned for each relation depend on your subscription's authorized areas per country. Fields you are not authorized to access are omitted from the response (not returned as null).
| Authorization Area | Fields Controlled |
|---|---|
| Beneficial Owner | BeneficialOwnerships |
| Owner | Ownerships |
| Company Structure Owner | CompanyStructureOwners |
| Key Person | KeyPersonRoles |
| Relations History | History |
| Hidden Person Access | Whether protected identity personal data is masked |
Protected identity handling: When IsProtected is true, personal fields (BirthDate, CountryCode, Addresses, Citizenships, CountryOfResidences) are masked as "Protected Identity". Name and national ID are also masked unless you have Hidden Person Access authorization.
JSON Serialization Behavior
| Value Type | Omission Rule |
|---|---|
null strings/objects | Omitted from response |
0 (integer/double) | Omitted from response |
Default DateTime | Omitted from response |
null nullable types | Omitted from response |
The absence of a field means "no data available" or "not authorized" — not an error.
Companion Endpoint: Search Parameters
Endpoint: GET /v2/relations/search-parameters
Returns all available search parameter names and their data types. Use this endpoint to discover valid filter names before calling the relations search endpoint.
Example response:
{
"SearchParameters": [
{ "ParameterName": "Valu8Id", "Datatype": "number" },
{ "ParameterName": "NationalIdentificationNumber", "Datatype": "string" },
{ "ParameterName": "OrgNo", "Datatype": "string" },
{ "ParameterName": "ContentUpdatedAt", "Datatype": "date", "Description": "..." },
{ "ParameterName": "RelationsUpdatedAt", "Datatype": "date", "Description": "..." },
{ "ParameterName": "CountryCode", "Datatype": "string" }
]
}