didit-verification-management

Full Didit identity verification platform management — account creation, API keys, sessions, workflows, questionnaires, users, billing, blocklist, and webhooks. Use when someone needs to create a Didit account, get API keys, set up verification workflows, create or retrieve verification sessions, approve or decline sessions, manage users, check credit balance, top up credits, configure blocklists, configure webhooks programmatically, handle webhook signatures, or perform any platform administration. 45+ endpoints across 9 categories.

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "didit-verification-management" with this command: npx skills add rosasalberto/didit-verification-management

Didit Identity Verification Platform

The single skill for the entire Didit verification platform. Covers account creation, session management, workflow configuration, questionnaires, user management, billing, blocklist, and webhook configuration — 45+ endpoints across 9 categories.

For standalone verification APIs (ID scan, liveness, face match, AML, etc.), see the individual didit-* skills.

API Reference Links:


Getting Started — Zero to Verifying

Go from nothing to a live verification link in 4 API calls, no browser needed:

import requests

# 1. Register (any email, no business email required)
requests.post("https://apx.didit.me/auth/v2/programmatic/register/",
    json={"email": "you@gmail.com", "password": "MyStr0ng!Pass"})

# 2. Check email for 6-char OTP, then verify → get api_key
resp = requests.post("https://apx.didit.me/auth/v2/programmatic/verify-email/",
    json={"email": "you@gmail.com", "code": "A3K9F2"})
api_key = resp.json()["application"]["api_key"]
headers = {"x-api-key": api_key, "Content-Type": "application/json"}

# 3. Create a KYC workflow
wf = requests.post("https://verification.didit.me/v3/workflows/",
    headers=headers,
    json={"workflow_label": "My KYC", "workflow_type": "kyc",
          "is_liveness_enabled": True, "is_face_match_enabled": True}).json()

# 4. Create a session → send user to the URL
session = requests.post("https://verification.didit.me/v3/session/",
    headers=headers,
    json={"workflow_id": wf["uuid"], "vendor_data": "user-123"}).json()
print(f"Send user to: {session['url']}")

To add credits: GET /v3/billing/balance/ to check, POST /v3/billing/top-up/ with {"amount_in_dollars": 50} for a Stripe checkout link.


Authentication

Two auth schemes are used across the platform:

EndpointsAuthHeader
Register, Verify Email, LoginNone(unauthenticated)
List Organizations, Get CredentialsBearerAuthorization: Bearer <access_token>
Everything else (sessions, workflows, etc.)API Keyx-api-key: <api_key>

Get your api_key via programmatic registration (above) or from Didit Business Console → API & Webhooks.


Account Setup

Base URL: https://apx.didit.me/auth/v2

1. Register

POST /programmatic/register/
BodyTypeRequiredDescription
emailstringYesAny email address
passwordstringYesMin 8 chars, 1 upper, 1 lower, 1 digit, 1 special

Response (201): {"message": "Registration successful...", "email": "..."}

Rate limit: 5 per IP per hour.

2. Verify Email & Get Credentials

POST /programmatic/verify-email/
BodyTypeRequiredDescription
emailstringYesSame email from register
codestringYes6-character alphanumeric OTP from email

Response (200):

{
  "access_token": "eyJ...",
  "refresh_token": "eyJ...",
  "expires_in": 86400,
  "organization": {"uuid": "...", "name": "..."},
  "application": {"uuid": "...", "client_id": "...", "api_key": "YOUR_KEY_HERE"}
}

application.api_key is the x-api-key for all subsequent calls.

3. Login (Existing Accounts)

POST /programmatic/login/
BodyTypeRequiredDescription
emailstringYesAccount email
passwordstringYesAccount password

Response (200): {"access_token": "...", "refresh_token": "...", "expires_in": 86400}

Progressive lockout: 5 fails = 15min, 10 = 1hr, 20 = 24hr.

4. List Organizations

GET /organizations/me/

Auth: Authorization: Bearer <access_token>

