> ## Documentation Index
> Fetch the complete documentation index at: https://developer.kyckr.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Retrieve Ultimate Beneficial Ownership

> Ultimate beneficial ownership as declared by companies to government registers: the owners and the interests they hold, with Kyckr's normalised values alongside what the register gave.

A beneficial ownership profile is a company's declaration to the central register of beneficial owners in its country: the register to which a company declares who ultimately owns or controls it. Kyckr retrieves the declaration directly from the official register when you order, so it reaches you independently of the customer. Where the register states how current the declaration is, `dataAsOfDate` carries that date.

> [!NOTE]
>
> To access ultimate beneficial ownership you must qualify for Legitimate Interest under the EU AML framework (AMLR). For more details, please speak to your Account Manager.

This article covers where declared beneficial ownership fits, how to order it, and how to read the response. For every field, see the [UBO Register Profile reference](https://developer.kyckr.com/bo-v2/schemas/bo-profile.md) and the [Order a UBO Register Profile](https://developer.kyckr.com/api-reference/operations/order-a-ubo-register-profile.md) endpoint.

***

## Where declared beneficial ownership fits

The draft regulatory technical standards on customer due diligence from AMLA, the EU Anti-Money Laundering Authority, treat the central register as a source to consult and to identify beneficial owners from, and look to a different, independent source to verify them, with the business register named first. Kyckr's guide [What AMLA's Rules Say About KYB Data, Documents and Sources](https://kyckr.com/guides-and-reports/what-the-amla-says-about-kyb-data-and-documents) covers the regulatory detail.

> [card] Control beyond shareholding
>
> Voting rights, board appointment rights and trust roles: interests that share-capital analysis alone does not reveal.

> [card] Trusts and foundations
>
> Settlors, trustees, protectors and beneficiaries, where the register discloses them.

> [card] Audit trail
>
> Each classification sits beside the register's own text, or the register's documented meaning of a code, and the UBO Register Profile PDF gives a document record of the declaration. Together they show what was disclosed and how it was interpreted.

> [card] Screening
>
> The declared owners' names, birth details and nationalities, where the register discloses them, feed sanctions and PEP screening of the people behind the company.

### Declared ownership and the ownership chain

Company registers are a source separate from the central register of beneficial owners: the company profile for each entity in a chain carries details such as its legal form, jurisdiction and shareholdings, and Ownership Discovery traverses that chain from share-capital data to calculate ultimate beneficial owners.

| | Declared beneficial ownership | Ownership Discovery |
| - | - | - |
| **Source** | Central registers of beneficial owners | Company registers |
| **Method** | Direct retrieval of the company's declaration | Ownership chain traversal from share-capital data |
| **Output** | Beneficial owners as the company declared them | Ultimate beneficial owners calculated through the chain |
| **Interests covered** | Ownership, control and trust interests | Shareholdings |
| **Coverage** | Jurisdictions with a central register of beneficial owners | Jurisdictions with ownership data |

Together they give two independent accounts of ownership: the company's declaration from the central register of beneficial owners, and the ownership chain from company registers.

***

## How it works

The workflow has three steps:

1. **Search**: find the company and obtain its `kyckrId`.
2. **Order**: place an order against the company.
3. **Collect**: poll the order, then download the completed profile as JSON, as a PDF, or both.

To see which countries you can order beneficial ownership profiles for, visit the [Kyckr Coverage Portal](https://coverage.kyckr.com).

Ordering is always asynchronous: the profile is never returned inline, and collection is the same in every jurisdiction.

All orders are managed through the [Company V2 orders system](https://developer.kyckr.com/api-reference/orders/get-single-order.md), the same ordering, billing, and retrieval mechanism used by every other Kyckr product.

### Placing an order

```bash theme={null}
curl --location --request POST 'https://api.kyckr.com/v2/companies/FR|MTIzNDU2Nzg5/uboregister' \
--header 'Authorization: Bearer {{apiKey}}' \
--header 'Content-Type: application/json' \
--data '{
  "customerReference": "BO-2026-001"
}'
```

The response is `202 Accepted` and returns an `orderId`:

```json theme={null}
{
  "correlationId": "90b271d92b084f0bad3730e828a63d39",
  "timeStamp": "2026-03-09T10:20:00Z",
  "data": {
    "status": "Pending",
    "orderId": 12345,
    "cost": { "type": "credit", "value": 1 }
  }
}
```

> [!WARNING]
>
> Each successful `POST` places a new, chargeable order. If a request times out or fails with a `5xx` status, don't send it again straight away: first check [`GET /v2/orders`](https://developer.kyckr.com/api-reference/orders/get-list-of-orders) for an order carrying your `customerReference`, and only place a new order if there isn't one.

### Retrieving the result

Poll `GET /v2/orders/{orderId}` until `status` is `Success`:

```bash theme={null}
curl --location 'https://api.kyckr.com/v2/orders/12345' \
--header 'Authorization: Bearer {{apiKey}}'
```

| Status | Meaning |
| - | - |
| `Success` | Order completed. Download the profile using the order's `links`. |
| `Pending` | Order placed, awaiting fulfilment from the register. Poll again. |
| `Failed` | Order could not be fulfilled. Check `failureReason` for the reason. |

Poll at an interval of 30 seconds or longer, and lengthen the interval while the order stays `Pending`.

A completed order carries two links:

```json theme={null}
"links": {
  "data": "/orders/12345/download?format=json",
  "document": "/orders/12345/download?format=pdf"
}
```

| Link | Returns |
| - | - |
| `links.data` | The beneficial ownership profile as JSON (`application/json`) |
| `links.document` | The UBO Register Profile as a PDF (`application/pdf`), named `{orderId}.pdf` |

Until the order is `Success`, a download returns `204 No Content` with no body.

Download the JSON profile:

```bash theme={null}
curl --location 'https://api.kyckr.com/v2/orders/12345/download?format=json' \
--header 'Authorization: Bearer {{apiKey}}'
```

The JSON response body is the profile itself. Its `_payloadType` is `BOProfile_v2`, and the order's product is `UBO_Register_Profile`, so code that handles order results generically across products can tell what it received. `schemaVersion` gives the version of the profile schema the payload follows, as a semantic version such as `1.0.0`; the version number on the API reference describes the documentation of the whole API, not an individual profile.

Download the PDF:

```bash theme={null}
curl --location 'https://api.kyckr.com/v2/orders/12345/download?format=pdf' \
--header 'Authorization: Bearer {{apiKey}}' \
--output 12345.pdf
```

### Testing

In the [test environment](https://developer.kyckr.com/company-v2/guides/test-environment.md) (`https://test-api.kyckr.com/v2`), ordering a beneficial ownership profile returns a single anonymised, redacted profile that reflects the structure of a typical entity, so you can build and test the order, poll and download flow end to end.

### Errors

| Status | When | What to do |
| - | - | - |
| `400` | The request is invalid, for example a malformed `kyckrId` | Correct the request |
| `401` | The `Authorization` header is missing or not recognised | Send a valid API key as a Bearer token |
| `402` | The account is not able to place the order | Speak to your Account Manager |
| `403` | The account is not entitled to beneficial ownership profiles, for example because Legitimate Interest has not been granted. Downloads check this again, so it also applies if access is removed after the order was placed | Speak to your Account Manager |
| `404` | The company or order was not found, or beneficial ownership profiles aren't available in the company's country (title `Registry Unavailable`) | Check the `kyckrId` or `orderId`, and the [Kyckr Coverage Portal](https://coverage.kyckr.com) |
| `429` | Too many requests were sent in a short period | Wait, then retry with a longer interval |
| `503` | The register is unavailable | Retry later, and check [status.kyckr.com](https://status.kyckr.com) |

An order whose `status` is `Failed` carries the reason in `failureReason`. Placing the order again creates a new, chargeable order. See [Response Codes](https://developer.kyckr.com/company-v2/guides/response-codes.md) for the error format shared by all V2 endpoints.

***

## Understanding the response

A complete profile, for an example company with one beneficial owner:

```json theme={null}
{
  "_payloadType": "BOProfile_v2",
  "schemaVersion": "1.0.0",
  "subject": {
    "subjectType": "Entity",
    "name": "Example Holdings SAS",
    "registrationNumber": "123456789",
    "jurisdiction": "FR",
    "status": { "original": null, "normalized": "Active" },
    "legalForm": { "original": "5710 (SAS, société par actions simplifiée)", "normalized": "Private Limited Company" },
    "addresses": [
      {
        "type": "Registered Address",
        "fullAddress": "1 Rue de l'Exemple, 75001 Paris, France",
        "streetNumber": "1",
        "streetName": "Rue de l'Exemple",
        "city": "Paris",
        "postcode": "75001",
        "country": "France",
        "isoCode": "FR"
      }
    ],
    "incorporationDate": { "original": "2015-03-12", "normalized": "2015-03-12" }
  },
  "registryInfo": {
    "registryName": "Registre National des Bénéficiaires Effectifs (RBE)",
    "dataAsOfDate": "2025-06-03T00:00:00Z",
    "extractedAt": "2025-06-04T09:15:00Z"
  },
  "interestedParties": [
    {
      "partyId": "FR:a1b2c3d4e5f6a7b8",
      "partyIdBasis": "DerivedDigest",
      "partyType": "Individual",
      "name": "Jane Example",
      "disclosure": { "status": "Partial" },
      "birthDate": { "original": "1980-05", "normalized": null },
      "birthYear": 1980,
      "nationalities": ["FR"],
      "countryOfResidence": "FR",
      "interests": [
        {
          "type": { "original": "Détention de capital direct", "normalized": "Shareholding" },
          "share": { "exact": 60.00, "original": "60.0%" },
          "directOrIndirect": { "original": null, "normalized": "Direct" },
          "heldAs": "Self",
          "hasSignificantControl": true,
          "startDate": "2025-06-03T00:00:00Z"
        },
        {
          "type": { "original": "Droits de vote directs", "normalized": "VotingRights" },
          "share": { "exact": 60.00, "original": "60.0%" },
          "directOrIndirect": { "original": null, "normalized": "Direct" },
          "heldAs": "Self",
          "hasSignificantControl": true,
          "startDate": "2025-06-03T00:00:00Z"
        }
      ],
      "totalOwnership": { "exact": 60.00, "original": "60.0%" },
      "totalVotingRights": { "exact": 60.00, "original": "60.0%" }
    }
  ],
  "registerStatements": []
}
```

### Company and register metadata

The `subject` object identifies the entity or arrangement the profile describes: legal name, registration number, jurisdiction, and where available its addresses, legal form, status, and incorporation date. The `kyckrId` is not repeated: it is the path parameter you ordered with.

The `registryInfo` object describes the currency and provenance of the data:

| Field | Description |
| - | - |
| `registryName` | Name of the government beneficial ownership register |
| `dataAsOfDate` | Date the register itself states the data is current as of: the register's own clock, for example `2025-06-03T00:00:00Z`. The register records a date, so use the date part. Null where a register makes no such currency claim |
| `extractedAt` | When Kyckr took this extract from the register: Kyckr's clock, distinct from `dataAsOfDate`. Null where not recorded |

These are two different clocks and can differ significantly: a register's stated currency date can be months or even years old, for example under an annual filing cycle.

### Interested parties

`interestedParties` is a single array of parties. Each carries a `partyType` of `Individual`, `Entity`, `Arrangement` or `Unknown`, so a trust or other legal arrangement holding an interest has somewhere to go rather than being forced into a company shape. Type-specific fields (date of birth for a person, for example) are present only where they apply. Where a party is itself a registered company, its registration number and issuing authority are carried in `identifiers[]`, the same way as for any other party.

Each party carries `totalOwnership` and `totalVotingRights`: the register's own stated total where it gives one, otherwise the sum of the party's interests that have not ended.

The profile carries the register's current position: the parties currently holding an interest in the subject, each with its current interests, and the statements in force.

### Interests

Each owner has an `interests` array. A single person may hold several distinct interests, such as shares and voting rights.

Each interest's `type` pairs what the register gave with Kyckr's normalisation of it:

```json theme={null}
"type": {
  "original": "Treugeber (Settlor), Trustee oder Protektor (§ 3 Abs. 3 Nr. 1 GwG)",
  "normalized": "Settlor"
}
```

| Field | What it carries |
| - | - |
| `original` | The register's own text, or the register's documented meaning of a code it sends. Null where the register supplies neither |
| `normalized` | The interest in Kyckr's vocabulary |

The normalised values carry the meanings of the [Beneficial Ownership Data Standard (BODS) v0.4](https://standard.openownership.org/en/0.4.0/) `interestType` codelist. Each value is the BODS code with its first letter capitalised: BODS `shareholding` is `Shareholding`.

`original` matters where a register category spans several roles. The German example above names settlor, trustee and protector in a single category; the normalisation resolves it to `Settlor`, and `original` shows what was actually disclosed.

The full vocabulary, grouped by what the interest asserts:

> [accordion] Ownership and economic interests
>
> | Value | Description |
> | - | - |
> | `Shareholding` | Economic interest via holding shares |
> | `RightsToSurplusAssetsOnDissolution` | Right to a share of surplus assets on winding up |
> | `RightsToProfitOrIncome` | Right to profits or income beyond those implied by ownership structure, granted by contract |
> | `RightsGrantedByContract` | An interest granted by contract |
> | `ConditionalRightsGrantedByContract` | An interest that exists only if a contractual condition is met |
> | `EnjoymentAndUseOfAssets` | Use of assets belonging to the entity |
> | `RightToProfitOrIncomeFromAssets` | Right to derive profits or income from the entity's assets |

> [accordion] Control interests
>
> | Value | Description |
> | - | - |
> | `VotingRights` | Controlling interest via the right to vote on matters of corporate policy |
> | `AppointmentOfBoard` | Absolute right to appoint members of the board of directors |
> | `OtherInfluenceOrControl` | Influence or control distinct from shareholding, voting rights, or the right to appoint to the board |
> | `SeniorManagingOfficial` | Control as the person exercising control over management of the entity |
> | `ControlViaCompanyRulesOrArticles` | Control via a provision in company articles or a shareholder agreement |
> | `ControlByLegalFramework` | Control established through a legal framework, such as legislation |
> | `BoardMember` | Member of the strategic decision-making body of the organisation |
> | `BoardChair` | The person holding the most power and authority on the board |
> | `Nominee` | A person acting on behalf of a nominator in a specified capacity |
> | `Nominator` | A person instructing a nominee to act on their behalf |

> [accordion] Trust and legal arrangement roles
>
> | Value | Description |
> | - | - |
> | `Settlor` | Person who creates a trust (also trustor, grantor, donor). Also used for settlor-equivalent roles in similar arrangements, including a foundation founder |
> | `Trustee` | Person who administers a trust for a third party |
> | `Protector` | Person appointed to protect the settlor's interests, with oversight of the trustee |
> | `BeneficiaryOfLegalArrangement` | Person who benefits from a trust or other legal arrangement |

> [accordion] Metadata
>
> | Value | Description |
> | - | - |
> | `UnknownInterest` | The party is known to have an interest but its nature is unknown |
> | `UnpublishedInterest` | The nature of this interest is known but is not published |

#### Interest details

Beyond its `type`, each interest can carry:

| Field | Description |
| - | - |
| `share` | Ownership percentage, as a `ShareRange` (see below). For a `VotingRights` interest, this carries the voting-rights quantum instead; there is no separate voting-rights field |
| `shareClass` | Share class (e.g., "Ordinary", "Preference"), where reported |
| `hasSignificantControl` | Whether the interest meets the jurisdiction's "significant control" threshold. **Orthogonal to `type`**: a `Shareholding` or `VotingRights` interest can independently qualify |
| `directOrIndirect` | How directly the interest is held (see below) |
| `heldAs` | The capacity in which the interest is held: `Self` (the default, and the meaning when `heldAs` is omitted), `Trust`, `Firm`, `ControlOverTrust`, `ControlOverFirm`, or `Nominee`. Orthogonal to `type`: a shareholding can be held directly or as trustee |
| `trustDetails` | The trust's own attributes (name, type), where a register publishes them. Supplementary to `type` and `heldAs`, which are authoritative for a party's role in the trust |
| `startDate` / `endDate` / `lastChangedDate` | When the interest began, ended, and was last modified in the register, as date-times such as `2025-06-03T00:00:00Z`. The register records dates, so use the date part |

### Share ranges

Registers frequently disclose banded ownership rather than exact figures, so percentages use a `ShareRange`. Percentages are expressed to two decimal places.

```json theme={null}
"share": { "exact": 75.00 }
```

When only a range is available:

```json theme={null}
"share": {
  "minimum": 25.00,
  "maximum": 50.00,
  "exclusiveMinimum": false,
  "exclusiveMaximum": false,
  "original": "25-50%"
}
```

An open-ended band such as "more than 25%" has a `minimum` and no `maximum`:

```json theme={null}
"share": {
  "minimum": 25.00,
  "maximum": null,
  "exclusiveMinimum": true,
  "original": "more than 25%"
}
```

`exact` is null when only a range is available, and `minimum`/`maximum` are null when an exact figure is known: check `exact` first, then fall back to the range.

### Direct vs indirect ownership

`directOrIndirect` follows the same `original` / `normalized` shape as `type`. The values are the BODS v0.4 `directOrIndirect` codes with the first letter capitalised; `Both` expresses a case BODS does not:

| `normalized` | Description |
| - | - |
| `Direct` | Intermediate entities or agents are known not to exist |
| `Indirect` | The interest is held via one or more intermediate entities |
| `Unknown` | Neither is known |
| `Both` | Held through direct and indirect means simultaneously |

### Statements from the register

An empty `interestedParties` is itself information. The `registerStatements` array carries what the register states about the subject's beneficial ownership declaration, most commonly why no owner is listed. A profile may carry several statements, and statements can accompany identified parties rather than replacing them.

Statements are either subject-level (`linkedPartyId` null) or about one specific party (`linkedPartyId` set), independent of `interestedParties`. To show a name for a party-linked statement, match `linkedPartyId` against `interestedParties[].partyId` and use that party's `name`.

Each statement's `type` uses the same `original` / `normalized` shape. Examples of each kind of statement, with the register's own wording:

```json theme={null}
"registerStatements": [
  {
    "type": {
      "original": "The company has no beneficial owners (persons)",
      "normalized": "NoBeneficialOwners"
    },
    "linkedPartyId": null
  },
  {
    "type": {
      "original": "Pakollinen ilmoitus puuttuu",
      "normalized": "NotFiled"
    },
    "linkedPartyId": null
  },
  {
    "type": {
      "original": "The company has actual beneficial owners",
      "normalized": "BeneficialOwnersDeclared"
    },
    "linkedPartyId": null
  },
  {
    "type": {
      "original": "There are deficiencies in the company's beneficial owner details",
      "normalized": "BeneficialOwnerDiscrepancy"
    },
    "linkedPartyId": null
  },
  {
    "type": {
      "original": "A person in the company is on the financial sanctions list",
      "normalized": "PersonSanctioned"
    },
    "linkedPartyId": null
  }
]
```

The statement vocabulary falls into three kinds: absence, which explains why no beneficial owner is listed; declaration, which confirms a filing occurred; and register flags, raised independently of either. The normalised values carry the meanings of the BODS v0.4 `unspecifiedReason` codelist, again with the first letter capitalised, plus further register-recorded statements about the subject's declaration:

| `normalized` | Description |
| - | - |
| `NoBeneficialOwners` | Filed a declaration stating there are no registrable beneficial owners, e.g. widely held, state-owned, or below-threshold ownership |
| `SubjectUnableToConfirmOrIdentifyBeneficialOwner` | The company has been unwilling or unable to confirm or identify a beneficial owner |
| `SubjectExemptFromDisclosure` | The company is not required to disclose its beneficial owner |
| `InterestedPartyExemptFromDisclosure` | The beneficial owner is exempt from having their identity disclosed |
| `InterestedPartyHasNotProvidedInformation` | The beneficial owner has not provided enough information to be identified |
| `Unknown` | The reason is not known |
| `InformationUnknownToPublisher` | The register does not have access to this information |

Kyckr extensions, beyond BODS v0.4:

| `normalized` | Description |
| - | - |
| `BeneficialOwnerDiscrepancy` | The subject's beneficial ownership details contain a discrepancy, as recorded by the register, for example following a discrepancy report |
| `PersonSanctioned` | The register records that a person connected with the subject is on a financial sanctions list. `linkedPartyId` identifies the person where the register names them |
| `SubjectSanctioned` | The subject is on a financial sanctions list, as recorded by the register |
| `AuthorityDetailsDiffer` | The subject's beneficial ownership details differ from those held by the authorities, as recorded by the register |
| `BeneficialOwnersDeclared` | The subject has declared its beneficial owners to the register |
| `NotFiled` | No beneficial ownership declaration has been received by the register, although one is required |

***

## Data quality considerations

* Field availability varies significantly by jurisdiction. A field populated for one register may be absent from another.
* An omitted field means the same as that field with a null value. Treat the two identically. The one exception is `heldAs`, which means `Self` when omitted.
* Enumerated values can grow as registers are added. Treat a value you don't recognise as unknown rather than as an error.
* Names and identifiers are returned as filed. Normalisation is applied to `legalForm`, `status`, interest types, and dates, not to names. An identifier's `type` is free text, not an enumerated value.
* Where a register withholds a party's details, `disclosure.status` records that (`Suppressed` for a party whose details are withheld in full, `Partial` where only some are), and `disclosure.reason` carries the register's own wording for why.
* `dataAsOfDate` reflects the register's own currency claim, not a snapshot date you control, and can be considerably older than the order itself; `extractedAt` is the retrieval-time reference.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.