Skip to main content
The Didit JavaScript SDK provides a programmatic way to integrate verification into your web application with full control over the user experience.

Features

  • Simple API - Singleton pattern with easy-to-use methods
  • Flexible Integration - Use UniLink URL directly or create sessions via backend
  • Responsive - Works on desktop and mobile browsers
  • Customizable - Configuration options for styling and behavior
  • Multiple Formats - ESM, CommonJS, and UMD builds
  • TypeScript Support - Full type definitions included
  • Modal & Inline Modes - Choose between modal overlay or inline embedding
  • Event Callbacks - Real-time events for verification progress (started, step completed, finished)
  • State Management - Observe SDK state for custom UI

Installation

NPM/Yarn

npm install @didit-protocol/sdk-web
# or
yarn add @didit-protocol/sdk-web

CDN (UMD)

<script src="https://unpkg.com/@didit-protocol/sdk-web/dist/didit-sdk.umd.min.js"></script>

Vanilla JavaScript

ES Modules / TypeScript

import { DiditSdk } from '@didit-protocol/sdk-web';

// Set up completion callback
DiditSdk.shared.onComplete = (result) => {
  switch (result.type) {
    case 'completed':
      console.log('Verification completed!');
      console.log('Session ID:', result.session?.sessionId);
      console.log('Status:', result.session?.status);
      break;
    case 'cancelled':
      console.log('User cancelled verification');
      break;
    case 'failed':
      console.error('Verification failed:', result.error?.message);
      break;
  }
};

// Start verification with the `url` returned by POST /v3/session/ (or your UniLink)
DiditSdk.shared.startVerification({
  url: 'https://verify.didit.me/session/3FaJ9wLqX2Mz'
});

Script Tag (UMD)

<script src="https://unpkg.com/@didit-protocol/sdk-web/dist/didit-sdk.umd.min.js"></script>
<script>
  const { DiditSdk } = DiditSDK;

  DiditSdk.shared.onComplete = (result) => {
    if (result.type === 'completed') {
      alert('Verification completed: ' + result.session.status);
    }
  };

  function startVerification() {
    DiditSdk.shared.startVerification({
      // You can get this link by clicking on "copy link" in the workflows view
      url: 'https://verify.didit.me/u/WORKFLOW_ID_IN_BASE_64'
    });
  }
</script>

<button onclick="startVerification()">Verify Identity</button>

Framework Examples

SDK Web Examples

React, Angular, Svelte, Next.js, Nuxt, Vue, and more — with examples and documentation for each framework.

Integration Methods

There are two ways to integrate the SDK: Use your workflow’s UniLink URL directly from the Didit Console. No backend required.
DiditSdk.shared.startVerification({
  // You can get this link by clicking on "copy link" in the workflows view
  url: 'https://verify.didit.me/u/WORKFLOW_ID_IN_BASE_64'
});
Get your UniLink URL from the Didit Console → Your Workflow → Copy Link. The session_id generated will be sent to you by an event. Check event reference here Your backend creates a session via the Didit API and returns the hosted verification URL. This gives you control over vendor_data, per-session callback, metadata, and lets you create sessions before the user reaches the frontend. Read more in the Create Session API reference. Backend (Node.js / Express)
import express from 'express';
const app = express();
app.use(express.json());

app.post('/api/create-session', async (req, res) => {
  const response = await fetch('https://verification.didit.me/v3/session/', {
    method: 'POST',
    headers: {
      'x-api-key': process.env.DIDIT_API_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      workflow_id: process.env.DIDIT_WORKFLOW_ID,
      vendor_data: req.body.userId,             // links the session to your user
      callback: 'https://yourapp.com/verified', // optional — overrides workflow default
    }),
  });

  if (!response.ok) {
    return res.status(response.status).send(await response.text());
  }

  // 201 response fields (per OpenAPI): session_id, session_number, session_token, url,
  // vendor_data, metadata, status, workflow_id, workflow_version, callback
  const session = await response.json();
  res.json({ session_id: session.session_id, url: session.url });
});
Frontend
import { DiditSdk } from '@didit-protocol/sdk-web';

