Skip to main content

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.

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:
1

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).
2

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

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.

Request an ownership tree

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

Parameters

ParameterTypeRequiredDescription
CompanyCodepathYesThe codeField of the root entity, obtained from Company Search
CountryIsopathYesTwo-letter ISO country code for the root entity’s jurisdiction
regAuthqueryConditionalRequired when the search returns a registrationAuthorityCodeField (e.g. for DE, CA)
maxCreditCostqueryYesMaximum credits to spend on this request. Must be a positive integer
uboThresholdqueryNoOwnership percentage required to qualify as a UBO. Defaults to 25. Accepts 1–100
maxLayersqueryNoMaximum ownership layers to unwrap. Minimum value: 3
continuationKeysqueryNoOne or more continuation keys to resolve previously ambiguous entity matches

Response

{
  "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.
curl --location \
  'XXXX/list/2614793' \
  --header 'Authorization: {{apiKey}}'
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.

Ownership tree status values

StatusDescription
IN_PROGRESSAnalysis is running. Continue polling
SUCCESSOwnership tree completed
COMPANY_NOT_FOUNDThe root company could not be located
NO_SHAREHOLDERSThe root company has no shareholder data available
REGISTRY_NOT_AVAILABLEThe relevant registry was unavailable at the time of the request
INSUFFICIENT_CREDITSInsufficient credits to retrieve the root company’s Enhanced Profile
INSUFFICIENT_MAX_CREDIT_COSTThe maxCreditCost was reached before the root profile could be retrieved
INSUFFICIENT_MAX_LAYERSThe configured layer limit was reached
ORDER_NOT_FOUNDThe specified order ID does not exist
SERVICE_UNAVAILABLEUBO Verify is temporarily unavailable

Understanding the response

A completed ownership tree response contains several distinct sections. The following example illustrates the key fields:
{
  "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.
FieldDescription
levelFieldDepth in the ownership tree. Level 1 is the root company
entityField.idFieldUnique node identifier, consistent across polling requests
entityField.typeFieldCOMPANY, PERSON, or OTHER
entityField.nameFieldEntity name
entityField.countryISOFieldJurisdiction of the entity
entityField.companyCodeFieldCompany registration number (companies only)
entityField.addressFieldRegistered address, when available from Enhanced Profile data
edgesFieldShareholding relationships connecting this node to its parent

Edges

Each edge records the shareholding relationship between a parent entity and a child shareholder.
FieldDescription
nodeIdFieldThe ID of the shareholder node
typeFieldAlways SHAREHOLDER
percentageFieldPercentage ownership held at this edge
nameFieldShareholder name as recorded in the parent company’s declarations
addressFieldShareholder address as recorded in the parent company’s declarations
isCircularFieldtrue if circular ownership is detected
shareholdingsFieldBreakdown of individual shareholding entries, including jointly held shares
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.

Jointly held shares

In jurisdictions such as Australia and New Zealand, shares may be held jointly. The shareholdingsField on an edge captures this:
"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.
StatusMeaning
COMPLETE_UBO_IDENTIFIEDAll UBOs above the threshold have been identified
COMPLETE_BELOW_THRESHOLDAnalysis is complete, but no entities reached the UBO threshold
INCOMPLETE_REQUIRED_PROFILESAdditional Enhanced Profiles need to be purchased to continue
INCOMPLETE_NO_SHAREHOLDERSThe root company has no shareholder data available
INCOMPLETE_BLOCKING_RFNCOne or more nodes have reasons for non-continuation that require action
INCOMPLETE_CIRCULAR_OWNERSHIPA circular ownership structure has been detected
INDETERMINATE_CORRUPT_DATAShareholder data from the registry is corrupt
INDETERMINATE_INSUFFICIENT_DATAShareholding coverage is below the required threshold for conclusive analysis
PLC_NO_SHAREHOLDERS_EXPECTEDThe root entity is a public company; absence of shareholder data is expected
UNKNOWNFallback 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:
"metricsField": {
  "uboCoverageField": 46.14,
  "shareholdingCoverageField": 100.0,
  "unpurchasedTotalField": 24.06
}
MetricDescription
uboCoverageFieldPercentage of root company ownership traced to identified UBOs
shareholdingCoverageFieldPercentage of the ownership tree that has been explored. For a conclusive analysis, this should exceed 100 - uboThreshold
unpurchasedTotalFieldPercentage 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:
"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.
"potentialBeneficialOwnersField": [
  {
    "canonicalNameField": "JONATHAN DAVIES",
    "totalOwnershipField": 29.62,
    "isFuzzyGroupField": true,
    "membersField": [
      { "nameField": "Jonathan Gray Davies", "ownershipField": 5.56 },
      { "nameField": "J. Davies", "ownershipField": 24.06 }
    ]
  }
]
FieldDescription
canonicalNameFieldRepresentative name chosen for the group
totalOwnershipFieldCombined ownership percentage across all group members
isFuzzyGroupFieldtrue if members were grouped by name similarity; false if exact name matches
membersFieldIndividual entries contributing to the group
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.

Entity resolution

UBO Verify matches company names from shareholder declarations against registered entities globally. Version 2 introduces a stricter resolution algorithm that 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:
"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:
"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:
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:
"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.
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.

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:
"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:
{
  "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.
TypeDescriptionRecommended action
COMPANY_NOT_FOUNDThe entity could not be uniquely resolved. May include candidates if partial matches were foundReview candidatesField and continue using the appropriate continuation key
INSUFFICIENT_MAX_CREDIT_COSTThe maxCreditCost limit was reached before this node could be retrievedResubmit with a higher maxCreditCost. Previously purchased profiles within the 24-hour window are reused
REGISTRY_NOT_AVAILABLEThe registry was temporarily unavailableRetry after a short delay. If the issue persists, contact support
NO_SHAREHOLDERSThe Enhanced Profile for this entity contains no shareholder dataManual research required. The registry may not publish shareholding information for this entity
INSUFFICIENT_CREDITSThe account has insufficient creditsContact your account manager
DESERIALIZATION_ERROR_ENHANCED_PROFILEA technical error occurred processing the Enhanced Profile responseRetry. If the error persists, contact support with the order ID
SERVER_ERRORThe Enhanced Profile API returned an HTTP 500 errorRetry after a short delay
UNSUPPORTED_JURISDICTIONThe entity’s jurisdiction is not supported by UBO VerifyManual research required. See Supported jurisdictions
INSUFFICIENT_MAX_LAYERSThe configured maxLayers depth was reachedIncrease maxLayers if deeper analysis is required
SHAREHOLDING_TOO_LOWA shareholder has a recorded ownership percentage of exactly 0%Review whether this is a data quality issue. This branch cannot be automatically continued
INVALID_REGAUTHThe regAuth parameter provided is invalidVerify that the regAuth value matches the registrationAuthorityCodeField returned by search
POSSIBLE_PLCThe company name format suggests a publicly listed companyVerify 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

CodeMessageDescription
201SUCCESSOwnership tree request accepted
403You have insufficient permissions to access UBO VerifyUBO Verify is not enabled on your account
404Resource not foundMissing ISO or company code
107MaxCreditCost is requiredThe maxCreditCost parameter was not provided
107Invalid jurisdictionThe CountryIso provided is not valid
105Company not foundThe CompanyCode provided could not be found or is not in the correct format
107MaxCreditCost must be an integer greater than 0Invalid maxCreditCost value
107UboThreshold must be a whole number between 0 - 100Invalid uboThreshold value

List endpoint

CodeMessageDescription
200Successful retrieval (covers in-progress and completed states)
403Service unavailableUBO Verify is temporarily unavailable
403Order not foundThe UBO Verify feature is not enabled, or the order ID is invalid

Company Search

Find the root entity and retrieve its codeField before requesting an ownership tree

Enhanced Profile

Retrieve full company profiles including representatives and shareholders

UBO Verify API Reference

Full request and response schema for the UBO Verify endpoints

UBO Verify Release Note

Summary of all changes introduced in v2