> ## 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 연동 가이드: 아키텍처 및 패턴

> Didit의 프로덕션 준비 KYB 연동: 아키텍처, 세션, 호스팅 흐름, webhook, 폴링, 결정. 국가 및 등급별 과금, 건당 $2.00부터.



KYB 연동 프롬프트
        프롬프트를 클립보드에 복사



      
      

\<pre>

\````# Goal — ship a production-ready KYB (business verification) integration

KYB runs through the same `/v3/session/` endpoint as KYC. The session's workflow determines whether it's a KYC or KYB session — pass a KYB workflow id and Didit creates a business session automatically (`session_kind: "business"`).

\## End-to-end flow

\```
You: POST /v3/session/ (KYB workflow_id, vendor_data) → session_id, url, session_token
You: deliver url to the business contact (email / your UI / iframe)
Biz: completes the hosted flow (registry confirm → Key People → documents → AML)
Didit → Webhook: status.updated with session_kind: "business"
You: GET /v3/session/{session_id}/decision/ → full KYB decision
You: branch on decision.status ("Approved" / "Declined" / "In Review" / "Resubmitted")
\```

\## Create a KYB session

\```bash
curl -X POST https://verification.didit.me/v3/session/ \
-H "x-api-key: $DIDIT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"workflow_id": "$KYB_WORKFLOW_ID",
"vendor_data": "biz-acme",
"callback": "https://myapp.com/kyb/return",
"metadata": {"plan": "growth", "country": "GBR"}
}'
\```

Recommended fields:

\- `workflow_id` — references your KYB workflow.
\- `vendor_data` — your business id; binds the session to a [Business entity](/entities/businesses/overview).
\- `callback` — where to redirect the user after completion.
\- `metadata` — JSON attached to the session for your own reporting.

\## Webhook events for KYB

\| Event | Trigger |
\|---|---|
\| `status.updated` (with `session_kind === "business"`) | KYB session status changed. Follow this event for progress. |
\| `data.updated` (with `session_kind === "business"`) | A reviewer edited registry data or Key People in the console, or the registry reported a change (registry monitoring). Not sent for document uploads or Key People submissions. |
\| `business.status.updated` | Linked Business entity status changed |
\| `business.data.updated` | Linked Business entity profile / counters changed |

Subscribe via `POST /v3/webhook/destinations/` with `webhook_version: "v3"`. Verify the `X-Signature-V2` header (HMAC-SHA256 of canonical JSON). De-dupe on `event_id`. Respond within 5 seconds.

\## KYB decision shape (V3 plural arrays)

\```bash
curl https://verification.didit.me/v3/session/$SESSION_ID/decision/ \
-H "x-api-key: $DIDIT_API_KEY"
\```

Key V3 arrays you'll iterate:

\| Array | Holds |
\|---|---|
\| `key_people_checks[]` | UBOs, shareholders, directors, officers — bucketed into `registry` (from the registry lookup) and `submitted` (what the business confirmed). Plus a `ubo_kyc_summary` rollup. |
\| `document_verifications[]` | Each item has `status`, `node_id`, `items[]` (signed `file_url` + OCR extract), `groups`, `required_groups`. |
\| `aml_screenings[]` | Company AML and per-person AML hits. |

The KYB-specific features are `KYB_REGISTRY`, `AML`, `KYB_DOCUMENTS`, `KYB_KEY_PEOPLE`. Statuses are the exact labels `"Not Finished"`, `"Approved"`, `"Declined"`, `"In Review"`, `"Resub Requested"`.

\## Apply-decision logic

\```ts
switch (decision.status) {
case "Approved":   await onboardBusiness(decision); break;
case "Declined":   await logRejection(collectWarnings(decision), decision); break; // warnings[] tags on each feature array
case "In Review":  await markPending(decision); break; // wait for next webhook
case "Resubmitted":await notifyBusiness(decision); break; // business needs to re-upload
case "Awaiting User": await pingChildPersonForKyc(decision); break; // child Key People KYC pending
}
\```

See /business-verification/statuses for the full state machine.

\## Resubmission flow

When a session transitions to `Resubmitted` (or a feature to `Resub Requested`, or a feature is marked for resubmission), re-deliver the same `url` — the hosted flow resumes at the resubmission step. To re-verify a specific Key Person, resubmit that person's child KYC session; the parent `kyb_key_people` re-aggregates automatically.

\## Key People child KYC

If your KYB workflow has KYC required for some roles, each person triggers a child KYC session automatically. While any child is in progress, the parent's `kyb_key_people` status is `Awaiting User`. Configure per-role required/skippable behaviour at *Workflows → [KYB workflow] → Key People*. A child session expires after the session expiration time of the KYC workflow its role is mapped to, not the KYB session's. A party whose session was deleted, or whose link expired before the person started it, is reissued with `POST /v3/session/{session_id}/kyb/parties/{party_uuid}/regenerate/`.

\## Failure modes

\| Scenario | Response |
\|---|---|
\| Invalid `workflow_id` | `400 Bad Request` |
\| Wrong workflow type (KYC instead of KYB) | Session is created but runs KYC steps — verify the workflow's `workflow_type` is `"kyb"` |
\| Duplicate `vendor_data` | A new session is created — that's by design for re-KYB |
\| Company country outside the workflow's allowed countries | The registry check raises the `KYB_COUNTRY_RESTRICTED` warning |
\| Registry provider outage during company search | `502` with `code: "kyb_registry_provider_unavailable"`. Not billed. In Didit's hosted flow, the business is automatically offered manual company entry instead of a retry-only error. |
\| Rate limit | `429` with `Retry-After` header |

\## Sources of truth

\- /sessions-api/create-session — request body schema
\- /business-verification/response-schema — KYB decision payload
\- /business-verification/statuses — feature state machine
\- /business-verification/webhooks — KYB-specific event catalog
\- /entities/businesses/data-model — Business entity schema
\- /integration/integration-prompt — canonical end-to-end prompt````

\</pre>



      
      

붙여넣을 곳

이 가이드는 [빠른 시작](https://docs.didit.me/ko/business-verification/quickstart.md)의 보완 문서입니다. 아키텍처, 연동 시 판단해야 할 모든 사항, 그리고 운영 환경에서 KYB를 안정적으로 운영하기 위한 패턴을 다룹니다.## 아키텍처```mermaid theme={null}
sequenceDiagram
    participant You as Your platform
    participant Didit as Didit API
    participant Biz as Business contact
    participant Webhook as Your webhook endpoint

    You->>Didit: POST /v3/session/ (workflow_id, vendor_data)
    Didit-->>You: session_id, url, token
    You->>Biz: Deliver hosted verification URL (your email/flow)
    Biz->>Didit: Completes KYB hosted flow
    Didit->>Didit: Registry lookup, AML screening, OCR
    Didit->>Webhook: status.updated (session_kind: business)
    You->>Didit: GET /v3/session/{id}/decision/
    Didit-->>You: Full KYB decision payload
    You->>You: Onboard / reject / escalate based on status