Response (200): Array of {"uuid": "...", "name": "...", "contact_email": "..."}

5. Get Application Credentials

GET /organizations/me/{org_id}/applications/{app_id}/

Auth: Authorization: Bearer <access_token>

Response (200): {"uuid": "...", "client_id": "...", "api_key": "..."}


Workflows

Base URL: https://verification.didit.me/v3

Workflows define verification steps, thresholds, and accepted documents. Each has a UUID used as workflow_id when creating sessions.

Workflow Types:

TypePurposeTypical Features
kycFull identity verification (ID + selfie)ID Verification, Liveness, Face Match, AML, NFC
adaptive_age_verificationAge gating with ID fallback for borderline casesAge Estimation, Liveness, per-country age restrictions
biometric_authenticationRe-verify returning users (no document)Liveness, Face Match against stored portrait
address_verificationVerify proof of address documentsProof of Address, geocoding, name matching
questionnaire_verificationCustom form/questionnaire verificationQuestionnaire, optional ID/liveness add-ons
email_verificationEmail OTP verification as a workflowEmail send/check, breach/disposable detection
phone_verificationPhone OTP verification as a workflowPhone send/check, carrier/VoIP detection

Features (toggleable per workflow): ID Verification, Liveness, Face Match, NFC, AML, Phone, Email, Proof of Address, Database Validation, IP Analysis, Age Estimation, Questionnaire.

1. List Workflows

GET /v3/workflows/

Response (200): Array of workflow objects with uuid, workflow_label, workflow_type, is_default, features, total_price.

2. Create Workflow

POST /v3/workflows/
BodyTypeDefaultDescription
workflow_labelstringautoDisplay name
workflow_typestringkycWorkflow template type
is_defaultbooleanfalseSet as default
is_liveness_enabledbooleanfalseLiveness detection
face_liveness_methodstringpassive"passive", "active_3d", "flashing"
face_liveness_score_decline_thresholdinteger50Below this → auto-decline
is_face_match_enabledbooleanfalseSelfie-to-document match
face_match_score_decline_thresholdinteger50Below this → auto-decline
face_match_score_review_thresholdinteger70Below this → manual review
is_aml_enabledbooleanfalseAML/PEP/sanctions screening
aml_decline_thresholdinteger80Above this → auto-decline
is_phone_verification_enabledbooleanfalsePhone verification step
is_email_verification_enabledbooleanfalseEmail verification step
is_database_validation_enabledbooleanfalseGov database validation
is_ip_analysis_enabledbooleanfalseIP risk analysis
is_nfc_enabledbooleanfalseNFC chip reading (mobile only, ePassports)
is_age_restrictions_enabledbooleanfalseEnable per-country age restrictions (for adaptive_age_verification)
documents_allowedobject{}Restrict accepted countries/doc types (empty = accept all)
duplicated_user_actionstringno_actionno_action, review, decline (set after creation via update)
max_retry_attemptsinteger3Max retries per session
retry_window_daysinteger7Days within which retries are allowed

Response (201): Workflow object with uuid.

wf = requests.post("https://verification.didit.me/v3/workflows/",
    headers={"x-api-key": API_KEY, "Content-Type": "application/json"},
    json={"workflow_label": "KYC + AML", "workflow_type": "kyc",
          "is_liveness_enabled": True, "is_face_match_enabled": True,
          "is_aml_enabled": True}).json()

3. Get Workflow

GET /v3/workflows/{settings_uuid}/

4. Update Workflow

PATCH /v3/workflows/{settings_uuid}/

Partial update — only send fields to change.

5. Delete Workflow

DELETE /v3/workflows/{settings_uuid}/

Response: 204 No Content. Existing sessions are not affected.


Sessions

Base URL: https://verification.didit.me/v3

Sessions are the core unit of verification. Every verification starts by creating a session linked to a workflow.

Lifecycle: Create → User verifies at URL → Webhook/poll decision → Optionally update status

Statuses: Not Started, In Progress, In Review, Approved, Declined, Abandoned, Expired, Resubmitted

