Step 1: Get Your Credentials
You have two ways to obtain anapi_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
- Go to the Didit Console.
- Create or select your organization.
- Navigate to Settings → API & Webhooks.
- Copy:
- API Key — used as the
x-api-keyheader on every verification call. - Webhook Secret Key — used to verify webhook HMAC signatures.
- API Key — used as the
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
- Go to Didit Console → Workflows
- Click Create Workflow
- Choose a base template:
- Add optional features:
- 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:Option A: Native SDK (recommended for mobile)
Use thesession_token with the native SDKs for camera, NFC, and biometric integration.
→ iOS SDK · Android SDK · React Native · Flutter
Option B: InContext iframe (recommended for web)
Embed the verification in your page using theurl returned in Step 3.
Option C: Redirect
Redirect the user to the verification URL.Option D: Mobile WebView
For mobile apps without a native SDK.Step 5: Receive Results
Via Webhook (Recommended)
Webhooks notify your server in real-time when verification status changes. Setup:- Create a webhook destination in the Console (API & Webhooks) or via
POST /v3/webhook/destinations/withwebhook_version: "v3"and asubscribed_eventsarray (e.g.["status.updated"]) - Store the
secret_shared_keyreturned on creation — it is the HMAC secret for all signature variants - Implement a webhook endpoint on your server
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.
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.
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: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 ofstatus — 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
- Choose your integration method:
- Mobile apps → Native SDKs
- Web apps → Web SDKs
- Configure webhooks: Webhooks
- Plan capacity: Rate limiting
- Handle every status: Verification statuses
- Customize your workflow: Workflows
- Verify the API is reachable: Healthcheck
Need help?
- Support: support@didit.me
- Programmatic onboarding: Programmatic registration