> ## 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.

# Unwrap Ownership

> Trace corporate ownership structures and identify ultimate beneficial owners across 100+ countries.

UBO Verify automates the analysis of corporate ownership structures, retrieving Enhanced Profiles across jurisdictions and calculating beneficial ownership at each layer of the tree. What would take analysts hours to piece together manually is resolved in minutes.

***

## How it works

UBO Verify works by iteratively retrieving Enhanced Profiles for each entity in the ownership structure of the root company, tracing shareholders layer by layer until it reaches individuals or terminates for a documented reason.

The process follows three steps:

<Steps>
  <Step title="Search for the root company">
    Use Company Search to locate the entity and obtain its `codeField` and jurisdiction ISO. If the search response includes a `registrationAuthorityCodeField`, note this value — it is required when ordering the UBO report for certain jurisdictions (e.g. Germany, Canada).
  </Step>

  <Step title="Request an ownership tree">
    Submit the root company's code, country ISO, and your cost parameters. Kyckr will begin retrieving Enhanced Profiles for each shareholder layer and return an `orderIdField` for polling.
  </Step>

  <Step title="Poll for results">
    Retrieve the ownership tree using the order ID. While the analysis is in progress, the response returns `IN_PROGRESS`. Once complete, the tree, UBO list, coverage metrics, and any recommended next actions are returned.
  </Step>
</Steps>

***

## Request an ownership tree

```bash theme={null}
curl --location \
  'XXXX/create/GB/09657876?uboThreshold=25&maxCreditCost=50&maxLayers=5' \
  --header 'Authorization: {{apiKey}}'
```

### Parameters

| Parameter          | Type  | Required    | Description                                                                           |
| ------------------ | ----- | ----------- | ------------------------------------------------------------------------------------- |
| `CompanyCode`      | path  | Yes         | The `codeField` of the root entity, obtained from Company Search                      |
| `CountryIso`       | path  | Yes         | Two-letter ISO country code for the root entity's jurisdiction                        |
| `regAuth`          | query | Conditional | Required when the search returns a `registrationAuthorityCodeField` (e.g. for DE, CA) |
| `maxCreditCost`    | query | Yes         | Maximum credits to spend on this request. Must be a positive integer                  |
| `uboThreshold`     | query | No          | Ownership percentage required to qualify as a UBO. Defaults to 25. Accepts 1–100      |
| `maxLayers`        | query | No          | Maximum ownership layers to unwrap. Minimum value: 3                                  |
| `continuationKeys` | query | No          | One or more continuation keys to resolve previously ambiguous entity matches          |

### Response

```json theme={null}
{
  "ownershipTreeField": {
    "statusField": "SUCCESS",
    "orderIdField": "2614793"
  },
  "responseCodeField": "201"
}
```

Use the `orderIdField` to retrieve results.

***

## Retrieve the ownership tree

Poll the list endpoint with the `orderIdField` until `statusField` is no longer `IN_PROGRESS`.

```bash theme={null}
curl --location \
  'XXXX/list/2614793' \
  --header 'Authorization: {{apiKey}}'
```

<Note>
  Processing time depends on the depth and complexity of the ownership structure. Shallow trees with a small number of corporate shareholders complete quickly; deep, multi-jurisdiction structures take longer as each layer requires a live Enhanced Profile retrieval.
</Note>

### Ownership tree status values

| Status                         | Description                                                                |
| ------------------------------ | -------------------------------------------------------------------------- |
| `IN_PROGRESS`                  | Analysis is running. Continue polling                                      |
| `SUCCESS`                      | Ownership tree completed                                                   |
| `COMPANY_NOT_FOUND`            | The root company could not be located                                      |
| `NO_SHAREHOLDERS`              | The root company has no shareholder data available                         |
| `REGISTRY_NOT_AVAILABLE`       | The relevant registry was unavailable at the time of the request           |
| `INSUFFICIENT_CREDITS`         | Insufficient credits to retrieve the root company's Enhanced Profile       |
| `INSUFFICIENT_MAX_CREDIT_COST` | The `maxCreditCost` was reached before the root profile could be retrieved |
| `INSUFFICIENT_MAX_LAYERS`      | The configured layer limit was reached                                     |
| `ORDER_NOT_FOUND`              | The specified order ID does not exist                                      |
| `SERVICE_UNAVAILABLE`          | UBO Verify is temporarily unavailable                                      |

