Skip to main content
This guide walks you through a complete KYB verification in under 10 minutes. You’ll create a workflow, start a session, deliver the hosted verification link to your business contact, wait for the webhook, and fetch the final decision.

Prerequisites

  • A Didit application with KYB enabled. Create one at business.didit.me if needed.
  • An API key from Developer Settings → API Keys.
  • A webhook endpoint reachable from the internet (for the decision webhook).

Steps

1

Create a KYB workflow in the console

Navigate to Workflows → Create workflow. Choose Business Verification as the workflow type.Enable the features you need:
  • Company registry lookup (required)
  • Company AML (recommended)
  • Key People (required for most regulated industries)
  • Documents (optional — pick document types you’ll require)
Save and copy the workflow_id — you’ll use it in the next step.
2

Create a Business Verification (KYB) session via the API

curl -X POST https://verification.didit.me/v3/session/ \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_id": "YOUR_KYB_WORKFLOW_ID",
    "vendor_data": "biz-acme-001"
  }'
The response contains the session_id, session_number, and url — the hosted verification link you deliver to the business contact. The workflow’s type (KYB) automatically flags the session as a business session.
3

Send the link to your business contact

Deliver the url to the company admin via your own email or chat. They open it, fill in the registry data, add key people and UBOs, and upload documents.You can customize the hosted experience with branding, logo, and domain — see White-label.
4

Receive the status webhook

When the business finishes the flow and KYB processing reaches a terminal status, Didit POSTs a status.updated event to your webhook endpoint. Business-session events carry session_kind: "business" inside data — filter on that to route the event to your KYB handler.Verify the HMAC signature (see webhooks) and trigger your downstream logic.Example payload:
{
  "event": "status.updated",
  "application_id": "app_abc123",
  "timestamp": "2026-04-18T12:30:00Z",
  "data": {
    "session_id": "bs_01H...",
    "session_kind": "business",
    "vendor_data": "biz-acme-001",
    "status": "APPROVED",
    "previous_status": "IN_PROGRESS"
  }
}
5

Retrieve the decision (optional)

The status.updated webhook payload already contains the full decision. You only need to call this endpoint if you didn’t subscribe to webhooks, or you want to fetch the decision on demand later.
curl https://verification.didit.me/v3/session/bs_01H.../decision/ \
  -H "x-api-key: YOUR_API_KEY"
The decision includes registry data, key people (UBOs, shareholders, directors and representatives), AML hits, documents, and per-feature results. See response schema for the full payload reference.
6

Act on the decision

Based on status:
  • APPROVED — onboard the business.
  • DECLINED — reject and log the reason code.
  • IN_REVIEW — wait for the analyst decision; you’ll receive another webhook when it resolves.

Node.js example

import fetch from 'node-fetch';

const API_KEY = process.env.DIDIT_API_KEY!;
const WORKFLOW_ID = process.env.DIDIT_KYB_WORKFLOW_ID!;
const BASE_URL = 'https://verification.didit.me';

async function startKybVerification(vendorData: string) {
  const res = await fetch(`${BASE_URL}/v3/session/`, {
    method: 'POST',
    headers: {
      'x-api-key': API_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ workflow_id: WORKFLOW_ID, vendor_data: vendorData }),
  });
  if (!res.ok) throw new Error(`Session create failed: ${res.status}`);
  return res.json();
}

async function getDecision(sessionId: string) {
  const res = await fetch(`${BASE_URL}/v3/session/${sessionId}/decision/`, {
    headers: { 'x-api-key': API_KEY },
  });
  return res.json();
}

// Kick off the flow
const { session_id, url } = await startKybVerification('biz-acme-001');
console.log('Deliver this URL to your contact:', url);

// ... later, after the webhook confirms completion:
const decision = await getDecision(session_id);
console.log('KYB status:', decision.status);

What happens automatically

  • Company registry lookup against 190+ jurisdictions.
  • UBO and officer extraction from registry data.
  • Company-level AML screening (sanctions, PEP, adverse media).
  • Person-level AML for each identified party.
  • Document OCR and cross-referencing.
  • Business profile creation and aggregation keyed by vendor_data.

Next steps

Integration guide

End-to-end architecture, polling vs webhooks, retry logic.

KYB webhooks

Every KYB event and payload shape.

Statuses

Session, feature, and registry status reference.

Response schema

The full KYB decision payload.

Business entities

How profiles aggregate across sessions.

Troubleshooting

Common issues and fixes.