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

# KYB 企业登记库搜索 API - 企业查询

> Didit 的 POST /v3/kyb/search/ 用于查找企业候选项。付费企业数据源的成功搜索每次请求收费 $0.50；档案获取另行计费。

请先使用此端点查找匹配的公司登记候选记录。
搜索不会创建已保存的 Manual Check。

使用付费企业数据源的独立搜索成功后，每次请求收费 **\$0.50**，与候选记录数量无关。空结果、失败的搜索以及仅由其他数据源返回的结果均不收费。之后获取企业档案将另行计费。

对于可能使用付费数据源的搜索，Didit 会在联系登记机构之前检查并预留相应的搜索价格。
余额不足时返回 `403`，并带有 `code: "insufficient_credits"`。
合同计费按您约定的搜索费率执行；未配置的合同费率会在搜索前被拒绝。
沙盒中的搜索免费。
每次成功的重复搜索都是一次新的计费请求；回调投递不会再产生一次搜索费用。

如果您发送 `webhook_url`，Didit 可在服务提供商处理搜索期间立即返回，待候选记录就绪后再将其发送到您的回调 URL。该回调按设计未经签名，因此无需为此搜索通知配置 Webhook 密钥。请参阅[搜索回调负载示例](https://docs.didit.me/zh/standalone-apis/kyb-registry.md#搜索回调)。

选定正确的 `kyb_response_id` 后，调用 `POST /v3/kyb/select/`（Lite）、`POST /v3/kyb/shareholders/` 或 `POST /v3/kyb/ubo/`，即可按所需层级获取可计费的登记档案。

> [!NOTE]
>
> 搜索时，每个候选记录的 `fetch_status` 均为 `pending`，并一直保持 `pending`，直到您选定该候选记录为止。搜索仅列出候选记录，选定操作才会获取完整档案。请勿为等待其状态更新而轮询搜索。
>
> `kyb_response_id` 是仅限于单次搜索请求的不透明临时句柄：请原样回传您收到的值，切勿解析其内容或从中推导任何信息；重复相同搜索时会返回新的 ID。搜索后请及时选定候选记录；如需该公司的稳定标识符，请使用 `registration_number`。

## 搜索层级

`tier` 用于选择搜索所运行的登记层级，即该层级对应的服务提供商链：`basic`（默认，即 Lite 链）、`shareholders` 或 `ubo`。候选列表来自该层级的服务提供商链，而该链所用的数据源不一定与 Lite 搜索读取的数据源相同。因此，Lite 搜索结果为空并不能证明登记机构未收录该公司，请在您需要的层级重新搜索。

若该国家/地区不提供您指定的层级，搜索将运行在该国家/地区提供的、不高于该层级的最高层级上。没有任何登记数据的国家/地区不提供登记核验，请改为手动录入企业信息。

请在您打算购买的层级上进行搜索，然后通过提供该层级可计费登记档案的端点获取候选记录：

| 您搜索的 `tier` | 获取候选记录的端点 |
| - | - |
| `basic`（默认） | `POST /v3/kyb/select/`（Lite） |
| `shareholders` | `POST /v3/kyb/shareholders/` |
| `ubo` | `POST /v3/kyb/ubo/` |

## search\_type

`search_type` 仅接受 `contains`，且为默认值。背后的登记数据源按公司名称包含关系进行匹配，因此 `start_with` 和 `fuzzy` 会被拒绝并返回 `400`（`"start_with" is not a valid choice`），而不会被静默视为 `contains`。如需精确匹配公司，请发送 `registration_number`。

## 托管与独立搜索

`POST /v1/kyb/search/` 是托管验证流程运行的搜索：它通过验证会话进行身份验证，使用 API 密钥进行身份验证时返回 `403`，且不接受 `tier`，由工作流的 KYB 登记配置决定使用哪条链。独立 API 使用您的 `x-api-key` 调用 `POST /v2/kyb/search/` 或 `POST /v3/kyb/search/`。`tier` 输入参数以及分层的 select 端点，是独立集成在所需层级上获取相同候选记录的方式。

## 处理登记服务中断

若登记服务提供商暂时不可用，该端点将返回 `502`，并附带稳定的机器可读代码：

```json theme={null}
{
  "detail": "The company registry provider is temporarily unavailable.",
  "code": "kyb_registry_provider_unavailable"
}
```

收到此代码后，可让用户改为手动录入企业信息，或请其稍后重试。请将校验错误与之区分：无效的搜索输入返回 `400`，不会使用此中断代码。

## 处理不支持的国家/地区和搜索限制

另有两个稳定代码，提示您停止重试，改为手动录入企业信息：

| 状态 | `code` | 适用情况 |
| - | - | - |
| `400` | `kyb_registry_country_unsupported` | 该国家/地区在任何层级都没有公司登记数据源。此限制是永久性的，因此重试相同搜索永远不会成功。 |
| `429` | `kyb_registry_search_limit_reached` | 您的应用在付费企业数据源上的搜索额度（每小时 600 次）已用尽，且该国家/地区已无可用的免费数据源。请等待该时间窗口过去，或手动录入企业信息。 |

在托管流程中，每个登记步骤最多允许对付费企业数据源进行 3 次搜索。第三次之后，系统会提示申请人手动录入。

若选定的候选记录是商标注册而非公司，将返回 `400`，并带有 `code: "kyb_registry_entry_not_a_company"`。请改为从搜索结果中选择一家公司。


## OpenAPI

````yaml zh/openapi-25.json POST /v3/kyb/search/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: 身份证件验证 API。使用 x-api-key 请求头进行身份验证。
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/kyb/search/:
    post:
      tags:
        - Standalone APIs
      summary: KYB 公司登记企业搜索（独立项）
      description: >-
        按名称和/或注册号在官方公司登记中搜索候选企业。这是两步登记流程的第 1 步：**搜索**返回轻量级候选企业，随后通过 `POST
        /v3/kyb/select/` 获取某一候选企业的完整档案。


        **搜索计费。**使用付费企业数据源的成功搜索每次请求费用为 USD
        0.50，无论候选企业数量多少。空结果、失败以及仅由其他数据源提供的结果不收费。适用价格会在搜索前预扣；余额不足将返回 403 及代码
        `insufficient_credits`。若有约定则适用合同费率，未配置的合同搜索费率将返回
        403。沙盒搜索免费。重复成功的搜索可能会产生另一笔费用；回调投递不收取额外费用。档案获取单独计费。该搜索费用同样适用于
        v2。返回的候选企业状态始终为 `fetch_status: "pending"`：完整的企业数据仅在调用 select 时获取（并计费）。


        **`kyb_response_id` 为临时句柄。**它是单次搜索的句柄，并非稳定的企业
        ID。请在搜索后尽快选择，若需更新请重新搜索获取新句柄，切勿长期存储。


        **`tier` 选择提供商链。**`tier` 指定搜索运行的公司登记等级：`basic`（默认值，即 Lite
        链）、`shareholders` 或 `ubo`。搜索将使用为该等级提供服务的提供商链，且该链并不总是与 Lite 搜索读取的链相同，因此
        Lite
        搜索结果为空并不代表公司登记中没有该企业，请在您所需的等级下重新搜索。如果某个国家/地区不提供您指定的等级，则会在其所提供的不高于该等级的最高等级上进行搜索。请从销售该等级的
        endpoint 获取候选企业：`POST /v3/kyb/select/`（Lite）、`POST
        /v3/kyb/shareholders/` 或 `POST /v3/kyb/ubo/`。


        **身份验证。**`POST /v3/kyb/search/`（以及 `/v2/`）在 `x-api-key` 请求头中接收您应用的 API
        密钥。托管的 `POST /v1/kyb/search/` 是托管验证流程调用的基于会话认证的路由：对 API 密钥会返回 `403`，且不接收
        `tier`，由工作流的 KYB 公司登记配置来选择提供商链。


        **两种模式。**

        - *同步（默认）：*API 会持续轮询公司登记，直到搜索完成并返回最终候选企业列表（`search_resolved: true`）。

        - *异步：*传入 `webhook_url`，API 将立即返回响应（通常带有 `search_status: "pending"`
        和空的候选企业列表），随后在公司登记处理完成时向您的 URL 发送 `kyb.registry_search.resolved` 的 POST
        回调。回调正文为 `{"event_id", "event_type": "kyb.registry_search.resolved",
        "request_id", "vendor_data", "metadata", "search_status",
        "search_resolved", "kyb_registry", "timestamp", "created_at"}`（请注意，与该
        endpoint 的 ISO 格式 `created_at` 不同，回调中的 `timestamp` 和 `created_at` 为
        epoch 时间戳整数），并且是以**未签名**形式发送（请求头为 `X-Didit-Unsigned-Callback: true`，无
        `X-Signature`）。


        **国家/地区代码。**ISO 3166-1 alpha-2（`GB`、`DE`），若公司登记为地区性质，则加上 `XX-YY`
        行政区划代码，例如加利福尼亚州的 `US-CA`。


        **沙盒。**来自沙盒应用的密钥将返回一个静态候选企业，不会与任何公司登记通信。
      operationId: post_v3_kyb_search
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - country_code
              properties:
                country_code:
                  type: string
                  maxLength: 10
                  description: >-
                    要搜索其公司登记所在国家/地区的 ISO 3166-1 alpha-2 代码。例如
                    `GB`。若公司登记在州或省级别运作，请以 `XX-YY` 格式附加 ISO 3166-2 行政区划代码：`US-CA`
                    搜索加利福尼亚州登记。美国搜索始终需要行政区划，仅传 `US` 将被拒绝。不区分大小写；规范化为大写。
                  example: GB
                name:
                  type: string
                  maxLength: 255
                  description: 要搜索的企业名称。`name` 或 `registration_number` 必填其一。
                  example: Tesco
                registration_number:
                  type: string
                  maxLength: 100
                  description: 要搜索的公司登记注册号。`name` 或 `registration_number` 必须提供其一。
                tier:
                  type: string
                  enum:
                    - basic
                    - shareholders
                    - ubo
                  default: basic
                  description: >-
                    本次搜索运行所依托的服务商链对应的公司登记等级。`basic`（默认）搜索该国家/地区的 Lite
                    链；`shareholders` 和 `ubo` 搜索该等级的股权结构链，两者可能来自不同数据源，因此 Lite
                    搜索结果为空并不代表公司登记中没有该企业。对于不提供指定等级的国家/地区，将使用其支持的最高等级（不超过该等级）进行搜索。从售卖所搜索等级的
                    endpoint 获取候选对象：`POST /v3/kyb/select/`（Lite）、`POST
                    /v3/kyb/shareholders/` 或 `POST /v3/kyb/ubo/`。
                  example: basic
                search_type:
                  type: string
                  enum:
                    - contains
                  default: contains
                  description: >-
                    登记处搜索所应用的名称匹配策略。`contains` 是唯一接受的值：搜索背后的登记处数据源均不提供前缀或模糊模式，因此
                    `start_with` 和 `fuzzy` 会被拒绝并返回 `400`（`not a valid choice`）。
                vendor_data:
                  type: string
                  description: 您为此查询指定的标识符；将原样返回并包含在 Webhook 回调中。
                metadata:
                  type: object
                  nullable: true
                  description: 自由格式 JSON；回显并包含在 Webhook 回调中。
                webhook_url:
                  type: string
                  format: uri
                  maxLength: 500
                  description: >-
                    将搜索切换为异步模式：API 会立即返回，并在候选列表准备就绪时向此 URL 发送未签名的
                    `kyb.registry_search.resolved` 回调 POST 请求。
            example:
              country_code: GB
              name: Tesco
              search_type: contains
              vendor_data: company-1234
      responses:
        '200':
          description: >-
            搜索已受理。同步模式返回已确定的候选名单；Webhook 模式立即返回（通常为 `search_status:
            "pending"`）并通过 `kyb.registry_search.resolved` 回调投递最终名单。
          content:
            application/json:
              schema:
                type: object
                properties:
                  request_id:
                    type: string
                    format: uuid
                    description: >-
                      包含 `webhook_url` 时：持久化的搜索请求 ID，在
                      `kyb.registry_search.resolved` 回调中作为 `request_id` 返回。不包含
                      `webhook_url` 时：临时关联 UUID（搜索不会被存储）。
                  kyb_registry:
                    $ref: '#/components/schemas/KYBRegistrySearchResults'
                  vendor_data:
                    type: string
                    nullable: true
                    description: 回显您发送的 `vendor_data`。
                  metadata:
                    type: object
                    nullable: true
                    description: 您发送的 `metadata` 回显。
                  created_at:
                    type: string
                    format: date-time
              examples:
                Resolved search:
                  summary: 同步模式 — 最终候选列表
                  value:
                    request_id: 0c7e9a40-3a13-4f7e-8a44-9d2e2f1c5b6a
                    kyb_registry:
                      companies:
                        - kyb_response_id: 69aeeb95febb0f1704042259
                          name: Tesco PLC
                          registration_number: '00445790'
                          status: active
                          type: Public Limited Company
                          risk_level: null
                          fetch_status: pending
                        - kyb_response_id: 69aeeb95febb0f170404225a
                          name: E-TESCO LTD
                          registration_number: '15168476'
                          status: active
                          type: Private Limited Company
                          risk_level: null
                          fetch_status: pending
                      pagination:
                        total: 2
                        page: 1
                        per_page: 25
                      search_status: resolved
                      search_resolved: true
                    vendor_data: company-1234
                    metadata: null
                    created_at: '2026-06-11T10:40:00.000000+00:00'
                Pending search (webhook mode):
                  summary: 已提供 `webhook_url`：候选对象通过 kyb.registry_search.resolved 回调送达
                  value:
                    request_id: 5f2d8c1b-7e4a-4b9c-9f0d-3a6e8c2b1d4f
                    kyb_registry:
                      companies: []
                      pagination:
                        total: 0
                        page: 1
                        per_page: 25
                      search_status: pending
                      search_resolved: false
                    vendor_data: company-1234
                    metadata:
                      source: onboarding
                    created_at: '2026-06-11T10:41:00.000000+00:00'
        '400':
          description: >-
            验证错误。字段级问题使用 DRF 的标准外层结构；名称/注册号规则在 `non_field_errors`
            下报告。登记处未覆盖的国家/地区返回 `400` 并附带 `code:
            kyb_registry_country_unsupported`。
          content:
            application/json:
              examples:
                Missing search criteria:
                  summary: 既未提供 `name` 也未提供 `registration_number`
                  value:
                    non_field_errors:
                      - Either 'name' or 'registration_number' is required.
                Invalid country_code:
                  summary: 必须为 `XX`（alpha-2 代码）或 `XX-YY` 行政区划代码
                  value:
                    country_code:
                      - country_code must be a 2-letter ISO code.
                Invalid search_type:
                  summary: 仅接受 `contains`
                  value:
                    search_type:
                      - '"start_with" is not a valid choice.'
                Invalid webhook_url:
                  summary: '`webhook_url` 必须是有效的 URL'
                  value:
                    webhook_url:
                      - Enter a valid URL.
                Country not covered:
                  summary: 没有覆盖该国家/地区的公司登记
                  value:
                    detail: >-
                      Company registry search is not available for this country.
                      Enter the company details manually to continue.
                    code: kyb_registry_country_unsupported
        '403':
          description: >-
            权限被拒绝。当缺少 `x-api-key` 请求头时返回；错误、已撤销或已过期的密钥返回 `401`。缺少密钥时返回 `403` 及
            `{"detail": ...}`；错误、已撤销或已过期的密钥返回
            `401`。此外，在搜索之前，如果无法覆盖适用的搜索费用（`code:
            "insufficient_credits"`），或缺少合同搜索费率，也会返回此错误。
          content:
            application/json:
              examples:
                Missing or invalid API key:
                  summary: 缺少 `x-api-key` 请求头，或者密钥无效/已被吊销
                  value:
                    detail: You do not have permission to perform this action.
        '429':
          description: >-
            超出速率限制，或搜索配额已耗尽。POST/PATCH/DELETE endpoint 每个 API 密钥每分钟共享 300
            次写入请求的额度（交易创建和事件摄入具有单独的 600 次额度），并带有 `X-RateLimit-*` 和 `Retry-After`
            请求头。此外，每个应用每小时的付费公司登记搜索限制为 600 次：超过此限制后响应为 `429`，附带 `code:
            kyb_registry_search_limit_reached`，仅由免费数据源提供服务的搜索仍可正常工作。请等待并稍后重新搜索。
          content:
            application/json:
              examples:
                Write rate limit exceeded:
                  summary: 当前分钟内的写入请求超过 300 次
                  value:
                    detail: >-
                      Write request rate limit exceeded. You can make up to 300
                      requests per minute.
                Search allowance spent:
                  summary: 过去一小时内付费搜索超过 600 次
                  value:
                    detail: >-
                      The maximum number of company registry searches for this
                      session has been reached. Enter the company details
                      manually to continue.
                    code: kyb_registry_search_limit_reached
              schema:
                type: object
                properties:
                  detail:
                    type: string
                  code:
                    type: string
        '502':
          description: >-
            KYB 登记提供商暂时不可用：上游公司登记返回 5xx 响应、超时或连接失败。搜索不计费。请稍后重试，或者在 Didit
            托管验证流程中，系统会自动为用户提供手动输入企业信息的选项，而不是仅提示重试错误。
          content:
            application/json:
              examples:
                Registry provider outage:
                  summary: 登记处提供商未响应搜索
                  value:
                    detail: >-
                      The KYB registry provider is temporarily unavailable.
                      Please try again shortly.
                    code: kyb_registry_provider_unavailable
              schema:
                type: object
                properties:
                  detail:
                    type: string
                  code:
                    type: string
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: |-
            curl -X POST https://verification.didit.me/v3/kyb/search/ \
              -H 'x-api-key: YOUR_API_KEY' \
              -H 'Content-Type: application/json' \
              -d '{
                "country_code": "GB",
                "name": "Tesco",
                "search_type": "contains",
                "vendor_data": "company-1234"
              }'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.kyb.search(
                country_code="GB",
                name="Tesco",
                search_type="contains",
                vendor_data="company-1234",
            )
            print(result)
        - lang: javascript
          label: Node.js
          source: |-
            import Didit from "@didit-protocol/sdk-node";

            // Reads DIDIT_API_KEY.
            const didit = new Didit();

            const result = await didit.kyb.search({
              country_code: "GB",
              name: "Tesco",
              search_type: "contains",
              vendor_data: "company-1234",
            });
            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.KYB.Search(ctx, didit.KYBSearchParams{\n\tCountryCode: \"GB\",\n\tName:        didit.String(\"Tesco\"),\n\tSearchType:  didit.Some(didit.KYBSearchParamsSearchType(\"contains\")),\n\tVendorData:  didit.String(\"company-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
        - lang: java
          label: Java
          source: |-
            import me.didit.Didit;
            import me.didit.types.KybSearchParams;

            // Reads DIDIT_API_KEY.
            Didit client = new Didit();

            var result = client.kyb().search(KybSearchParams.builder()
                    .countryCode("GB")
                    .name("Tesco")
                    .searchType(KybSearchParams.SearchType.of("contains"))
                    .vendorData("company-1234")
                    .build());
            System.out.println(result);
        - lang: php
          label: PHP
          source: |-
            <?php

            require 'vendor/autoload.php';

            use Didit\DiditClient;

            // Reads DIDIT_API_KEY.
            $didit = new DiditClient();

            $result = $didit->kyb->search([
                'country_code' => 'GB',
                'name' => 'Tesco',
                'search_type' => 'contains',
                'vendor_data' => 'company-1234',
            ]);
            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

            # Reads DIDIT_API_KEY.
            didit = Didit::Client.new

            result = didit.kyb.search(
              country_code: "GB",
              name: "Tesco",
              search_type: "contains",
              vendor_data: "company-1234"
            )
            puts result.to_h
        - lang: csharp
          label: .NET
          source: |-
            using System;
            using System.Text.Json;
            using Didit;

            // Reads DIDIT_API_KEY.
            using var client = new DiditClient();

            var result = await client.Kyb.SearchAsync(new KybSearchParams
            {
                CountryCode = "GB",
                Name = "Tesco",
                SearchType = new KybSearchParamsSearchType("contains"),
                VendorData = "company-1234",
            });
            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  schemas:
    KYBRegistrySearchResults:
      type: object
      properties:
        companies:
          type: array
          items:
            type: object
            properties:
              kyb_response_id:
                type: string
                nullable: true
                description: >-
                  该候选对象的句柄。将其传递给 `POST /v3/kyb/select/`
                  以检索完整档案。该句柄为临时性质且仅对本次搜索有效：请勿长期存储；重新搜索可获取新句柄。
                example: 69aeeb95febb0f1704042259
              name:
                type: string
                nullable: true
                description: 注册公司名称。
                example: Tesco PLC
              registration_number:
                type: string
                nullable: true
                description: 公司登记注册号。
                example: '00445790'
              status:
                type: string
                nullable: true
                description: 归一化的企业登记状态（例如 `active`、`dissolved`、`inactive`、`struck off`）。
                example: active
              type:
                type: string
                nullable: true
                description: 公司登记机构报告的法律形式。
                example: Public Limited Company
              registered_address:
                type: string
                nullable: true
                description: >-
                  候选公司的注册地址（当登记机构返回该地址时）。可结合注册号使用该地址来区分同名公司：在美国，候选公司可能列在其实际运营所在的州，而非您搜索的州。
                example: >-
                  Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, AL7
                  1GA
              risk_level:
                type: string
                nullable: true
                description: 公司登记所报告的风险等级（如可用）。搜索时通常为 `null`。
              fetch_status:
                type: string
                nullable: true
                description: 对于搜索候选对象始终为 `pending` — 仅当您选择该候选对象时，才会获取完整的公司资料（并进行计费）。
                example: pending
          description: 去重后的候选人列表。当 `search_resolved=false`（Webhook 模式）或未匹配到任何内容时为空。
        pagination:
          type: object
          properties:
            total:
              type: integer
              description: 返回的候选人数量。
            page:
              type: integer
            per_page:
              type: integer
              example: 25
        search_status:
          type: string
          nullable: true
          enum:
            - pending
            - resolved
          description: 公司登记搜索生命周期状态。
        search_resolved:
          type: boolean
          description: 候选名单最终确定后为 `true`。
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        您的应用 API 密钥，可在 Business Console 的“开发者 -> API
        密钥”中获取。主密钥拥有完整访问权限。指定名称的密钥可设置作用域：针对每个资源设为无权限、只读或读写，限定于特定工作流或已通过的会话、限定于
        IP 地址列表，以及设置到期日期。401 表示密钥错误、已撤销或已过期；403 表示未发送密钥、密钥无权访问该资源或操作，或请求来自其 IP
        列表之外的地址；在会话路由上返回 404 表示该会话不在该密钥允许的工作流或状态范围内。没有媒体访问权限的密钥获取到的图片、视频和 PDF
        URL 将为 null；没有会话写入权限的密钥获取到的会话链接和 token 将为 null。请参阅
        https://docs.didit.me/console/api-keys。

````

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