Rate limits: 300 req/min per method. Session creation: 600/min. Decision polling: 100/min.

1. Create Session

POST /v3/session/
BodyTypeRequiredDescription
workflow_iduuidYesWorkflow UUID
vendor_datastringNoYour user identifier
callbackurlNoRedirect URL (Didit appends verificationSessionId + status)
callback_methodstringNo"initiator", "completer", or "both"
metadataJSON stringNoCustom data stored with session
languagestringNoISO 639-1 UI language
contact_details.emailstringNoPre-fill email for email verification step
contact_details.phonestringNoPre-fill phone (E.164) for phone verification step
contact_details.send_notification_emailsbooleanNoSend status update emails to user
contact_details.email_langstringNoLanguage for email notifications (ISO 639-1)
expected_details.first_namestringNoTriggers mismatch warning if different (fuzzy match)
expected_details.last_namestringNoExpected last name (fuzzy match)
expected_details.date_of_birthstringNoYYYY-MM-DD
expected_details.genderstringNo"M", "F", or null
expected_details.nationalitystringNoISO 3166-1 alpha-3 country code
expected_details.id_countrystringNoISO alpha-3 for expected ID document country (overrides nationality)
expected_details.poa_countrystringNoISO alpha-3 for expected PoA document country
expected_details.addressstringNoExpected address (human-readable, for PoA matching)
expected_details.identification_numberstringNoExpected document/personal/tax number
expected_details.ip_addressstringNoExpected IP address (logs warning if different)
portrait_imagebase64NoReference portrait for Biometric Auth (max 1MB)

Response (201):

{
  "session_id": "...",
  "session_number": 1234,
  "session_token": "abcdef123456",
  "url": "https://verify.didit.me/session/abcdef123456",
  "status": "Not Started",
  "workflow_id": "..."
}

Send the user to url to complete verification.

2. Retrieve Session (Get Decision)

GET /v3/session/{sessionId}/decision/

Returns all verification results. Image URLs expire after 60 minutes.

Response (200): Full decision with status, features, id_verifications, liveness_checks, face_matches, aml_screenings, phone_verifications, email_verifications, poa_verifications, database_validations, ip_analyses, reviews.

3. List Sessions

GET /v3/sessions/
QueryTypeDefaultDescription
vendor_datastringFilter by your user identifier
statusstringFilter by status (e.g. Approved, Declined, In Review)
countrystringFilter by ISO 3166-1 alpha-3 country code
workflow_idstringFilter by workflow UUID
offsetinteger0Number of items to skip
limitinteger20Max items to return

Response (200): Paginated list with count, next, previous, results[].

4. Delete Session

DELETE /v3/session/{sessionId}/delete/

Response: 204 No Content. Permanently deletes all associated data.

5. Batch Delete Sessions

POST /v3/sessions/delete/
BodyTypeDescription
session_numbersarrayList of session numbers to delete
delete_allbooleanDelete all sessions (use with caution)

6. Update Session Status

PATCH /v3/session/{sessionId}/update-status/
BodyTypeRequiredDescription
new_statusstringYes"Approved", "Declined", or "Resubmitted"
commentstringNoReason for change
send_emailbooleanNoSend notification email
email_addressstringConditionalRequired when send_email is true
email_languagestringNoEmail language (default: "en")
nodes_to_resubmitarrayNoFor Resubmitted: [{"node_id": "feature_ocr", "feature": "OCR"}]

Resubmit requires session to be Declined, In Review, or Abandoned.

7. Generate PDF Report

GET /v3/session/{sessionId}/generate-pdf

Rate limit: 100 req/min.

8. Share Session

POST /v3/session/{sessionId}/share/

Generates a share_token for B2B KYC sharing. Only works for finished sessions.

9. Import Shared Session

POST /v3/session/import-shared/
BodyTypeRequiredDescription
share_tokenstringYesToken from sharing partner
trust_reviewbooleanYestrue: keep original status; false: set to "In Review"
workflow_idstringYesYour workflow ID
vendor_datastringNoYour user identifier