const res = await fetch('/api/create-session', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ userId: 'user-123' }),
});
const { url } = await res.json();

DiditSdk.shared.startVerification({
  url,
  configuration: {
    loggingEnabled: true,
  },
});
The session-create response field is named url (see the Create Session OpenAPI schema). Pass it directly to startVerification({ url }).

Configuration

OptionTypeDefaultDescription
loggingEnabledbooleanfalseEnable SDK logging for debugging
containerElementHTMLElementdocument.bodyCustom container element to mount the modal
zIndexnumber9999Z-index for the modal overlay
showCloseButtonbooleantrueShow close button on modal
showExitConfirmationbooleantrueShow exit confirmation dialog when closing
closeModalOnCompletebooleanfalseAutomatically close modal when verification completes
embeddedbooleanfalseRender verification inline instead of modal overlay
embeddedContainerIdstringContainer element ID for embedded mode (required when embedded is true)
See the full TypeScript type definitions below for the complete DiditSdkConfiguration interface.

Embedded Mode

Render verification inline instead of a modal overlay:
<div id="verification-container" style="width: 500px; height: 700px;"></div>
DiditSdk.shared.startVerification({
  url: 'https://verify.didit.me/u/...',
  configuration: {
    embedded: true,
    embeddedContainerId: 'verification-container'
  }
});

Verification Results

The SDK returns three types of results:

Completed

Verification flow finished (approved, pending, or declined).
{
  type: 'completed',
  session: {
    sessionId: 'session-uuid',
    status: 'Approved' | 'Pending' | 'Declined'
  }
}
The TypeScript type declares 'Approved' | 'Pending' | 'Declined', but the value is passed through from the hosted flow’s session status — you can also receive other statuses such as In Review. Pending is the SDK’s fallback when the flow reported no status. Treat status as a hint and rely on the webhook for the canonical decision.

Cancelled

User closed the verification modal. session is included when a sessionId was already known (it can be undefined if the user cancelled before the iframe reported one).
{
  type: 'cancelled',
  session: {
    sessionId: 'session-uuid',
    status: 'Pending'
  }
}

Failed

An error occurred during verification.
{
  type: 'failed',
  error: {
    type: 'sessionExpired' | 'networkError' | 'cameraAccessDenied' | 'unknown',
    message: 'Your verification session has expired.'
  }
}

State Management

You can observe the SDK state for custom UI:
DiditSdk.shared.onStateChange = (state, error) => {
  switch (state) {
    case 'idle':
      // Ready to start
      break;
    case 'loading':
      // Loading verification iframe
      showLoadingSpinner();
      break;
    case 'ready':
      // Verification in progress
      hideLoadingSpinner();
      break;
    case 'error':
      // Error occurred
      showError(error);
      break;
  }
};

// Check current state
console.log(DiditSdk.shared.state);

// Check if verification is presented
console.log(DiditSdk.shared.isPresented);

API Reference

DiditSdk.shared

The singleton SDK instance.

Methods

MethodDescription
startVerification(options)Start the verification flow
close()Programmatically close the verification modal
destroy()Destroy the SDK instance and clean up

Properties

PropertyTypeDescription
stateDiditSdkStateCurrent SDK state
configurationDiditSdkConfiguration | undefinedActive configuration (set while a verification is in progress)
isPresentedbooleanWhether verification modal is open
errorMessagestring | undefinedError message (set when state is error)

Callbacks

CallbackParametersDescription
onComplete(result: VerificationResult)Called when verification finishes
onStateChange(state: DiditSdkState, error?: string)Called on state changes
onEvent(event: VerificationEvent)Called on granular verification events

Granular Events

Track verification progress with the onEvent callback:
DiditSdk.shared.onEvent = (event) => {
  console.log('Event:', event.type, event.data);
};

Event Reference