***

## Understanding the response

A completed ownership tree response contains several distinct sections. The following example illustrates the key fields:

```json theme={null}
{
  "ownershipTreeField": {
    "idField": "2700226",
    "nameField": "HAND MADE HAIR LTD",
    "statusField": "SUCCESS",
    "uboThresholdField": 25,
    "nodesField": [...],
    "ultimateBeneficialOwnersField": [
      {
        "idField": "907bae93-f2d4-4c8c-95b2-f10fe9c89f2f",
        "nameField": "JOSHUA JOHN WOOD",
        "percentageField": "46.14",
        "entityTypeField": "PERSON"
      }
    ]
  },
  "uboAnalysisField": {
    "statusField": "INCOMPLETE_REQUIRED_PROFILES",
    "metricsField": {
      "uboCoverageField": 46.14,
      "shareholdingCoverageField": 100.0,
      "unpurchasedTotalField": 24.06
    },
    "requiredProfilesField": [...],
    "potentialBeneficialOwnersField": [...]
  }
}
```

### Nodes

The `nodesField` array contains every entity in the ownership tree. Each node represents either a company or a person, with edges describing the shareholding relationship to the node below it.

| Field                          | Description                                                   |
| ------------------------------ | ------------------------------------------------------------- |
| `levelField`                   | Depth in the ownership tree. Level 1 is the root company      |
| `entityField.idField`          | Unique node identifier, consistent across polling requests    |
| `entityField.typeField`        | `COMPANY`, `PERSON`, or `OTHER`                               |
| `entityField.nameField`        | Entity name                                                   |
| `entityField.countryISOField`  | Jurisdiction of the entity                                    |
| `entityField.companyCodeField` | Company registration number (companies only)                  |
| `entityField.addressField`     | Registered address, when available from Enhanced Profile data |
| `edgesField`                   | Shareholding relationships connecting this node to its parent |

### Edges

Each edge records a relationship between a parent entity and a connected entity. An edge is either a `SHAREHOLDER` edge (an ownership relationship, with a percentage) or a `REPRESENTATIVE` edge (a director, officer, or other appointment, with a role).

| Field                | Description                                                                                             |
| -------------------- | ------------------------------------------------------------------------------------------------------- |
| `nodeIdField`        | The ID of the connected node                                                                            |
| `typeField`          | `SHAREHOLDER` for an ownership relationship, or `REPRESENTATIVE` for a directorship/officer appointment |
| `percentageField`    | Percentage ownership held at this edge. Present for `SHAREHOLDER` edges only                            |
| `roleField`          | The role held, e.g. Director or Secretary. Present for `REPRESENTATIVE` edges only                      |
| `nameField`          | Entity name as recorded in the parent company's declarations                                            |
| `addressField`       | Entity address as recorded in the parent company's declarations                                         |
| `isCircularField`    | `true` if circular ownership is detected                                                                |
| `shareholdingsField` | Breakdown of individual shareholding entries, including jointly held shares (`SHAREHOLDER` edges)       |

<Tip>
  The `nameField` and `addressField` on an edge reflect how the parent company recorded that shareholder — which may differ from the entity's canonical name and address. Comparing `edge.nameField` against `node.entity.nameField` helps you identify name variations and verify that the resolved entity is the correct match.
</Tip>

### Jointly held shares

In jurisdictions such as Australia and New Zealand, shares may be held jointly. The `shareholdingsField` on an edge captures this:

```json theme={null}
"shareholdingsField": [
  {
    "isJointlyHeldField": true,
    "jointHoldingGroupIdField": "64cb8fb8-0d07-4546-a92d-b200cd60a91c",
    "percentageField": 17.13
  },
  {
    "isJointlyHeldField": false,
    "percentageField": 0.02
  }
]
```

Entries sharing a `jointHoldingGroupIdField` belong to the same jointly held block.

***

## Analysis insights

The `uboAnalysisField` provides a structured assessment of your UBO discovery, including coverage metrics, recommended next steps, and detection of potential consolidated ownership.

### Analysis status

The `statusField` in `uboAnalysisField` tells you immediately whether the investigation is complete and, if not, what is preventing it.