A session can only be imported once per partner application.

10. List Session Reviews

GET /v3/sessions/{session_id}/reviews/

Response (200): Array of review activity items:

[
  {
    "id": 1,
    "action": "status_change",
    "old_status": "In Review",
    "new_status": "Approved",
    "note": "Document verified manually",
    "created_at": "2025-06-01T15:00:00Z"
  }
]

11. Create Session Review

POST /v3/sessions/{session_id}/reviews/
BodyTypeRequiredDescription
new_statusstringYes"Approved", "Declined", or "In Review"
commentstringNoReview note

Response (201): The created review item.


Blocklist

Block entities from a session to auto-decline future matches.

1. Add to Blocklist

POST /v3/blocklist/add/
BodyTypeRequiredDescription
session_iduuidYesSession to blocklist items from
blocklist_facebooleanNoBlock biometric face template
blocklist_documentbooleanNoBlock document fingerprint
blocklist_phonebooleanNoBlock phone number
blocklist_emailbooleanNoBlock email address

Warning tags on match: FACE_IN_BLOCKLIST, ID_DOCUMENT_IN_BLOCKLIST, PHONE_NUMBER_IN_BLOCKLIST, EMAIL_IN_BLOCKLIST

2. Remove from Blocklist

POST /v3/blocklist/remove/

Same structure with unblock_face, unblock_document, unblock_phone, unblock_email.

3. List Blocklist

GET /v3/blocklist/
QueryTypeDescription
item_typestring"face", "document", "phone", "email". Omit for all.

Questionnaires

Custom forms attached to verification workflows. Support 7 element types: short_text, long_text, multiple_choice, checkbox, file_upload, date, number.

1. List Questionnaires

GET /v3/questionnaires/

2. Create Questionnaire

POST /v3/questionnaires/
BodyTypeRequiredDescription
titlestringYesDisplay title
descriptionstringNoDescription shown to users
default_languagestringNoDefault language code
languagesarrayNoSupported languages
form_elementsarrayYesQuestion objects

Form element:

FieldTypeRequiredDescription
element_typestringYesOne of the 7 types above
labelobjectYesTranslations: {"en": "Question?", "es": "¿Pregunta?"}
is_requiredbooleanNoMandatory answer
optionsarrayConditionalRequired for multiple_choice/checkbox
requests.post("https://verification.didit.me/v3/questionnaires/",
    headers=headers,
    json={
        "title": "Employment Details",
        "default_language": "en",
        "form_elements": [
            {"element_type": "short_text",
             "label": {"en": "Occupation?"}, "is_required": True},
            {"element_type": "multiple_choice",
             "label": {"en": "Employment status"},
             "options": [{"label": {"en": "Employed"}}, {"label": {"en": "Student"}}]},
        ]
    })

3. Get Questionnaire

GET /v3/questionnaires/{questionnaire_uuid}/

4. Update Questionnaire

PATCH /v3/questionnaires/{questionnaire_uuid}/

5. Delete Questionnaire

DELETE /v3/questionnaires/{questionnaire_uuid}/

Response: 204 No Content.


Users

Manage verified individuals identified by vendor_data.

1. List Users

GET /v3/users/
QueryTypeDescription
statusstringApproved, Declined, In Review, Pending
searchstringSearch by name or identifier
countrystringISO 3166-1 alpha-3
limitintegerResults per page (max 200)
offsetintegerPagination offset

Response (200): Paginated list with vendor_data, full_name, status, session_count, issuing_states, approved_emails, approved_phones.

2. Get User

GET /v3/users/{vendor_data}/

3. Update User

PATCH /v3/users/{vendor_data}/
BodyTypeDescription
display_namestringCustom display name
statusstringManual override: Approved, Declined, In Review
metadataobjectCustom JSON metadata

4. Batch Delete Users

POST /v3/users/delete/
BodyTypeDescription
vendor_data_listarrayList of vendor_data strings
delete_allbooleanDelete all users