EventDescriptionData Payload
didit:readyThe page is ready and the sessionId is available{ sessionId }
didit:startedUser started verification{ sessionId? }
didit:step_startedA verification step began{ step, sessionId? }
didit:step_completedA step finished successfully{ step, nextStep?, sessionId? }
didit:step_changedCurrent step changed{ step, previousStep?, sessionId? }
didit:media_startedCamera/media capture started{ step, mediaType }
didit:media_capturedPhoto/video captured{ step, isAuto }
didit:document_selectedUser selected document type and country{ documentType, country }
didit:verification_submittedData submitted for processing{ step, sessionId? }
didit:code_sentOTP code sent{ step, channel?, codeSize?, sessionId? }
didit:code_verifiedOTP code verified{ step, sessionId? }
didit:status_updatedSession status changed{ status, previousStep?, sessionId? }
didit:completedVerification flow completed{ sessionId?, status?, country?, documentType? }
didit:cancelledUser cancelled verification{ sessionId? }
didit:errorAn error occurred{ error: string, step?, sessionId? }
didit:close_requestUser requested to close modal(no data)

Step Values

The step field can be one of:
  • document_selection - Document type selection
  • document_front - Front side of document
  • document_back - Back side of document
  • face - Face/liveness verification
  • email - Email verification
  • phone - Phone verification
  • poa - Proof of address
  • questionnaire - Questionnaire step

Channel Values

The channel field in code_sent can be:
  • email - Code sent via email
  • sms - Code sent via SMS
  • whatsapp - Code sent via WhatsApp

Code Size

The codeSize field in code_sent indicates the OTP code length (e.g., 4 or 6 digits).

TypeScript Types

// Configuration types
interface DiditSdkConfiguration {
  /**
   * Enable SDK logging for debugging
   * @default false
   */
  loggingEnabled?: boolean;

  /**
   * Custom container element to mount the modal
   * @default document.body
   */
  containerElement?: HTMLElement;

  /**
   * Z-index for the modal overlay
   * @default 9999
   */
  zIndex?: number;

  /**
   * Show close button on modal
   * @default true
   */
  showCloseButton?: boolean;

  /**
   * Show exit confirmation dialog when closing
   * @default true
   */
  showExitConfirmation?: boolean;

  /**
   * Automatically close modal when verification completes
   * @default false
   */
  closeModalOnComplete?: boolean;

  /**
   * Render verification inline instead of modal overlay
   * @default false
   */
  embedded?: boolean;

  /**
   * Container element ID for embedded mode
   * Required when embedded is true
   */
  embeddedContainerId?: string;
}

// Session + error types
type VerificationStatus = 'Approved' | 'Pending' | 'Declined';

interface SessionData {
  sessionId: string;
  status: VerificationStatus;
}

type VerificationErrorType =
  | 'sessionExpired'
  | 'networkError'
  | 'cameraAccessDenied'
  | 'unknown';

interface VerificationError {
  type: VerificationErrorType;
  message: string;
}

// Verification result — `session` and `error` are both optional fields
// on every result; which one is populated depends on `type`.
type VerificationResultType = 'completed' | 'cancelled' | 'failed';

interface VerificationResult {
  type: VerificationResultType;
  session?: SessionData;
  error?: VerificationError;
}

// State types
type DiditSdkState = 'idle' | 'loading' | 'ready' | 'error';

// Event types
type VerificationEventType =
  | 'didit:ready'
  | 'didit:started'
  | 'didit:step_started'
  | 'didit:step_completed'
  | 'didit:step_changed'
  | 'didit:media_started'
  | 'didit:media_captured'
  | 'didit:document_selected'
  | 'didit:verification_submitted'
  | 'didit:code_sent'
  | 'didit:code_verified'
  | 'didit:status_updated'
  | 'didit:completed'
  | 'didit:cancelled'
  | 'didit:error'
  | 'didit:close_request';

interface VerificationEventData {
  sessionId?: string;
  status?: string;
  step?: string;
  nextStep?: string;
  previousStep?: string;
  error?: string;
  country?: string;
  documentType?: string;
  isAuto?: boolean;
  mediaType?: string;
  channel?: string;
  codeSize?: number;
  [key: string]: unknown;
}

interface VerificationEvent {
  type: VerificationEventType;
  data?: VerificationEventData;
  timestamp?: number;
}

// Start verification options
interface StartVerificationOptions {
  url: string;
  configuration?: DiditSdkConfiguration;
}