| Status                            | Meaning                                                                       |
| --------------------------------- | ----------------------------------------------------------------------------- |
| `COMPLETE_UBO_IDENTIFIED`         | All UBOs above the threshold have been identified                             |
| `COMPLETE_BELOW_THRESHOLD`        | Analysis is complete, but no entities reached the UBO threshold               |
| `INCOMPLETE_REQUIRED_PROFILES`    | Additional Enhanced Profiles need to be purchased to continue                 |
| `INCOMPLETE_NO_SHAREHOLDERS`      | The root company has no shareholder data available                            |
| `INCOMPLETE_BLOCKING_RFNC`        | One or more nodes have reasons for non-continuation that require action       |
| `INCOMPLETE_CIRCULAR_OWNERSHIP`   | A circular ownership structure has been detected                              |
| `INDETERMINATE_CORRUPT_DATA`      | Shareholder data from the registry is corrupt                                 |
| `INDETERMINATE_INSUFFICIENT_DATA` | Shareholding coverage is below the required threshold for conclusive analysis |
| `PLC_NO_SHAREHOLDERS_EXPECTED`    | The root entity is a public company; absence of shareholder data is expected  |
| `UNKNOWN`                         | Fallback value — should not occur in practice                                 |

When `statusField` indicates an incomplete analysis, `blockingReasonField` provides additional context explaining specifically what is preventing completion.

### Coverage metrics

The `metricsField` quantifies how complete your analysis is:

```json theme={null}
"metricsField": {
  "uboCoverageField": 46.14,
  "shareholdingCoverageField": 100.0,
  "unpurchasedTotalField": 24.06
}
```

| Metric                      | Description                                                                                                                 |
| --------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `uboCoverageField`          | Percentage of root company ownership traced to identified UBOs                                                              |
| `shareholdingCoverageField` | Percentage of the ownership tree that has been explored. For a conclusive analysis, this should exceed `100 - uboThreshold` |
| `unpurchasedTotalField`     | Percentage of ownership held by entities for which no Enhanced Profile has been purchased                                   |

**Interpreting the metrics:**

* If `shareholdingCoverageField` is 100% but `uboCoverageField` is low, the entire tree has been explored but many branches end at companies without Enhanced Profiles. Use `requiredProfilesField` to identify which profiles to purchase next.
* If `unpurchasedTotalField` is high, there is a clear gap to close. Each profile purchase reduces this value and is likely to improve `uboCoverageField`.

### Required profile recommendations

When further investigation is possible, `requiredProfilesField` provides a ranked list of the entities whose Enhanced Profiles would have the greatest impact on your UBO coverage:

```json theme={null}
"requiredProfilesField": [
  {
    "entityIdField": "9c1b25c1-6a63-427f-8154-05c03a1dbf24",
    "entityNameField": "INDEX VENTURES IX (JERSEY) L.P.",
    "companyCodeField": "REG123"
  }
]
```

Use the `entityIdField` to locate the node in `nodesField` and the `companyCodeField` to retrieve its Enhanced Profile directly if needed.

### Potential beneficial owners

The `potentialBeneficialOwnersField` surfaces cases where the same individual may appear under multiple name variations across different shareholder declarations. Where combined ownership across those variations exceeds the UBO threshold, the system flags this for review.

```json theme={null}
"potentialBeneficialOwnersField": [
  {
    "canonicalNameField": "JONATHAN DAVIES",
    "totalOwnershipField": 29.62,
    "isFuzzyGroupField": true,
    "membersField": [
      { "nameField": "Jonathan Gray Davies", "ownershipField": 5.56 },
      { "nameField": "J. Davies", "ownershipField": 24.06 }
    ]
  }
]
```

| Field                 | Description                                                                      |
| --------------------- | -------------------------------------------------------------------------------- |
| `canonicalNameField`  | Representative name chosen for the group                                         |
| `totalOwnershipField` | Combined ownership percentage across all group members                           |
| `isFuzzyGroupField`   | `true` if members were grouped by name similarity; `false` if exact name matches |
| `membersField`        | Individual entries contributing to the group                                     |

<Warning>
  Fuzzy grouping is based on first name and last name similarity and is conservative by design. You should verify potential UBO matches through additional due diligence before treating them as confirmed.
</Warning>

***

## Entity resolution

UBO Verify matches company names from shareholder declarations against registered entities globally. The resolution algorithm requires address-based or jurisdiction-specific confirmation before automatically selecting a company match.

This means you may encounter more situations requiring manual input — but each resolution will be a high-confidence, verifiable match rather than a potentially incorrect automatic one.

