didit-protocol/skills

didit-kyc-onboarding

End-to-end KYC (Know Your Customer) identity verification for onboarding real users. Use when someone needs to perform KYC, onboard users with identity verification, verify a person's identity with ID scan and selfie, run a full KYC flow, create a verification session for a user, set up ID + liveness + face match verification, or implement user onboarding with document and biometric checks. Creates a KYC workflow, generates a verification URL, and retrieves the decision.

First seen Mar 11, 2026

Installation

$ npx skills add didit-protocol/skills --skill didit-kyc-onboarding

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from didit-protocol/skills · top by installs.

npx skills add didit-protocol/skills

Browse all from didit-protocol/skills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 26
License LICENSE
Default branch main
Open issues 0
Status Active

Skill metadata

Parsed from SKILL.md frontmatter.

Version1.1.0
Declared agents clawdbot
More metadata
openclaw
{"requires":{"env":["DIDIT_API_KEY"]},"primaryEnv":"DIDIT_API_KEY","emoji":"\"�"}

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 12,272 B
  • docs SUMMARY.md 503 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 236 installs

SKILL.md

Running KYC with Didit

End-to-end Know Your Customer (KYC) verification. This skill creates a KYC workflow, generates a session URL where a real user completes ID scan + selfie + face match, and retrieves the verification decision.

