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

# Guide d'intégration KYB : architecture et modèles

> Intégrez la vérification KYB avec Didit : architecture, sessions, webhooks, décisions. À partir de $2.00 par contrôle, selon pays et niveau.



Prompt d'intégration KYB
        Copier le prompt dans le presse-papiers



      
      

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



      
      

Coller dans

Ce guide complète le [démarrage rapide](https://docs.didit.me/fr/business-verification/quickstart.md). Il couvre l'architecture, chaque décision d'intégration et les modèles opérationnels qui rendent la KYB fiable en production.## Architecture```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
```## AuthentificationToutes les requêtes exigent l'en-tête `x-api-key` avec la clé API de votre application. Consultez [authentification API](https://docs.didit.me/fr/getting-started/api-authentication.md) pour la rotation des clés, la séparation des environnements et les scopes.## Création de sessionUn seul endpoint : `POST /v3/session/`. Le type du workflow détermine si la session est KYC ou KYB, sans qu'un indicateur « entreprise » explicite soit nécessaire.**Champs recommandés à la création :**| Champ | Rôle |
| - | - |
| `workflow_id` | Obligatoire : référence votre workflow KYB. |
| `vendor_data` | Votre identifiant de l'entreprise. Lie la session à une [entité Business](https://docs.didit.me/fr/entities/businesses/overview.md). |
| `callback_url` | Facultatif : URL vers laquelle rediriger l'utilisateur une fois le parcours terminé. |
| `expected_details` | Facultatif : `{ company_name, registry_country, registration_number }`. Pré-remplit la recherche dans le registre des sociétés : le pays de constitution est présélectionné et verrouillé (`registry_country` au format `XX`, ou `XX-YY` pour les registres à l'échelle des États, par exemple `US-CA`), les champs du nom de l'entreprise et du numéro d'immatriculation sont pré-remplis, et la recherche déclarée s'exécute automatiquement, en combinant les deux identifiants lorsque les deux sont présents. Pré-remplissage uniquement : les écarts ne génèrent pas d'avertissements. |
| `metadata` | Facultatif : JSON attaché à la session. |Schéma complet : [créer une session](https://docs.didit.me/fr/sessions-api/create-session.md).## Transmission du lien hébergéLa réponse `url` est un lien de vérification hébergé. Options de transmission :- Envoyez-le par e-mail depuis votre propre plateforme.
- Intégrez-le à votre interface d'onboarding sous forme de lien.
- Ouvrez-le dans une webview intégrée à l'application (iOS / Android / React Native).Vous pouvez **personnaliser** l'expérience hébergée (logo, couleur, domaine, modèles d'e-mails) via [Marque blanche](https://docs.didit.me/fr/console/white-label.md).## Interrogation ou webhooksLes webhooks constituent le modèle recommandé. Didit envoie les événements de fin de traitement, par requête POST, à l'endpoint auquel vous êtes abonné dès que le traitement se termine.L'interrogation (polling) est prise en charge pour le développement, ou lorsque votre endpoint de webhook est injoignable :* Interrogez `GET /v3/session/{id}/decision/` avec un backoff exponentiel (toutes les 10 s au départ, jusqu'à 60 s).
* Arrêtez l'interrogation lorsque `status` prend l'une des valeurs suivantes : `"Approved"`, `"Declined"`, `"In Review"`.> [!WARNING]
>
> L'interrogation à haute fréquence peut atteindre les [limites de débit](https://docs.didit.me/fr/integration/rate-limiting.md). Privilégiez toujours les webhooks en production.## Traitement des webhooksAbonnez-vous aux événements qui vous intéressent : les mêmes événements couvrent les KYC et les KYB, avec `session_kind: "business"` dans le payload pour identifier les événements des sessions d'entreprise :- `status.updated` : le statut de la session a changé. Filtrez sur `session_kind === "business"` pour les sessions KYB.
- `data.updated` : un relecteur a modifié les données du registre ou les personnes clés dans la console, ou le registre a signalé un changement. Cet événement n'est pas envoyé lorsque le candidat téléverse un document ou soumet les personnes clés : suivez `status.updated` dans ce cas. Le même filtre `session_kind` s'applique.
- `business.status.updated` / `business.data.updated` : l'[entité Business](https://docs.didit.me/fr/entities/businesses/overview.md) liée a changé.Catalogue complet des événements : [webhooks KYB](https://docs.didit.me/fr/business-verification/webhooks.md). Vérification des signatures et comportement des nouvelles tentatives : [référence des webhooks](https://docs.didit.me/fr/integration/webhooks.md).## Gestion des décisions```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;
}
```Consultez les [statuts KYB](https://docs.didit.me/fr/business-verification/statuses.md) pour la machine à états complète, et les [avertissements KYB](https://docs.didit.me/fr/business-verification/warnings.md) pour les tags qui expliquent une décision.## Flux de nouvelle soumissionLorsqu'une session de Vérification d'entreprise (KYB) passe à `Resubmitted` (ou qu'une fonctionnalité est marquée pour nouvelle soumission), l'entreprise doit téléverser des données corrigées ou complémentaires.Vous pouvez :- **Renvoyer** la même `url` : le parcours hébergé reprend là où la nouvelle soumission est nécessaire.
- **Réémettre un lien de personne clé devenu invalide** : une partie dont la session KYC enfant a été supprimée, ou a expiré avant que la personne ne la démarre, reçoit une nouvelle session via [Régénérer la session KYC des personnes clés](https://docs.didit.me/fr/sessions-api/regenerate-kyb-party.md).
- **Ouvrir un [dossier](https://docs.didit.me/fr/transaction-monitoring/cases.md)** dans la Business Console pour suivre les allers-retours en interne.## Exécuter les étapes depuis votre propre interfaceLes étapes des documents et des personnes clés peuvent aussi être pilotées depuis votre serveur, avec votre clé API : vous conservez l'interface utilisateur, et Didit conserve la vérification et la décision.
Chaque appel est limité à la session KYB, nécessite la permission `write:businesses` (la lecture des parties extraites accepte aussi `read:businesses` ou `read:sessions`), et exécute les mêmes contrôles, la même facturation et la même progression d'étape que la page hébergée.1) [Téléversez les documents de la société](https://docs.didit.me/fr/sessions-api/kyb-upload-documents.md) pendant que la session se trouve à l'étape Documents KYB.
2) [Lisez les parties nommées dans les documents](https://docs.didit.me/fr/sessions-api/kyb-extracted-parties.md), y compris les actionnaires et les pourcentages de détention, et présentez-les à votre candidat.
3) [Créez](https://docs.didit.me/fr/sessions-api/kyb-create-party-draft.md), [modifiez](https://docs.didit.me/fr/sessions-api/kyb-update-party-draft.md) et [supprimez](https://docs.didit.me/fr/sessions-api/kyb-delete-party-draft.md) des [brouillons de parties](https://docs.didit.me/fr/sessions-api/kyb-list-party-drafts.md). Un brouillon n'est pas déclaré et ne coûte rien.
4) [Soumettez les brouillons](https://docs.didit.me/fr/sessions-api/kyb-submit-parties.md). Didit détermine quelles parties doivent être vérifiées, crée une session KYC pour chacune et renvoie son `kyc_session_url` à transmettre ou à intégrer.
5) Lisez la décision consolidée depuis la session, comme pour le parcours hébergé.Un appel effectué pendant que la session se trouve à une autre étape renvoie `409 kyb_step_mismatch` avec l'étape en cours, et une session terminée renvoie `409 kyb_session_not_writable`.## Agrégation du profil d'entrepriseSi vous transmettez `vendor_data` à la création de la session, Didit agrège toutes les sessions de cette entreprise dans une seule [entité Business](https://docs.didit.me/fr/entities/businesses/overview.md). Utilisez la carte `features` de l'entité pour savoir si cette entreprise est entièrement vérifiée actuellement, sans parcourir les sessions.Avantages :- Les flux de KYB périodiques (re-KYB) s'ajoutent au même profil.
- Les transactions surveillées avec le même `vendor_data` portent le contexte de risque de l'entreprise.
- Les UBO et dirigeants liés à des entités utilisateur alimentent les relations entre entités.## Bonnes pratiques| Pratique | Pourquoi |
| - | - |
| Transmettez toujours `vendor_data` | Sans lui, la session est orpheline et ne peut pas être agrégée. |
| Utilisez les webhooks plutôt que le polling | Latence plus faible, et aucune pression sur la limite de débit. |
| Vérifiez les signatures des webhooks | Empêche l'usurpation des événements. |
| Stockez le `session_id` de votre côté | Nécessaire pour récupérer la décision et générer les PDF. |
| Étiquetez les sessions avec `metadata` | Simplifie les rapports et le débogage. |
| Configurez un workflow de test | Utilisez un workflow sandbox pour les tests d'intégration avant la production. |## Gestion des erreurs| Scénario | Réponse |
| - | - |
| `workflow_id` invalide | `400 Bad Request` |
| Session en double avec le même `vendor_data` | Crée une nouvelle session. C'est voulu, car une revérification est attendue. |
| Pays de l'entreprise hors des pays autorisés par le workflow | La vérification dans le registre déclenche l'avertissement `KYB_COUNTRY_RESTRICTED`. |
| Panne du fournisseur de registre pendant la recherche d'entreprise | `POST /v3/kyb/search/` renvoie `502` avec `code: "kyb_registry_provider_unavailable"`. La requête n'est pas facturée. Réessayez, ou traitez le `code` pour proposer la saisie manuelle de l'entreprise. Dans le parcours hébergé de Didit, l'entreprise est automatiquement dirigée vers la saisie manuelle, au lieu de renvoyer uniquement une erreur nécessitant une nouvelle tentative. Voir [Recherche dans le registre KYB](https://docs.didit.me/fr/standalone-apis/kyb-registry-search.md#gérer-les-indisponibilités-du-registre). |
| Limite de débit | `429 Too Many Requests` avec l'en-tête `Retry-After`. |Référence complète sur la [limitation du débit](https://docs.didit.me/fr/integration/rate-limiting.md).## Étapes suivantes> [card] [Webhooks](https://docs.didit.me/fr/business-verification/webhooks.md)
>
> Chaque événement KYB et son payload.> [card] [Statuts](https://docs.didit.me/fr/business-verification/statuses.md)
>
> Référence de la machine à états.> [card] [Schéma de réponse](https://docs.didit.me/fr/business-verification/response-schema.md)
>
> Décodage de la décision KYB.


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