Billing

1. Get Credit Balance

GET /v3/billing/balance/

Response (200):

{
  "balance": "142.5000",
  "auto_refill_enabled": true,
  "auto_refill_amount": "100.0000",
  "auto_refill_threshold": "10.0000"
}

2. Top Up Credits

POST /v3/billing/top-up/
BodyTypeRequiredDescription
amount_in_dollarsnumberYesMinimum $50
success_urlstringNoRedirect after payment
cancel_urlstringNoRedirect on cancel

Response (200):

{
  "checkout_session_id": "cs_live_...",
  "checkout_session_url": "https://checkout.stripe.com/..."
}

Present checkout_session_url to the user for payment.


Webhook Configuration

Set up webhooks programmatically — no console needed.

1. Get Webhook Configuration

GET /v3/webhook/

Response (200):

{
  "webhook_url": "https://myapp.com/webhooks/didit",
  "webhook_version": "v3",
  "secret_shared_key": "whsec_a1b2c3d4e5f6g7h8i9j0...",
  "capture_method": "both",
  "data_retention_months": null
}
FieldTypeDescription
webhook_urlstring/nullURL where notifications are sent (null if not configured)
webhook_versionstring"v1", "v2", or "v3" (v3 recommended)
secret_shared_keystringHMAC secret for verifying webhook signatures
capture_methodstring"mobile", "desktop", or "both"
data_retention_monthsinteger/nullMonths to retain session data (null = unlimited)

2. Update Webhook Configuration

PATCH /v3/webhook/
BodyTypeRequiredDescription
webhook_urlstring/nullNoURL for notifications (set null to disable)
webhook_versionstringNo"v1", "v2", or "v3"
rotate_secret_keybooleanNotrue to generate a new secret (old one immediately invalidated)
capture_methodstringNo"mobile", "desktop", or "both"
data_retention_monthsinteger/nullNo1–120 months, or null for unlimited

Example — set webhook URL:

requests.patch(
    "https://verification.didit.me/v3/webhook/",
    headers={"x-api-key": API_KEY, "Content-Type": "application/json"},
    json={"webhook_url": "https://myapp.com/webhooks/didit", "webhook_version": "v3"},
)

Example — rotate secret:

r = requests.patch(
    "https://verification.didit.me/v3/webhook/",
    headers={"x-api-key": API_KEY, "Content-Type": "application/json"},
    json={"rotate_secret_key": True},
)
new_secret = r.json()["secret_shared_key"]

Example — disable webhooks:

requests.patch(
    "https://verification.didit.me/v3/webhook/",
    headers={"x-api-key": API_KEY, "Content-Type": "application/json"},
    json={"webhook_url": None},
)

Response (200): Same shape as GET — returns the updated configuration.


Webhook Events & Signatures

Didit sends POST requests to your webhook URL when session status changes. Retries up to 2 times with exponential backoff (1 min, 4 min).

Payload

{
  "session_id": "...",
  "status": "Approved",
  "webhook_type": "status.updated",
  "vendor_data": "user-123",
  "timestamp": 1627680000,
  "decision": { ... }
}

Event types: status.updated (status change), data.updated (KYC/POA data manually updated).

Signature Verification (V2 — recommended)

Two headers: X-Signature-V2 (HMAC-SHA256 hex) and X-Timestamp (Unix seconds).

import hashlib, hmac, time, json

def verify_webhook_v2(body_dict: dict, signature: str, timestamp: str, secret: str) -> bool:
    if abs(time.time() - int(timestamp)) > 300:
        return False
    def process_value(v):
        if isinstance(v, float) and v == int(v):
            return int(v)
        if isinstance(v, dict):
            return {k: process_value(val) for k, val in v.items()}
        if isinstance(v, list):
            return [process_value(i) for i in v]
        return v
    canonical = json.dumps(process_value(body_dict), sort_keys=True, ensure_ascii=False, separators=(",", ":"))
    message = f"{timestamp}:{canonical}"
    expected = hmac.new(secret.encode(), message.encode(), hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature)

