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

# Guida all'integrazione KYB: architettura e pattern

> Integrazione KYB con Didit in produzione: architettura, sessioni, webhook, polling e decisioni. Da $2.00 per verifica, per paese e livello.



Prompt di integrazione KYB
        Copia il prompt negli appunti



      
      

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



      
      

Incolla in

Questa guida è il complemento della [guida rapida](https://docs.didit.me/it/business-verification/quickstart.md). Descrive l'architettura, ogni decisione di integrazione e i modelli operativi che rendono la verifica KYB affidabile in produzione.## Architettura```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
```## AutenticazioneTutte le richieste richiedono l'intestazione `x-api-key` con la chiave API della tua applicazione. Consulta [Autenticazione API](https://docs.didit.me/it/getting-started/api-authentication.md) per la rotazione delle chiavi, la separazione degli ambienti e gli scope.## Creazione della sessioneEndpoint unico: `POST /v3/session/`. Il tipo del workflow determina se la sessione è KYC o KYB, quindi non serve alcun flag esplicito "business".**Campi consigliati in fase di creazione:**| Campo | Scopo |
| - | - |
| `workflow_id` | Obbligatorio: fa riferimento al tuo workflow KYB. |
| `vendor_data` | Il tuo identificativo per l'azienda. Associa la sessione a un'[entità Business](https://docs.didit.me/it/entities/businesses/overview.md). |
| `callback_url` | Facoltativo: indirizzo a cui reindirizzare l'utente al termine della verifica. |
| `expected_details` | Facoltativo: `{ company_name, registry_country, registration_number }`. Precompila la ricerca nel registro delle imprese: il paese di costituzione viene preselezionato e bloccato (`registry_country` come `XX`, oppure `XX-YY` per i registri a livello di stato, ad esempio `US-CA`), i campi della ragione sociale e del numero di registrazione vengono precompilati e la ricerca basata sui dati dichiarati viene eseguita automaticamente, combinando entrambi gli identificativi quando sono presenti. Solo precompilazione: eventuali discrepanze non generano avvisi. |
| `metadata` | Facoltativo: JSON allegato alla sessione. |Schema completo: [crea sessione](https://docs.didit.me/it/sessions-api/create-session.md).## Invio del link ospitatoL'`url` della risposta è un link di verifica ospitato. Opzioni per l'invio:- Inviarlo via email dalla tua piattaforma.
- Incorporarlo come link nella tua interfaccia di onboarding.
- Aprirlo in una webview interna all'app (iOS / Android / React Native).Puoi **personalizzare** l'esperienza ospitata (logo, colori, dominio, modelli delle email) tramite [White label](https://docs.didit.me/it/console/white-label.md).## Polling o webhookI webhook sono il modello consigliato. Didit invia eventi di completamento con una POST all'endpoint che hai sottoscritto non appena l'elaborazione termina.Il polling è supportato per lo sviluppo o quando il tuo endpoint webhook non è raggiungibile:* Esegui il polling di `GET /v3/session/{id}/decision/` con backoff esponenziale (ogni 10 s inizialmente, fino a 60 s).
* Interrompi il polling quando `status` è uno tra `"Approved"`, `"Declined"`, `"In Review"`.> [!WARNING]
>
> Un polling ad alta frequenza può superare i [limiti di frequenza](https://docs.didit.me/it/integration/rate-limiting.md). In produzione preferisci sempre i webhook.## Gestione dei webhookSottoscrivi gli eventi che ti interessano. Gli stessi eventi coprono sia KYC sia KYB, con `session_kind: "business"` nel payload per identificare gli eventi delle sessioni business:- `status.updated`: lo stato della sessione è cambiato. Filtra su `session_kind === "business"` per le sessioni KYB.
- `data.updated`: un revisore ha modificato i dati del registro o le persone chiave nella console, oppure il registro ha segnalato una modifica. Non viene inviato quando il richiedente carica un documento o invia le persone chiave: per questo segui `status.updated`. Vale lo stesso filtro su `session_kind`.
- `business.status.updated` / `business.data.updated`: l'[entità Business](https://docs.didit.me/it/entities/businesses/overview.md) collegata è cambiata.Catalogo completo degli eventi: [webhook KYB](https://docs.didit.me/it/business-verification/webhooks.md). Verifica della firma e comportamento dei nuovi tentativi: [riferimento dei webhook](https://docs.didit.me/it/integration/webhooks.md).## Gestione delle decisioni```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;
}
```Per la macchina a stati completa consulta [stati KYB](https://docs.didit.me/it/business-verification/statuses.md), e per i tag che spiegano una decisione consulta [avvisi KYB](https://docs.didit.me/it/business-verification/warnings.md).## Flusso di nuova presentazioneQuando una sessione di Verifica aziendale (KYB) passa a `Resubmitted` (oppure una funzionalità viene contrassegnata per la nuova presentazione), l'azienda deve caricare dati corretti o aggiuntivi.Puoi:- **Rinviare** lo stesso `url`: il flusso ospitato riprende dal punto in cui serve la nuova presentazione.
- **Riemettere un link non valido per una persona chiave**: a una parte la cui sessione KYC figlia è stata eliminata, o è scaduta prima che la persona la avviasse, viene assegnata una nuova sessione con [Rigenera la sessione KYC delle persone chiave](https://docs.didit.me/it/sessions-api/regenerate-kyb-party.md).
- **Aprire un [caso](https://docs.didit.me/it/transaction-monitoring/cases.md)** nella Business Console per tenere traccia internamente dello scambio.## Esegui i passaggi dal tuo front endI passaggi relativi ai documenti e alle persone chiave possono essere gestiti anche dal tuo server con la tua chiave API: così mantieni l'interfaccia utente e Didit mantiene la verifica e la decisione.
Ogni chiamata è limitata alla sessione KYB, richiede l'autorizzazione `write:businesses` (la lettura delle parti estratte accetta anche `read:businesses` o `read:sessions`) ed esegue gli stessi controlli, la stessa fatturazione e lo stesso avanzamento al passaggio successivo della pagina ospitata.1) [Carica i documenti societari](https://docs.didit.me/it/sessions-api/kyb-upload-documents.md) mentre la sessione si trova nel passaggio Documenti KYB.
2) [Leggi i soggetti nominati nei documenti](https://docs.didit.me/it/sessions-api/kyb-extracted-parties.md), inclusi gli azionisti e le percentuali di proprietà, e mostrali al tuo richiedente.
3) [Crea](https://docs.didit.me/it/sessions-api/kyb-create-party-draft.md), [modifica](https://docs.didit.me/it/sessions-api/kyb-update-party-draft.md) ed [elimina](https://docs.didit.me/it/sessions-api/kyb-delete-party-draft.md) [bozze di soggetti](https://docs.didit.me/it/sessions-api/kyb-list-party-drafts.md). Una bozza non è dichiarata e non ha costi.
4) [Invia le bozze](https://docs.didit.me/it/sessions-api/kyb-submit-parties.md). Didit decide quali parti devono essere verificate, crea una sessione KYC per ciascuna e restituisce il suo `kyc_session_url` da inviare o incorporare.
5) Leggi la decisione consolidata dalla sessione, come nel flusso ospitato.Una chiamata effettuata mentre la sessione si trova in un altro passaggio riceve `409 kyb_step_mismatch` con il passaggio in cui si trova, mentre una sessione conclusa riceve `409 kyb_session_not_writable`.## Aggregazione del profilo aziendaleSe passi `vendor_data` alla creazione della sessione, Didit aggrega tutte le sessioni di quell'azienda in un'unica [entità Business](https://docs.didit.me/it/entities/businesses/overview.md). Usa la mappa `features` dell'entità per rispondere alla domanda "questa azienda è completamente verificata in questo momento?" senza scorrere le sessioni.Vantaggi:- I flussi di re-KYB periodici si aggiungono allo stesso profilo.
- Le transazioni monitorate con lo stesso `vendor_data` portano il contesto di rischio dell'azienda.
- I titolari effettivi e gli amministratori collegati alle entità User popolano le relazioni tra entità.## Migliori pratiche| Pratica | Motivo |
| - | - |
| Passa sempre `vendor_data` | Senza di esso, la sessione resta orfana e non può essere aggregata. |
| Usa i webhook invece del polling | Latenza più bassa, nessuna pressione sul limite di frequenza. |
| Verifica le firme dei webhook | Impedisce eventi falsificati. |
| Memorizza il `session_id` nel tuo sistema | Serve per recuperare la decisione e generare i PDF. |
| Etichetta le sessioni con `metadata` | Semplifica la reportistica e il debugging. |
| Configura un workflow di test | Usa un workflow sandbox per i test di integrazione prima della produzione. |## Gestione degli errori| Scenario | Risposta |
| - | - |
| `workflow_id` non valido | `400 Bad Request` |
| Sessione duplicata con lo stesso `vendor_data` | Crea una nuova sessione: è il comportamento previsto, perché è prevista una nuova verifica. |
| Paese dell'azienda al di fuori dei paesi consentiti dal workflow | Il controllo del registro genera l'avviso `KYB_COUNTRY_RESTRICTED`. |
| Interruzione del provider del registro durante la ricerca dell'azienda | `POST /v3/kyb/search/` restituisce `502` con `code: "kyb_registry_provider_unavailable"`. Non viene fatturata: riprova, oppure usa `code` per proporre l'inserimento manuale dell'azienda. Nel flusso ospitato di Didit, l'azienda viene indirizzata automaticamente all'inserimento manuale invece di ricevere un errore che prevede solo il nuovo tentativo. Vedi [Ricerca nel registro KYB](https://docs.didit.me/it/standalone-apis/kyb-registry-search.md#gestire-le-interruzioni-del-registro). |
| Limite di frequenza | `429 Too Many Requests` con l'intestazione `Retry-After`. |Riferimento completo sui [limiti di frequenza](https://docs.didit.me/it/integration/rate-limiting.md).## Prossimi passi> [card] [Webhook](https://docs.didit.me/it/business-verification/webhooks.md)
>
> Ogni evento e payload KYB.> [card] [Stati](https://docs.didit.me/it/business-verification/statuses.md)
>
> Riferimento alla macchina a stati.> [card] [Schema della risposta](https://docs.didit.me/it/business-verification/response-schema.md)
>
> Come decodificare la decisione KYB.


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