What the user experiences:

  1. Receives a verification link
  2. Scans their ID document (passport, ID card, driver's license)
  3. Takes a live selfie
  4. System auto-matches selfie to document photo
  5. Gets approved, declined, or flagged for review

API Reference:


Authentication

All requests require x-api-key header. Get your key from Didit Business Console → API & Webhooks, or via programmatic registration (see below).

Getting Started (No Account Yet?)

If you don't have a Didit API key, create one in 2 API calls:

  1. Register: POST https://apx.didit.me/auth/v2/programmatic/register/ with {"email": "[email protected]", "password": "MyStr0ng!Pass"}
  2. Check email for a 6-character OTP code
  3. Verify: POST https://apx.didit.me/auth/v2/programmatic/verify-email/ with {"email": "[email protected]", "code": "A3K9F2"} → response includes api_key

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

See the didit-verification-management skill for full platform management (workflows, sessions, users, billing).


Quick Start — KYC in 3 API Calls

import requests, time

API_KEY = "your_api_key"
headers = {"x-api-key": API_KEY, "Content-Type": "application/json"}
BASE = "https://verification.didit.me/v3"

# 1. Create a KYC workflow (one-time setup — reuse the workflow_id for all users)
workflow = requests.post(f"{BASE}/workflows/", headers=headers, json={
    "workflow_label": "KYC Onboarding",
    "max_retry_attempts": 3,
    "features": [
        {"feature": "OCR"},
        {"feature": "LIVENESS", "config": {"face_liveness_method": "PASSIVE"}},
        {"feature": "FACE_MATCH", "config": {"face_match_score_decline_threshold": 50}},
    ],
}).json()
workflow_id = workflow["uuid"]

# 2. Create a session for a specific user
session = requests.post(f"{BASE}/session/", headers=headers, json={
    "workflow_id": workflow_id,
    "vendor_data": "user-abc-123",
    "callback": "https://yourapp.com/verification-done",
    "language": "en",
}).json()

print(f"Send user to: {session['url']}")
# User opens this URL → scans ID → takes selfie → done

# 3. Poll for the decision (or use webhooks)
while True:
    decision = requests.get(
        f"{BASE}/session/{session['session_id']}/decision/",
        headers={"x-api-key": API_KEY},
    ).json()
    status = decision["status"]
    if status in ("Approved", "Declined", "In Review"):
        break
    time.sleep(10)

print(f"Result: {status}")
if status == "Approved":
    id_data = decision["id_verifications"][0]
    print(f"Name: {id_data['first_name']} {id_data['last_name']}")
    print(f"DOB: {id_data['date_of_birth']}")
    print(f"Document: {id_data['document_type']} ({id_data['issuing_country']})")

Step 1: Create a KYC Workflow

A workflow defines what checks run. Create one per use case and reuse it for all users.

POST https://verification.didit.me/v3/workflows/

API Reference: https://docs.didit.me/management-api/workflows/create

Recommended KYC Configuration

The workflow body uses a features array (run in order). Put OCR first so downstream features can use the document data.

Field Value Why
workflow_label "KYC Onboarding" Display name (max 50 chars)
features[].feature "OCR", "LIVENESS", "FACE_MATCH" Full KYC: ID + selfie + match
LIVENESSconfig.facelivenessmethod "PASSIVE" Anti-spoofing method (uppercase)
FACEMATCHconfig.facematchscoredecline_threshold 50 Match below 50% → auto-decline
(add) {"feature": "AML"} Sanctions/PEP screening (+cost)
maxretryattempts 3 User can retry 3 times on failure

Response

{
  "uuid": "d8d2fa2d-c69c-471c-b7bc-bc71512b43ef",
  "workflow_label": "KYC Onboarding",
  "features": ["ocr", "liveness", "face_match"],
  "total_price": "0.10",
  "workflow_url": "https://verify.didit.me/..."
}

Save uuid as your workflow_id.


Step 2: Create a Session for Each User

Each user gets their own session. The session generates a unique URL where they complete verification.

POST https://verification.didit.me/v3/session/

API Reference: https://docs.didit.me/sessions-api/create-session

Key Parameters

Parameter Type Required Description
workflow_id uuid Yes From Step 1
vendor_data string Recommended Your user ID — links the session to your system
callback url Recommended Redirect URL after verification. Didit appends ?verificationSessionId=...&status=...
language string No UI language (ISO 639-1). Auto-detected if omitted
contact_details.email string No Pre-fill email for notification
expecteddetails.firstname string No Triggers mismatch warning if document name differs
expecteddetails.dateof_birth string No YYYY-MM-DD format
metadata JSON string No Custom data stored with session

Response

{
  "session_id": "11111111-2222-3333-4444-555555555555",
  "session_token": "abcdef123456",
  "url": "https://verify.didit.me/session/abcdef123456",
  "status": "Not Started",
  "workflow_id": "d8d2fa2d-..."
}

Send the user to url — this is where they complete verification (web or mobile).


Step 3: Get the Decision

After the user completes verification, retrieve the results.

GET https://verification.didit.me/v3/session/{sessionId}/decision/

API Reference: https://docs.didit.me/sessions-api/retrieve-session

Two Ways to Know When It's Ready

Option A: Webhooks (recommended for production) Configure a webhook URL in Business Console → API & Webhooks. Didit sends a POST with session_id and status when the decision is ready.

Option B: Polling Poll GET /v3/session/{id}/decision/ every 10–30 seconds. Check status — stop when it's Approved, Declined, or In Review.

Decision Response Fields

{
  "session_id": "...",
  "status": "Approved",
  "features": ["ID_VERIFICATION", "LIVENESS", "FACE_MATCH"],
  "id_verifications": [{
    "status": "Approved",
    "document_type": "PASSPORT",
    "issuing_country": "USA",
    "first_name": "John",
    "last_name": "Doe",
    "date_of_birth": "1990-01-15",
    "document_number": "ABC123456",
    "expiry_date": "2030-06-01",
    "gender": "M",
    "nationality": "USA",
    "mrz": "P<USADOE<<JOHN<<<<<<<<<..."
  }],
  "liveness_checks": [{
    "status": "Approved",
    "method": "PASSIVE",
    "score": 92.5
  }],
  "face_matches": [{
    "status": "Approved",
    "score": 97.3
  }],
  "aml_screenings": [],
  "warnings": []
}

Key Decision Statuses

Status Meaning Action
Approved All checks passed User is verified
Declined One or more checks failed Check warnings for details
In Review Borderline result Manual review needed, or auto-decide via API
Not Started User hasn't opened the link yet Wait or remind user
In Progress User is completing verification Wait
Expired Session expired (default: 7 days) Create a new session

Optional: Post-Decision Actions

Approve or Decline Manually

PATCH https://verification.didit.me/v3/session/{sessionId}/update-status/

API Reference: https://docs.didit.me/sessions-api/update-status

requests.patch(f"{BASE}/session/{session_id}/update-status/",
    headers=headers,
    json={"new_status": "Approved", "comment": "Manual review passed"})

Request Resubmission

If the ID photo was blurry, ask the user to redo just that step:

requests.patch(f"{BASE}/session/{session_id}/update-status/",
    headers=headers,
    json={
        "new_status": "Resubmitted",
        "nodes_to_resubmit": [{"node_id": "feature_ocr", "feature": "OCR"}],
        "send_email": True,
        "email_address": "[email protected]",
    })

Block Fraudulent Users

Add an entry to a system blocklist via the Lists API. Reference the session to auto-extract and block the underlying face/document/phone/email:

# Find the face blocklist (auto-provisioned), then add the session's face/document
lists = requests.get(f"{BASE}/lists/", headers=headers,
                     params={"list_type": "blocklist", "entry_type": "face"}).json()
list_uuid = lists["results"][0]["uuid"]
requests.post(f"{BASE}/lists/{list_uuid}/entries/",
    headers=headers,
    json={"reference_session_id": session_id})

API Reference: https://docs.didit.me/management-api/lists/create-entry

Generate PDF Report

response = requests.get(f"{BASE}/session/{session_id}/generate-pdf",
    headers={"x-api-key": API_KEY})

API Reference: https://docs.didit.me/sessions-api/generate-pdf


KYC Workflow Variants

KYC + AML Screening

Add sanctions/PEP screening to catch high-risk individuals:

requests.post(f"{BASE}/workflows/", headers=headers, json={
    "workflow_label": "KYC + AML",
    "features": [
        {"feature": "OCR"},
        {"feature": "LIVENESS", "config": {"face_liveness_method": "PASSIVE"}},
        {"feature": "FACE_MATCH"},
        {"feature": "AML"},
    ],
})

KYC + Phone + Email

Add contact verification to the flow:

requests.post(f"{BASE}/workflows/", headers=headers, json={
    "workflow_label": "KYC + Contact",
    "features": [
        {"feature": "OCR"},
        {"feature": "LIVENESS", "config": {"face_liveness_method": "PASSIVE"}},
        {"feature": "FACE_MATCH"},
        {"feature": "PHONE_VERIFICATION"},
        {"feature": "EMAIL_VERIFICATION"},
    ],
})

KYC + NFC (Chip Reading)

For passports with NFC chips — highest assurance:

requests.post(f"{BASE}/workflows/", headers=headers, json={
    "workflow_label": "KYC + NFC",
    "features": [
        {"feature": "OCR"},
        {"feature": "NFC"},
        {"feature": "LIVENESS", "config": {"face_liveness_method": "PASSIVE"}},
        {"feature": "FACE_MATCH"},
    ],
})

Utility Scripts

run_kyc.py — Full KYC setup from the command line

# Requires: pip install requests
export DIDIT_API_KEY="your_api_key"

# Create a KYC workflow (one-time)
python scripts/run_kyc.py setup --label "My KYC" --liveness --face-match

# Create a session for a user
python scripts/run_kyc.py session --workflow-id <uuid> --vendor-data user-123

# Get the decision
python scripts/run_kyc.py decision <session_id>

# Full flow: create workflow + session in one command
python scripts/run_kyc.py full --vendor-data user-123 --callback https://myapp.com/done

Can also be imported:

from scripts.run_kyc import setup_kyc_workflow, create_kyc_session, get_decision