> ## 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-Integration: Architektur, Muster und Leitfaden

> KYB-Integration mit Didit: Architektur, Sitzungen, Webhooks und Entscheidungen. Ab $2.00 pro Verifizierung, nach Land und Stufe.



KYB-Integrationsprompt
        Prompt in die Zwischenablage kopieren



      
      

\<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>



      
      

Einfügen in

Dieser Leitfaden ergänzt die [Schnellstartanleitung](https://docs.didit.me/de/business-verification/quickstart.md). Er beschreibt die Architektur, alle Integrationsentscheidungen und die betrieblichen Muster, mit denen KYB in der Produktion zuverlässig läuft.## Architektur```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
```## AuthentifizierungAlle Anfragen benötigen den Header `x-api-key` mit dem API-Schlüssel Ihrer Anwendung. Informationen zur Schlüsselrotation, zur Trennung der Umgebungen und zu Scopes finden Sie unter [API-Authentifizierung](https://docs.didit.me/de/getting-started/api-authentication.md).## Sitzung erstellenEs gibt einen einzigen Endpoint: `POST /v3/session/`. Der Typ des Workflows bestimmt, ob es sich um eine KYC- oder eine KYB-Sitzung handelt. Ein eigenes Flag „business“ ist nicht erforderlich.**Empfohlene Felder beim Erstellen:**| Feld | Zweck |
| - | - |
| `workflow_id` | Erforderlich. Verweist auf Ihren KYB-Workflow. |
| `vendor_data` | Ihre Kennung für das Unternehmen. Verknüpft die Sitzung mit einer [Unternehmens-Entität](https://docs.didit.me/de/entities/businesses/overview.md). |
| `callback_url` | Optional. Ziel, an das der Benutzer nach Abschluss weitergeleitet wird. |
| `expected_details` | Optional. `{ company_name, registry_country, registration_number }`. Befüllt die Suche im Unternehmensregister vor: Das Gründungsland wird vorausgewählt und gesperrt (`registry_country` als `XX` oder `XX-YY` für Register auf Bundesstaatsebene, z. B. `US-CA`), die Felder für Firmenname und Registernummer werden vorausgefüllt, und die vorgegebene Suche läuft automatisch. Sind beide Kennungen vorhanden, werden sie kombiniert. Es handelt sich nur um eine Vorausfüllung. Abweichungen erzeugen keine Warnungen. |
| `metadata` | Optional. JSON-Daten, die der Sitzung angehängt werden. |Vollständiges Schema: [Sitzung erstellen](https://docs.didit.me/de/sessions-api/create-session.md).## Gehosteten Link bereitstellenDie Antwort `url` ist ein gehosteter Verifizierungslink. Für die Zustellung stehen folgende Möglichkeiten zur Verfügung:- Senden Sie ihn von Ihrer eigenen Plattform per E-Mail.
- Betten Sie ihn als Link in Ihre Onboarding-Oberfläche ein.
- Öffnen Sie ihn in einer In-App-WebView (iOS, Android oder React Native).Sie können die gehostete Erfahrung **anpassen**, also Logo, Farbe, Domain und E-Mail-Vorlagen, über [White-Label](https://docs.didit.me/de/console/white-label.md).## Polling oder WebhooksWebhooks sind das empfohlene Muster. Didit sendet Abschlussereignisse per POST an Ihren abonnierten Endpoint, sobald die Verarbeitung abgeschlossen ist.Polling wird während der Entwicklung oder dann unterstützt, wenn Ihr Webhook-Endpoint nicht erreichbar ist:* Fragen Sie `GET /v3/session/{id}/decision/` mit exponentiellem Backoff ab (zunächst alle 10 Sekunden, maximal alle 60 Sekunden).
* Beenden Sie das Polling, sobald `status` einen der Werte `"Approved"`, `"Declined"` oder `"In Review"` hat.> [!WARNING]
>
> Polling mit hoher Frequenz kann die [Rate-Limits](https://docs.didit.me/de/integration/rate-limiting.md) auslösen. Verwenden Sie in der Produktion immer Webhooks.## Webhook-VerarbeitungAbonnieren Sie die Ereignisse, die für Sie relevant sind. Dieselben Ereignisse gelten für KYC und KYB. Im Payload kennzeichnet `session_kind: "business"` die Ereignisse von Unternehmenssitzungen:- `status.updated`: Der Status der Sitzung hat sich geändert. Filtern Sie nach `session_kind === "business"` für KYB-Sitzungen.
- `data.updated`: Ein Prüfer hat Registerdaten oder Schlüsselpersonen in der Business Console bearbeitet, oder das Register hat eine Änderung gemeldet. Dieses Ereignis wird nicht gesendet, wenn der Antragsteller ein Dokument hochlädt oder Schlüsselpersonen einreicht. Verwenden Sie dafür `status.updated`. Derselbe Filter für `session_kind` gilt.
- `business.status.updated` und `business.data.updated`: Die verknüpfte [Unternehmens-Entität](https://docs.didit.me/de/entities/businesses/overview.md) hat sich geändert.Vollständiger Ereigniskatalog: [KYB-Webhooks](https://docs.didit.me/de/business-verification/webhooks.md). Signaturprüfung und Wiederholungslogik: [Webhook-Referenz](https://docs.didit.me/de/integration/webhooks.md).## Entscheidungen verarbeiten```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;
}
```Das vollständige Zustandsmodell finden Sie unter [KYB-Status](https://docs.didit.me/de/business-verification/statuses.md). Die Tags, die eine Entscheidung erklären, sind unter [KYB-Warnungen](https://docs.didit.me/de/business-verification/warnings.md) beschrieben.## Ablauf bei erneuter EinreichungWenn eine Sitzung zur Unternehmensverifizierung (KYB) in den Status `Resubmitted` übergeht oder eine Funktion zur erneuten Einreichung markiert wird, muss das Unternehmen korrigierte oder zusätzliche Daten hochladen.Sie haben folgende Möglichkeiten:- **Erneut übermitteln**: Senden Sie dieselbe `url` noch einmal. Der gehostete Ablauf setzt dort an, wo eine erneute Einreichung nötig ist.
- **Ungültigen Link für eine Schlüsselperson neu ausstellen**: Eine Person, deren untergeordnete KYC-Sitzung gelöscht wurde oder abgelaufen ist, bevor die Person sie begonnen hatte, erhält mit [Schlüsselpersonen-KYC-Sitzung neu erzeugen](https://docs.didit.me/de/sessions-api/regenerate-kyb-party.md) eine neue Sitzung.
- **Einen [Fall](https://docs.didit.me/de/transaction-monitoring/cases.md) in der Business Console öffnen**, um die Abstimmung intern nachzuverfolgen.## Schritte über Ihr eigenes Frontend ausführenDie Schritte für Dokumente und Schlüsselpersonen lassen sich auch serverseitig mit Ihrem API-Schlüssel steuern. So behalten Sie die Benutzeroberfläche, und Didit übernimmt die Verifizierung und die Entscheidung.
Jeder Aufruf bezieht sich auf die KYB-Sitzung und benötigt die Berechtigung `write:businesses`. Beim Lesen der ermittelten Beteiligten sind auch `read:businesses` oder `read:sessions` zulässig. Die Aufrufe führen dieselben Prüfungen und Abrechnungen durch und rücken den Workflow wie die gehostete Seite um denselben Schritt weiter.1) [Laden Sie die Unternehmensdokumente hoch](https://docs.didit.me/de/sessions-api/kyb-upload-documents.md), während sich die Sitzung im Schritt „KYB-Dokumente“ befindet.
2) [Lesen Sie die Beteiligten aus den Dokumenten](https://docs.didit.me/de/sessions-api/kyb-extracted-parties.md) inklusive Gesellschafter und Eigentumsanteilen aus, und zeigen Sie sie Ihrem Antragsteller an.
3) [Erstellen](https://docs.didit.me/de/sessions-api/kyb-create-party-draft.md), [bearbeiten](https://docs.didit.me/de/sessions-api/kyb-update-party-draft.md) und [löschen](https://docs.didit.me/de/sessions-api/kyb-delete-party-draft.md) Sie [Entwürfe für Beteiligte](https://docs.didit.me/de/sessions-api/kyb-list-party-drafts.md). Ein Entwurf gilt nicht als gemeldet und verursacht keine Kosten.
4) [Reichen Sie die Entwürfe ein](https://docs.didit.me/de/sessions-api/kyb-submit-parties.md). Didit entscheidet, welche Beteiligten verifiziert werden müssen, erstellt für jeden eine KYC-Sitzung und gibt deren `kyc_session_url` zurück, damit Sie sie senden oder einbetten können.
5) Lesen Sie die zusammengefasste Entscheidung aus der Sitzung aus, wie beim gehosteten Ablauf.Ein Aufruf, während die Sitzung sich in einem anderen Schritt befindet, antwortet mit `409 kyb_step_mismatch` und dem aktuellen Schritt. Eine abgeschlossene Sitzung liefert `409 kyb_session_not_writable` zurück.## Aggregation des UnternehmensprofilsWenn Sie beim Erstellen der Sitzung `vendor_data` übergeben, fasst Didit alle Sitzungen dieses Unternehmens in einer einzigen [Unternehmens-Entität](https://docs.didit.me/de/entities/businesses/overview.md) zusammen. Mit der Map `features` der Entität beantworten Sie die Frage „Ist dieses Unternehmen jetzt vollständig verifiziert?“, ohne Sitzungen durchlaufen zu müssen.Vorteile:- Periodische erneute KYB-Prüfungen werden demselben Profil hinzugefügt.
- Transaktionen, die mit demselben `vendor_data` überwacht werden, enthalten den Risikokontext des Unternehmens.
- UBOs und Organmitglieder, die mit Benutzer-Entitäten verknüpft sind, bilden Beziehungen über Entitäten hinweg ab.## Bewährte Vorgehensweisen| Praxis | Warum |
| - | - |
| Übergeben Sie immer `vendor_data` | Ohne dieses Feld ist die Sitzung verwaist und kann nicht aggregiert werden. |
| Verwenden Sie Webhooks statt Polling | Geringere Latenz, keine Belastung des Rate-Limits. |
| Prüfen Sie Webhook-Signaturen | Verhindert gefälschte Webhook-Ereignisse. |
| Speichern Sie die `session_id` auf Ihrer Seite | Sie wird benötigt, um die Entscheidung abzurufen und PDFs zu erzeugen. |
| Versehen Sie Sitzungen mit `metadata` | Vereinfacht Reporting und Fehlersuche. |
| Richten Sie einen Test-Workflow ein | Verwenden Sie vor dem Produktivbetrieb einen Sandbox-Workflow für Integrationstests. |## Fehlerbehandlung| Szenario | Antwort |
| - | - |
| Ungültige `workflow_id` | `400 Bad Request` |
| Doppelte Sitzung mit demselben `vendor_data` | Erstellt eine neue Sitzung. Das ist so vorgesehen, da eine erneute Verifizierung erwartet wird. |
| Land des Unternehmens liegt außerhalb der im Workflow zulässigen Länder | Die Unternehmensregisterprüfung löst die Warnung `KYB_COUNTRY_RESTRICTED` aus. |
| Ausfall des Unternehmensregisteranbieters während der Unternehmenssuche | `POST /v3/kyb/search/` gibt `502` mit `code: "kyb_registry_provider_unavailable"` zurück. Nicht abgerechnet. Wiederholen Sie den Versuch oder verzweigen Sie anhand von `code`, um die manuelle Eingabe des Unternehmens anzubieten. Im gehosteten Ablauf von Didit wird das Unternehmen automatisch zur manuellen Eingabe weitergeleitet, anstatt eines Fehlers, der ausschließlich einen Wiederholungsversuch zulässt. Siehe [KYB-Registersuche](https://docs.didit.me/de/standalone-apis/kyb-registry-search.md#ausfälle-des-registers-behandeln). |
| Rate-Limit | `429 Too Many Requests` mit `Retry-After`-Header. |Vollständige Referenz zu [Rate-Limits](https://docs.didit.me/de/integration/rate-limiting.md).## Nächste Schritte> [card] [Webhooks](https://docs.didit.me/de/business-verification/webhooks.md)
>
> Alle KYB-Ereignisse und Payloads.> [card] [Status](https://docs.didit.me/de/business-verification/statuses.md)
>
> Referenz zum Zustandsautomaten.> [card] [Antwortschema](https://docs.didit.me/de/business-verification/response-schema.md)
>
> Dekodierung der KYB-Entscheidung.


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