Simple Signature (Fallback)

Header: X-Signature-Simple — HMAC of key fields only.

def verify_webhook_simple(session_id, status, webhook_type, timestamp, signature, secret):
    message = f"{timestamp}:{session_id}:{status}:{webhook_type}"
    expected = hmac.new(secret.encode(), message.encode(), hashlib.sha256).hexdigest()
    return hmac.compare_digest(signature, expected)

Error Responses (All Endpoints)

CodeMeaningAction
400Invalid requestCheck required fields and formats
401Invalid or missing API keyVerify x-api-key header
403Insufficient credits or no permissionCheck balance, API key permissions
404Resource not foundVerify IDs
429Rate limitedCheck Retry-After header, exponential backoff

Common Workflows

Full KYC Onboarding

1. POST /programmatic/register/      → register
2. POST /programmatic/verify-email/  → get api_key
3. POST /v3/workflows/               → create KYC workflow
4. PATCH /v3/webhook/                → set webhook_url + webhook_version "v3"
5. POST /v3/session/                 → create session → get URL
6. User completes verification at URL
7. Webhook fires → GET /v3/session/{id}/decision/ → read results

Programmatic Review + Blocklist

1. Webhook: status "In Review"
2. GET /v3/session/{id}/decision/   → inspect results
3. If fraud: PATCH update-status → Declined + POST /v3/blocklist/add/
   If legit: PATCH update-status → Approved

B2B KYC Sharing

Service A: POST /v3/session/{id}/share/       → get share_token
Service B: POST /v3/session/import-shared/    → import with trust_review=true

Check Balance Before Sessions

1. GET /v3/billing/balance/    → check if balance > 0
2. If low: POST /v3/billing/top-up/ → get Stripe checkout URL
3. POST /v3/session/           → create session

Questionnaire + Workflow

1. POST /v3/questionnaires/  → create form → save uuid
2. POST /v3/workflows/       → questionnaire_verification type
3. POST /v3/session/         → session with workflow_id

Utility Scripts

setup_account.py — Register and verify accounts

pip install requests
python scripts/setup_account.py register you@gmail.com 'MyStr0ng!Pass'
# (check email for code)
python scripts/setup_account.py verify you@gmail.com A3K9F2
# Prints api_key, org_uuid, app_uuid
python scripts/setup_account.py login you@gmail.com 'MyStr0ng!Pass'

manage_workflows.py — CRUD workflows

export DIDIT_API_KEY="your_key"
python scripts/manage_workflows.py list
python scripts/manage_workflows.py create --label "My KYC" --type kyc --liveness --face-match
python scripts/manage_workflows.py get <uuid>
python scripts/manage_workflows.py update <uuid> --enable-aml --aml-threshold 75
python scripts/manage_workflows.py delete <uuid>

create_session.py — Create verification sessions

export DIDIT_API_KEY="your_key"
python scripts/create_session.py --workflow-id <uuid> --vendor-data user-123
python scripts/create_session.py --workflow-id <uuid> --vendor-data user-123 --callback https://myapp.com/done

All scripts can be imported as libraries:

from scripts.setup_account import register, verify_email, login
from scripts.manage_workflows import list_workflows, create_workflow
from scripts.create_session import create_session

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

Cypress Agent Skill

Production-grade Cypress E2E and component testing — selectors, network stubbing, auth, CI parallelization, flake elimination, Page Object Model, and TypeScr...

Registry SourceRecently Updated
Automation

Ichiro-Mind

Ichiro-Mind: The ultimate unified memory system for AI agents. 4-layer architecture (HOT→WARM→COLD→ARCHIVE) with neural graph, vector search, experience lear...

Registry SourceRecently Updated
1128
hudul
Automation

Reddit Engagement

Create and execute robust Reddit engagement workflows (create post, add comment, upvote) using browser accessibility-tree semantics instead of brittle DOM id...

Registry SourceRecently Updated