### Automatic resolution

When the algorithm can confidently identify a unique matching entity, it resolves the node automatically. This is indicated in the node's `entitySelectionMetadataField`:

```json theme={null}
"entitySelectionMetadataField": {
  "sourceField": "ALGORITHM"
}
```

### Ambiguous matches and continuation keys

When the algorithm cannot resolve a match with sufficient confidence — for example, when multiple companies share the same name in the same jurisdiction — it returns a `COMPANY_NOT_FOUND` reason for non-continuation and provides candidate options:

```json theme={null}
"reasonForNonContinuationField": {
  "typeField": "COMPANY_NOT_FOUND",
  "detailsField": "Multiple matches with the same name in the same jurisdiction",
  "candidatesField": [
    {
      "companyNameField": "ACME HOLDINGS LTD",
      "companyIdField": "12345678",
      "countryIsoField": "GB",
      "addressField": "123 Business Park, London",
      "continuationKeyField": "ba26a0bb-f632-4421-8092-58ed3a76d3be"
    },
    {
      "companyNameField": "ACME HOLDINGS LIMITED",
      "companyIdField": "87654321",
      "countryIsoField": "GB",
      "addressField": "456 Industrial Estate, Manchester",
      "continuationKeyField": "cd38b1cc-g743-5532-9193-69fe4b87e4cf"
    }
  ]
}
```

To continue the investigation, review the candidates and pass the `continuationKeyField` of the correct entity in a new create request:

```bash theme={null}
curl --location \
  'XXXX/create/GB/12345678?continuationKeys=ba26a0bb-f632-4421-8092-58ed3a76d3be' \
  --header 'Authorization: {{apiKey}}'
```

After selection, the resolved node is marked with `USER_SELECTED`:

```json theme={null}
"entitySelectionMetadataField": {
  "sourceField": "USER_SELECTED",
  "continuationKeyField": "ba26a0bb-f632-4421-8092-58ed3a76d3be",
  "dateSelectedField": "2026-01-15T10:45:00.0000000Z"
}
```

If there are multiple unresolved nodes in the tree, there may be multiple continuation keys. You can pass them as a comma-separated list in a single request.

<Note>
  Only one candidate can be selected per ambiguous node. If you later determine the selection was incorrect, you will need to submit a new create request with a different continuation key.
</Note>

***

## Audit trail

Every ownership tree maintains a complete record of how it was built and how it has evolved through continuations.

### Continuation selection history

The `selectedCandidatesField` documents every manual disambiguation decision made during the investigation:

```json theme={null}
"selectedCandidatesField": [
  {
    "parentNodeIdField": "2e777682-3efc-478f-8472-fd78efb7f60e",
    "candidateField": {
      "companyNameField": "ACME HOLDINGS LTD",
      "companyIdField": "12345678",
      "continuationKeyField": "ba26a0bb-f632-4421-8092-58ed3a76d3be"
    },
    "nodeIdField": "dac4985e-501d-41f7-933b-44c0b8de0f54",
    "dateSelectedField": "2026-01-15T10:45:00.0000000Z",
    "orderIdField": "331999"
  }
]
```

### Version history

The `previousVersionsField` records the chain of order IDs that preceded the current tree:

```json theme={null}
{
  "idField": "331997",
  "previousVersionsField": ["332003", "331999"]
}
```

This allows you to trace every continuation decision back to the initial request, providing a full audit trail for compliance and review purposes.

***

## Reasons for non-continuation

When the ownership tree algorithm cannot continue down a branch, it returns a `reasonForNonContinuationField` on the relevant node. Any layers already discovered are always returned.