```## 인증모든 요청에는 애플리케이션의 API 키를 담은 `x-api-key` 헤더가 필요합니다. 키 교체, 환경 분리, 권한 범위에 대해서는 [API 인증](https://docs.didit.me/ko/getting-started/api-authentication.md)을 참고하세요.## 세션 생성엔드포인트는 `POST /v3/session/` 하나입니다. 세션이 KYC인지 KYB인지는 워크플로의 유형으로 결정되므로, 별도의 "business" 플래그는 필요하지 않습니다.**생성 시 권장 필드:**| 필드 | 용도 |
| - | - |
| `workflow_id` | 필수. KYB 워크플로를 지정합니다. |
| `vendor_data` | 기업을 식별하는 고유 값입니다. 세션을 [기업 엔티티](https://docs.didit.me/ko/entities/businesses/overview.md)에 연결합니다. |
| `callback_url` | 선택 사항. 완료 후 사용자를 리디렉션할 주소입니다. |
| `expected_details` | 선택 사항. `{ company_name, registry_country, registration_number }` 형식입니다. 법인 등기부 검색을 미리 채웁니다. 설립 국가는 미리 선택되고 잠기며(`XX` 형식의 `registry_country`, 또는 주 단위 등기부의 경우 `US-CA`와 같은 `XX-YY` 형식), 회사명과 등록번호 필드가 채워지고, 두 식별자가 모두 있으면 함께 사용해 검색을 자동으로 실행합니다. 이 값은 사전 입력용이며, 불일치해도 경고가 발생하지 않습니다. |
| `metadata` | 선택 사항. 세션에 첨부하는 JSON입니다. |전체 스키마는 [세션 생성](https://docs.didit.me/ko/sessions-api/create-session.md)을 참고하세요.## 호스팅 링크 전달응답의 `url`은 호스팅 인증 링크입니다. 전달 방법은 다음과 같습니다.- 자체 플랫폼에서 이메일로 보냅니다.
- 온보딩 UI에 링크로 삽입합니다.
- 앱 내 웹뷰(iOS / Android / React Native)에서 엽니다.[화이트 라벨](https://docs.didit.me/ko/console/white-label.md)을 통해 호스팅 경험을 **맞춤 설정**할 수 있습니다. 로고, 색상, 도메인, 이메일 템플릿을 변경할 수 있습니다.## 폴링과 webhookWebhook은 권장 방식입니다. 처리가 끝나면 Didit이 구독한 엔드포인트로 완료 이벤트를 POST합니다.폴링은 개발 중이거나 webhook 엔드포인트에 접근할 수 없을 때 사용할 수 있습니다.* 지수 백오프를 적용해 `GET /v3/session/{id}/decision/`을 폴링합니다. 처음에는 10초마다, 최대 60초 간격까지 늘립니다.
* `status`가 `"Approved"`, `"Declined"`, `"In Review"` 중 하나이면 폴링을 중단합니다.> [!WARNING]
>
> 폴링을 높은 빈도로 호출하면 [속도 제한](https://docs.didit.me/ko/integration/rate-limiting.md)에 걸릴 수 있습니다. 운영 환경에서는 항상 webhook을 사용하세요.## Webhook 처리관심 있는 이벤트를 구독하세요. 같은 이벤트가 KYC와 KYB 모두에 사용되며, 기업 세션의 이벤트를 식별하려면 페이로드 안의 `session_kind: "business"`를 확인합니다.- `status.updated`: 세션 상태가 변경되었습니다. KYB 세션을 필터링하려면 `session_kind === "business"`를 조건으로 사용하세요.
- `data.updated`: 검토자가 콘솔에서 등기 데이터나 주요 인물 정보를 수정했거나, 등기부에서 변경을 보고한 경우입니다. 신청자가 문서를 업로드하거나 주요 인물을 제출할 때는 전송되지 않으므로, 그 경우에는 `status.updated`를 따르세요. 같은 `session_kind` 필터를 적용합니다.
- `business.status.updated` / `business.data.updated`: 연결된 [기업 엔티티](https://docs.didit.me/ko/entities/businesses/overview.md)가 변경되었습니다.전체 이벤트 목록은 [KYB webhook](https://docs.didit.me/ko/business-verification/webhooks.md)을 참고하세요. 서명 검증과 재시도 동작은 [webhook 참조](https://docs.didit.me/ko/integration/webhooks.md)에서 확인할 수 있습니다.## 결정 처리```typescript theme={null}
switch (decision.status) {
  case 'Approved':
    await onboardBusiness(decision);
    break;
  case 'Declined':
    // The KYB decision has no single reason code: collectWarnings is your helper
    // that flattens warnings[] from registry_checks, document_verifications,
    // key_people_checks and aml_screenings
    await logRejection(collectWarnings(decision), decision);
    break;
  case 'In Review':
    // Wait for analyst decision — another webhook will fire
    await markPending(decision);
    break;
  case 'Resubmitted':
    // The business was asked to re-upload a document
    await notifyBusiness(decision);
    break;
}
```상태 전이의 전체 흐름은 [KYB 상태](https://docs.didit.me/ko/business-verification/statuses.md)를, 결정의 이유를 설명하는 태그는 [KYB 경고](https://docs.didit.me/ko/business-verification/warnings.md)를 참고하세요.## 재제출 흐름기업 확인(KYB) 세션이 `Resubmitted`로 전환되거나 기능이 재제출 대상으로 표시되면, 기업은 수정되었거나 추가된 데이터를 업로드해야 합니다.다음과 같이 대응할 수 있습니다.- 같은 `url`을 **다시 전달**하세요. 호스팅 플로우는 재제출이 필요한 지점부터 이어서 진행됩니다.
- 사용할 수 없게 된 주요 인물 링크를 **다시 발급**하세요. 하위 KYC 세션이 삭제되었거나 해당 인물이 시작하기 전에 만료된 당사자에게는 [주요 인물 KYC 세션 재생성](https://docs.didit.me/ko/sessions-api/regenerate-kyb-party.md)으로 새 세션을 받을 수 있습니다.
- Business Console에서 [케이스](https://docs.didit.me/ko/transaction-monitoring/cases.md)를 열어 내부적으로 주고받는 과정을 추적하세요.## 자체 프런트엔드에서 단계 실행문서 및 주요 인물 단계는 API 키를 사용해 서버에서 직접 진행할 수도 있습니다. 이 방식을 사용하면 사용자 인터페이스는 직접 관리하고, 인증과 결정은 Didit이 담당합니다.
모든 호출은 KYB 세션에 한정되며, `write:businesses` 권한이 필요합니다(추출된 당사자를 읽을 때는 `read:businesses` 또는 `read:sessions`도 허용됩니다). 호스팅 페이지와 동일한 검사, 결제, 단계 진행을 수행합니다.1) 세션이 KYB 문서 단계에 있는 동안 [법인 문서를 업로드](https://docs.didit.me/ko/sessions-api/kyb-upload-documents.md)하세요.
2) 주주를 포함해 문서에 명시된 [당사자와 소유 비율을 읽고](https://docs.didit.me/ko/sessions-api/kyb-extracted-parties.md), 신청자에게 보여 주세요.
3) [당사자 초안](https://docs.didit.me/ko/sessions-api/kyb-list-party-drafts.md)을 [생성](https://docs.didit.me/ko/sessions-api/kyb-create-party-draft.md), [수정](https://docs.didit.me/ko/sessions-api/kyb-update-party-draft.md), [삭제](https://docs.didit.me/ko/sessions-api/kyb-delete-party-draft.md)할 수 있습니다. 초안은 신고된 상태가 아니며 비용이 발생하지 않습니다.
4) [초안을 제출](https://docs.didit.me/ko/sessions-api/kyb-submit-parties.md)하세요. Didit이 검증해야 할 당사자를 결정하고, 각 당사자에 대해 KYC 세션을 생성한 뒤 `kyc_session_url`을 반환합니다. 이 URL을 전송하거나 삽입하면 됩니다.
5) 호스팅 플로우와 마찬가지로 세션에서 통합 결정을 읽으세요.세션이 다른 단계에 있을 때 호출하면 `409 kyb_step_mismatch`와 함께 현재 단계가 응답으로 반환됩니다. 완료된 세션에 호출하면 `409 kyb_session_not_writable`이 반환됩니다.## 기업 프로필 집계세션 생성 시 `vendor_data`를 전달하면, Didit이 해당 기업의 모든 세션을 하나의 [기업 엔티티](https://docs.didit.me/ko/entities/businesses/overview.md)로 집계합니다. 세션을 일일이 순회하지 않고도 "이 기업이 지금 완전히 인증되었는가?"를 확인하려면 엔티티의 `features` 맵을 사용하세요.이점은 다음과 같습니다.- 주기적인 KYB 재검증이 같은 프로필에 누적됩니다.
- 같은 `vendor_data`로 모니터링되는 거래에는 기업의 위험 맥락이 함께 포함됩니다.
- 사용자 엔티티에 연결된 실소유자와 임원이 엔티티 간 관계를 채웁니다.## 모범 사례| 사례 | 이유 |
| - | - |
| 항상 `vendor_data`를 전달하십시오 | 이 값이 없으면 세션이 고립되어 집계할 수 없습니다. |
| 폴링 대신 webhook을 사용하십시오 | 지연 시간이 짧고 속도 제한 부담이 없습니다. |
| webhook 서명을 검증하십시오 | 위조된 이벤트를 방지합니다. |
| `session_id`를 자체 시스템에 저장하십시오 | 결정 결과를 조회하고 PDF를 생성하는 데 필요합니다. |
| `metadata`로 세션에 태그를 지정하십시오 | 보고와 디버깅이 간편해집니다. |
| 테스트 워크플로를 설정하십시오 | 프로덕션 전에 연동 테스트용 샌드박스 워크플로를 사용하십시오. |## 오류 처리| 상황 | 응답 |
| - | - |
| 잘못된 `workflow_id` | `400 Bad Request` |
| `vendor_data`가 동일한 세션이 중복되는 경우 | 새 세션을 생성합니다. 재인증이 예상되므로 이는 의도된 동작입니다. |
| 회사의 국가가 워크플로에서 허용된 국가에 포함되지 않음 | 법인 등기부 확인에서 `KYB_COUNTRY_RESTRICTED` 경고가 발생합니다. |
| 회사 검색 중 법인 등기부 제공업체 장애 | `POST /v3/kyb/search/`가 `502`를 반환하며 `code: "kyb_registry_provider_unavailable"`을 포함합니다. 과금되지 않습니다. 재시도하거나, `code` 값에 따라 회사 정보를 수동으로 입력하는 옵션을 제공하십시오. Didit 호스팅 흐름에서는 재시도만 요구하는 오류 대신 기업이 자동으로 수동 입력 단계로 안내됩니다. 자세한 내용은 [KYB 등기부 검색](https://docs.didit.me/ko/standalone-apis/kyb-registry-search.md#레지스트리-중단-처리)을 참조하십시오. |
| 속도 제한 | `Retry-After` 헤더와 함께 `429 Too Many Requests`를 반환합니다. |[속도 제한](https://docs.didit.me/ko/integration/rate-limiting.md) 전체 참조 문서를 확인하십시오.## 다음 단계> [card] [webhook](https://docs.didit.me/ko/business-verification/webhooks.md)
>
> 모든 KYB 이벤트와 payload.> [card] [상태](https://docs.didit.me/ko/business-verification/statuses.md)
>
> 상태 머신 참조.> [card] [응답 스키마](https://docs.didit.me/ko/business-verification/response-schema.md)
>
> KYB 결정 결과 해석.


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