Skip to main content
This guide walks you through the complete flow for integrating Didit identity verification via the REST API: get credentials, create a session, present it to the user, and receive results.

Step 1: Get Your Credentials

You have two ways to obtain an api_key:

Option A: Programmatic registration (no browser)

Best for CI/CD and AI agents. Two API calls — POST /programmatic/register/ then POST /programmatic/verify-email/ — return the api_key inline. → See Programmatic Registration for the full flow, password rules, JWT lifetime, and lockout policy.

Option B: From the Didit Console

  1. Go to the Didit Console.
  2. Create or select your organization.
  3. Navigate to SettingsAPI & Webhooks.
  4. Copy:
    • API Key — used as the x-api-key header on every verification call.
    • Webhook Secret Key — used to verify webhook HMAC signatures.

Environment variables


Step 2: Create a Workflow

Before creating sessions, you need a verification workflow. Workflows define what verification steps users go through.

Create in Console

  1. Go to Didit ConsoleWorkflows
  2. Click Create Workflow
  3. Choose a base template:
  1. Add optional features:
  1. Copy your Workflow ID
See Workflows Documentation for detailed configuration options.

Step 3: Create a Verification Session

Call the API to create a session for your user.

Request

Request Parameters

Full Example with All Options

expected_details.expected_document_types restricts the ID verification step to specific document types — the document selection screen only shows the requested types. Allowed values: P (passport), ID (national ID), DL (driver’s licence), RP (residence permit), HIC (health insurance card), TC (tax card), SSC (social security card). Values are case-insensitive and deduplicated; unknown values return 400. See the Create Session reference for the full schema.

Response

201 Created:

Key Response Fields

Idempotency. When vendor_data is provided and an unfinished session (Not Started, In Progress, Resubmitted, or Awaiting User) with the same vendor_data already exists on the workflow’s latest published version, that existing session is returned (still 201) instead of creating a duplicate — with its callback and metadata updated to the new values, and status reflecting the existing session.
Auth errors are 403, never 401. A missing, malformed, or expired x-api-key returns 403 with {"detail": "You do not have permission to perform this action."} — the same body as a valid key without permission. Insufficient credits return 400. See Create Session API Reference for complete documentation.

Step 4: Present Verification to User

Choose how to present the verification flow to your user: Use the session_token with the native SDKs for camera, NFC, and biometric integration. iOS SDK · Android SDK · React Native · Flutter Embed the verification in your page using the url returned in Step 3.
InContext iframe

Option C: Redirect

Redirect the user to the verification URL.
Web redirect

Option D: Mobile WebView

For mobile apps without a native SDK.
WebView in iOS/Android

Step 5: Receive Results

Webhooks notify your server in real-time when verification status changes. Setup:
  1. Create a webhook destination in the Console (API & Webhooks) or via POST /v3/webhook/destinations/ with webhook_version: "v3" and a subscribed_events array (e.g. ["status.updated"])
  2. Store the secret_shared_key returned on creation — it is the HMAC secret for all signature variants
  3. Implement a webhook endpoint on your server
Example webhook payload: Inside decision, every per-feature result is delivered as a plural array (id_verifications[], nfc_verifications[], liveness_checks[], face_matches[], …) — one entry per node in the workflow. This is the V3 contract and is sacred: never code against a singular nfc / id_verification / liveness key.
The decision object is only present when status is Approved, Declined, In Review, or Abandoned (a Resubmitted event carries resubmit_info instead). Didit reuses the same event_id across retries and fan-out destinations — key your idempotency on it. See Data models for every plural array and field. Verify the signature (X-Signature-V2, recommended): X-Signature-V2 is HMAC-SHA256 over a canonical re-encoding of the JSON body: whole-valued floats shortened to ints, keys sorted recursively, compact separators, Unicode preserved.
Full webhooks documentation, including the raw-bytes X-Signature, the envelope-only X-Signature-Simple, and how to pick. Didit retries failed deliveries (5xx, 404, timeout) up to 2 times (~1 min, then ~4 min) and times out after 5 seconds — return 2xx fast.

Via API (optional)

Fetch the same decision payload at any time:
The response shape (plural arrays) is identical to the decision object inside the webhook payload, and the endpoint can be called at any point in the session lifecycle. Use webhooks for real-time updates and reserve API calls for backfill, audit, and rebuilds — the /decision/ endpoint is rate-limited to 600 GET requests/min per API key (see Rate limiting). Error semantics: an unknown session_id returns 404 with {"detail": "Not found."}; authentication failures surface as 403 — this endpoint never returns 401. Media URLs in the response are short-lived presigned links — fetch them promptly rather than persisting them. Retrieve session API reference

Complete Code Examples

Node.js / Express

Python / FastAPI


Session statuses

These are the 10 possible values of status — exact, case-sensitive strings (note Kyc Expired uses a single capital K): See Verification statuses for the full lifecycle, transitions, and Mermaid diagram.

Next steps

  1. Choose your integration method:
  2. Configure webhooks: Webhooks
  3. Plan capacity: Rate limiting
  4. Handle every status: Verification statuses
  5. Customize your workflow: Workflows
  6. Verify the API is reachable: Healthcheck

Need help?