| Type                                     | Description                                                                                                                                 | Recommended action                                                                                         |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `COMPANY_NOT_FOUND`                      | The entity could not be found, or multiple companies share the same name. Includes `candidatesField` when ambiguous same-name matches exist | Review `candidatesField` and continue using the appropriate continuation key                               |
| `LOW_CONFIDENCE_MATCH`                   | A single matching company was found, but confidence is insufficient to continue automatically. Includes `candidatesField`                   | Review `candidatesField` and continue using the appropriate continuation key                               |
| `INSUFFICIENT_MAX_CREDIT_COST`           | The `maxCreditCost` limit was reached before this node could be retrieved                                                                   | Resubmit with a higher `maxCreditCost`. Previously purchased profiles within the 24-hour window are reused |
| `REGISTRY_NOT_AVAILABLE`                 | The registry was temporarily unavailable                                                                                                    | Retry after a short delay. If the issue persists, contact support                                          |
| `NO_SHAREHOLDERS`                        | The Enhanced Profile for this entity contains no shareholder data                                                                           | Manual research required. The registry may not publish shareholding information for this entity            |
| `INSUFFICIENT_CREDITS`                   | The account has insufficient credits                                                                                                        | Contact your account manager                                                                               |
| `DESERIALIZATION_ERROR_ENHANCED_PROFILE` | A technical error occurred processing the Enhanced Profile response                                                                         | Retry. If the error persists, contact support with the order ID                                            |
| `SERVER_ERROR`                           | The Enhanced Profile API returned an HTTP 500 error                                                                                         | Retry after a short delay                                                                                  |
| `UNSUPPORTED_JURISDICTION`               | The entity's jurisdiction is not supported by UBO Verify                                                                                    | Manual research required. See [Supported jurisdictions](/company-v1/guides/jurisdictions)                  |
| `INSUFFICIENT_MAX_LAYERS`                | The configured `maxLayers` depth was reached                                                                                                | Increase `maxLayers` if deeper analysis is required                                                        |
| `SHAREHOLDING_TOO_LOW`                   | A shareholder's recorded ownership percentage is too low to continue analysis of that branch                                                | Review whether this is a data quality issue. This branch cannot be automatically continued                 |
| `INVALID_REGAUTH`                        | The `regAuth` parameter provided is invalid                                                                                                 | Verify that the `regAuth` value matches the `registrationAuthorityCodeField` returned by search            |
| `POSSIBLE_PLC`                           | The company name format suggests a publicly listed company                                                                                  | Verify whether the entity is publicly traded. PLCs are typically excluded from UBO analysis requirements   |

***

## Cached Enhanced Profiles

Enhanced Profiles purchased as part of a UBO Verify request are cached for 24 hours. If you resubmit a request — for example, with a higher `maxCreditCost` or an additional continuation key — profiles retrieved within that window are reused, avoiding duplicate purchases.

After 24 hours, all underlying profiles are refreshed to ensure reporting accuracy.

***

## Response codes

### Create endpoint

| Code | Message                                                | Description                                                                   |
| ---- | ------------------------------------------------------ | ----------------------------------------------------------------------------- |
| 201  | SUCCESS                                                | Ownership tree request accepted                                               |
| 403  | You have insufficient permissions to access UBO Verify | UBO Verify is not enabled on your account                                     |
| 404  | Resource not found                                     | Missing ISO or company code                                                   |
| 107  | MaxCreditCost is required                              | The `maxCreditCost` parameter was not provided                                |
| 107  | Invalid jurisdiction                                   | The `CountryIso` provided is not valid                                        |
| 105  | Company not found                                      | The `CompanyCode` provided could not be found or is not in the correct format |
| 107  | MaxCreditCost must be an integer greater than 0        | Invalid `maxCreditCost` value                                                 |
| 107  | UboThreshold must be a whole number between 0 - 100    | Invalid `uboThreshold` value                                                  |

### List endpoint

| Code | Message             | Description                                                       |
| ---- | ------------------- | ----------------------------------------------------------------- |
| 200  | —                   | Successful retrieval (covers in-progress and completed states)    |
| 403  | Service unavailable | UBO Verify is temporarily unavailable                             |
| 403  | Order not found     | The UBO Verify feature is not enabled, or the order ID is invalid |

***

<CardGroup cols={2}>
  <Card title="Company Search" icon="magnifying-glass" href="/documentation/features/search-for-a-company-v1">
    Find the root entity and retrieve its `codeField` before requesting an ownership tree
  </Card>

  <Card title="Enhanced Profile" icon="building" href="/documentation/features/perform-a-kyb-check-v1">
    Retrieve full company profiles including representatives and shareholders
  </Card>

  <Card title="UBO Verify API Reference" icon="code" href="/api-reference/ubo-verify/request-ownership-tree">
    Full request and response schema for the UBO Verify endpoints
  </Card>

  <Card title="UBO Verify Release Note" icon="newspaper" href="/company-v1/developer-news/2026-03-ubo-verify-release-note">
    Summary of the latest UBO Verify enhancements
  </Card>
</CardGroup>
