Skip to main content

Endpoints and billing

Successful standalone searches using a paid company-data source cost $0.50 per request, regardless of the number of candidates. Empty results, failed searches, and results served only by other sources are not charged. A later profile retrieval is billed separately. Retrieval is sold in three data tiers, one endpoint each, priced per country (per-country prices): select is the Lite tier: it is what a hosted KYB workflow bills for a registry check at the Lite level, and it keeps the contract it has always had. Europe means the EEA, the United Kingdom and Switzerland.
You pay for the tier delivered. Every response carries registry_tier_requested and registry_tier_delivered. When the country’s registries hold no ownership data, or the registry has no ownership record for the selected company, an ownership request is delivered and billed as the highest tier available (usually Lite), and registry_ownership_status says why. A UBO request whose resolved report names no natural person as a beneficial owner is delivered and billed as Shareholders.
Versioning. The Shareholders and UBO endpoints exist on /v3/ only. The standalone search fee also applies to /v2/kyb/search/; profile retrieval is billed separately.

Ownership status

registry_ownership_status says what happened to the ownership part of a Shareholders or UBO request: registry_data.ownership_error names the reason. Two of its values mean different things and must not be read as the same finding: A section the registry did not return is also recorded structurally, under registry_data.section_errors, keyed by section (officers, shareholders, group_structures_full) with the status and the message the registry gave:
section_errors describes the answer you are holding, not the history behind it. A section that was not returned on the first request and is served on a later pass (see the asynchronous retrieval below) loses its entry, so registry_ownership_status, ownership_error and section_errors always agree: a delivered section never has an entry, and no_shareholders_on_record is never accompanied by one for shareholders. A section is also never delivered in part: if the registry serves the first page of a list and then fails to serve a later one, the retrieval is not completed on that attempt - a pending retrieval is retried on its next pass, and a new request is answered with the registry-unavailable error - so a delivered officers or shareholders list is always the whole list the registry holds. Treat a section listed in section_errors as data that was never delivered, never as an empty result: an empty officers or shareholders list next to a section_errors entry for it says nothing about the company.

Ownership retrieved asynchronously

Some registries are queried on demand: the first request for a company the source has never been asked about returns no ownership section while it is fetched, and the data lands within a couple of minutes. Reporting that as “no ownership on record” would understate a company that does have shareholders, so the request comes back pending instead. While a retrieval is pending, fetch_status is also pending and the response status is 202 Accepted. Didit retries the section on its own and finishes the retrieval without any further call from you:
  • once the ownership data arrives, the shareholders and beneficial owners appear on the saved check, registry_tier_delivered becomes the tier that was served, and the usage is charged at that tier;
  • if the section is still empty when the retry window closes, the status becomes unavailable and the request is delivered and billed as Lite.
Keep the request_id and poll GET /v3/session/{request_id}/decision/ until registry_checks[0].company.fetch_status is resolved. Do not repeat the retrieval request while it is pending: every new POST is a separate, separately billable request. Use POST /v3/kyb/search/ to find candidate companies. Search does not create a saved check. The search tier input picks the chain it searches — see search tier. Registry searches can take around 90 seconds. Send webhook_url when you want Didit to return immediately and notify your URL once candidates are ready. The search callback is unsigned on purpose, so you do not need to configure a shared secret for this lightweight notification. Use POST /v3/kyb/select/, POST /v3/kyb/shareholders/ or POST /v3/kyb/ubo/ with the returned kyb_response_id to retrieve the profile at the tier you need. Retrieval is billable and saves the result as a Manual Check in the Business Console.

Typical flow

  1. Search by company name, registration number and country, on the tier you intend to buy (basic is the default Lite chain; shareholders and ubo search that tier’s chain).
  2. If search_resolved=false, wait for the optional webhook_url callback instead of polling.
  3. Show the returned candidates to your operator or customer.
  4. Retrieve the matching kyb_response_id at the tier you need (select for Lite, shareholders, or ubo).
  5. Store the returned request_id and use it to retrieve the saved business verification result.

Search callback

When the provider tells Didit the search is resolved, Didit sends one POST to your webhook_url:
Treat the callback as a delivery notification. Use the returned kyb_response_id with POST /v3/kyb/select/, POST /v3/kyb/shareholders/ or POST /v3/kyb/ubo/ to run the billable registry profile retrieval.