关于 didit-verification-management
面向需设置身份验证并管理 Didit 平台的团队,涵盖工作流、会话、用户、账单及相关设置。内容从账户配置延伸到 Webhook 管理,并指向处理单项检查和专项任务的其他技能。
主要功能
- 01账户与应用配置
- 02工作流和会话管理
- 03KYC 用户与 KYB 企业管理
- 04问卷、名单与批量导入
- 05账单、品牌设置与 Webhook
适用场景
- 01创建 Didit 账户和应用
- 02配置验证工作流与会话
- 03管理 KYC 和 KYB 记录
- 04维护 Webhook 目标和账单
MCP 相关
该技能指向 `didit-mcp-server`,用于通过 MCP 客户端使用 Didit。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ didit-protocol/ skills --skill didit-verification-management安装后在 Claude Code 中输入/didit-verification-management确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
scripts/create_session.pymanage_workflows.pysetup_account.py详细介绍
Didit 身份验证平台
概述
Didit 平台的核心技能:账户和应用设置、工作流、会话、批量导入、问卷、名单、用户(KYC)、企业(KYB)、账单、品牌和 Webhook。
相关技能:
| 需求 | 技能 |
|---|---|
| 单项独立检查(证件扫描、活体检测、人脸匹配、AML、地址证明、电子邮件、电话、数据库验证、年龄、人脸搜索) | didit-id-document-verification、didit-liveness-detection、didit-face-match、didit-aml-screening、didit-proof-of-address、didit-email-verification、didit-phone-verification、didit-database-validation、didit-biometric-age-estimation、didit-face-search |
| 端到端 KYC 入驻流程 | didit-kyc-onboarding |
| 创建交易、Travel Rule、钱包筛查、交易规则 | didit-transaction-monitoring |
| 发送用户事件(登录、账户变更)以供监控 | didit-event-monitoring |
| 案例、案例蓝图、监管报告 | didit-case-management |
| 欺诈网络(关联用户、设备、证件) | didit-fraud-networks |
| 欺诈检查 | didit-fraud-check |
| 自定义文档提取(Document AI) | didit-document-ai |
| Web 和移动 SDK、SDK 令牌 | didit-sdk-integration |
| 从 MCP 客户端使用 Didit | didit-mcp-server |
**定价:**一次会话的费用为其工作流运行的各项功能费用之和,且只对已完成的功能收费(即工作流的 total_price,不含 DATABASE_VALIDATION 和 PHONE_VERIFICATION 等按量定价的功能);每个组织每月可免费使用 500 次核心 KYC 功能检查(证件采集、被动活体检测、人脸匹配、设备和 IP 分析)。管理端点本身没有公开标价。在 2026 年 11 月 1 日 Didit 调整定价之前,这些是标价;届时每月 500 次免费检查将改为每月 10 美元的免费额度。请查看 didit.me/pricing 了解当前价格。
基础 URL:https://verification.didit.me/v3(所有接口均使用 x-api-key)、https://apx.didit.me/auth/v2(账户设置)。
API 参考链接:
- 账户设置: 注册 | 验证邮箱 | 登录 | 获取凭据 | 创建应用 | 更新应用
- 会话: 创建 | 检索 | 列出 | 删除 | 更新状态 | 预览重新提交 | 更新功能状态 | 更新 AML 命中状态 | 更新数据 | PDF | 分享 | 导入
- 会话操作: 批量删除 | 删除任务 | 列出审核记录 | 创建审核记录
- 工作流: 创建 | 列出 | 获取 | 更新 | 删除 | 功能配置
- 问卷: 创建 | 列出 | 获取 | 更新 | 删除
- 用户(KYC): 列出 | 创建 | 获取 | 更新 | 更新状态 | 删除 | PDF | 上传人脸
- 企业(KYB): 列出 | 创建 | 获取 | 更新 | 更新状态 | 删除 | KYB 注册信息
- AML 监控: 切换用户监控 | 切换企业监控 | 获取任务
- 生物识别模板: 概览 | 列出 | 计数 | 获取 | 清除 | 批量清除
- 交易: 列出 | 创建 | 获取
- 账单: 余额 | 充值
- 自定义: 获取 | 更新
- 列表(阻止/允许/自定义): 概览 | 列出 | 创建 | 获取 | 更新 | 删除 | 条目 | 添加条目 | 上传人脸 | 删除条目
- 批量导入: 导入验证记录
- Webhook 目标: 列出 | 创建 | 获取 | 更新 | 删除
- 指南: 程序化注册 | API 密钥 | Webhooks | 速率限制 | 验证状态 | 沙盒测试 | MCP 服务 | API 概览
身份验证
| 端点 | 身份验证 | 请求头 |
|---|---|---|
| 注册、验证邮箱、重新发送验证码、登录 | 无 | (未经身份验证) |
组织和应用(/organizations/me/...) | Bearer | Authorization: Bearer <access_token>(来自邮箱验证或登录) |
verification.didit.me/v3 上的所有接口 | API 密钥 | x-api-key: <api_key> |
向 verification.didit.me 发送的每个请求都需要 x-api-key 请求头。请在 Didit Business Console 的 Developers > API keys 中使用应用的 API 密钥,或以编程方式创建账户和密钥(参见入门指南)。具有自定义访问权限的命名密钥,必须对各章节使用的资源(Sessions、Decisions、Media、Users、Businesses、Transactions、Workflows、Webhooks、Application settings)具有读取或写入权限;仅限部分工作流或仅限已批准会话的密钥,只能用于会话端点。
API 密钥
| 主题 | 行为 |
|---|---|
| 主密钥 | 每个应用都有一个具有完整访问权限的主密钥。该密钥无法编辑或撤销,只能轮换。邮箱验证时返回的 application.api_key 就是此密钥。 |
| 命名密钥 | 每个服务或合作伙伴可创建一个。只能在控制台中创建、编辑、轮换和撤销(无 API)。有效期可设为永不过期、30 天、90 天、一年或指定日期(于该日期结束,UTC)。 |
| 访问权限 | 每项资源可设为无、读取或写入权限。读取权限涵盖 GET;写入权限涵盖 POST、PUT、PATCH、DELETE。资源包括:Sessions(写入权限还可运行独立检查和导入)、Decisions(写入权限:批准、拒绝、审核,以及设置功能和 AML 命中状态)、Media(仅读取)、Users、Businesses、Transactions、Workflows(也包括问卷和列表)、Webhooks、Application settings(自定义设置、余额、充值)、Analytics(仅读取)。 |
| 限制 | Workflows:只能查看所选工作流的会话,也只能创建这类会话;其他会话会返回 404。仅限已批准的会话:已拒绝、审核中和未完成的会话会被隐藏。受任一限制的密钥都无法访问用户、企业、交易或分析数据,也无法运行独立检查。 |
| IP 允许列表 | 最多可添加 20 个 IPv4/IPv6 地址或 CIDR 网段;来自其他地址的请求会返回 403。 |
| 轮换 | 新密钥仅显示一次;旧密钥在 24 小时内仍有效。 |
| 精简输出 | 如果没有 Media 读取权限,决策中的每个图像、视频和 PDF URL 都会是 null,PDF 端点会返回 403。如果没有 Sessions 写入权限,会话 URL 和 session_token 都会返回 null。 |
| 状态码 | 401 密钥已过期;403 密钥缺失、错误或已撤销、无权访问资源,或请求来源 IP 不在允许列表中;404 会话超出密钥的限制范围。 |
入门指南(还没有账户?)
如果你还没有 Didit API 密钥,只需调用 2 次 API 即可创建:
- 注册: 使用
{"email": "[email protected]", "password": "MyStr0ng!Pass"}调用POST https://apx.didit.me/auth/v2/programmatic/register/ - 查看邮箱,获取 6 位验证码
- 验证: 使用
{"email": "[email protected]", "code": "A3K9F2"}调用POST https://apx.didit.me/auth/v2/programmatic/verify-email/。密钥位于响应中的application.api_key。
添加额度: 调用 GET /v3/billing/balance/ 查看余额;调用 POST /v3/billing/top-up/ 并传入 {"amount_in_dollars": 50},获取 Stripe 结账链接。
只需调用 4 次即可生成可用的验证链接:
import requests
AUTH = "https://apx.didit.me/auth/v2"
API = "https://verification.didit.me/v3"
# 1. Register: emails a 6-character code (valid 10 minutes)
requests.post(f"{AUTH}/programmatic/register/",
json={"email": "[email protected]", "password": "MyStr0ng!Pass"}).raise_for_status()
# 2. Verify the code: the response carries the application's API key
resp = requests.post(f"{AUTH}/programmatic/verify-email/",
json={"email": "[email protected]", "code": "A3K9F2"})
resp.raise_for_status()
headers = {"x-api-key": resp.json()["application"]["api_key"]}
# 3. Create a KYC workflow from an ordered `features` array
wf = requests.post(f"{API}/workflows/", headers=headers, json={
"workflow_label": "My KYC",
"features": [
{"feature": "OCR"},
{"feature": "LIVENESS", "config": {"face_liveness_method": "PASSIVE"}},
{"feature": "FACE_MATCH"},
],
}).json()
# 4. Create a session and send the user to its URL
session = requests.post(f"{API}/session/", headers=headers,
json={"workflow_id": wf["uuid"], "vendor_data": "user-123"}).json()
print("Send the user to:", session["url"])
账户设置
基础 URL: https://apx.didit.me/auth/v2
| 步骤 | 端点 | 请求正文 | 成功响应 |
|---|---|---|---|
| 1. 注册 | POST /programmatic/register/ | email、password | 201 {"message", "email"}。如果邮箱尚未验证,重新注册会返回 200 "A new verification code has been sent to your email." |
| 2. 验证邮箱 | POST /programmatic/verify-email/ | email、code(6 个字符) | 200 {access_token, refresh_token, expires_in, organization{uuid, name}, application{uuid, name, client_id, api_key}} |
| 重新发送验证码 | POST /programmatic/resend-otp/ | email、password | 200。凭据错误或邮箱已验证时返回 400。 |
| 3. 登录 | POST /programmatic/login/ | email、password | 200 {access_token, refresh_token, expires_in, message} |
| 4. 列出组织 | GET /organizations/me/(Bearer) | - | 200 分页结果 {count, next, previous, results[]};每条结果包含 uuid、name、contact_email、created_at |
| 5. 列出应用 | GET /organizations/me/{org_id}/applications/(Bearer) | - | 200 分页的应用记录列表 |
| 创建应用 | POST /organizations/me/{org_id}/applications/(Bearer) | 可选:name、website_url、redirect_uris、terms_url、privacy_url、description | 201 应用记录,包含其专属的 api_key(默认名称为 "<organization name> App") |
| 6. 获取凭据 | GET /organizations/me/{org_id}/applications/{app_id}/(Bearer) | - | 200 {uuid, name, client_id, api_key, website_url, redirect_uris, terms_url, privacy_url, description, created_at} |
| 更新应用 | PATCH /organizations/me/{org_id}/applications/{app_id}/(Bearer) | 创建时所用字段中的任意字段 | 200 完整记录;uuid、client_id 和 api_key 不会更改 |
| 规则 | 值 |
|---|---|
| 密码 | 至少 8 个字符,且包含大写字母、小写字母、数字和特殊字符 |
| 验证码 | 6 个字母数字字符,在最近一次发送后 10 分钟过期;每个邮箱每小时最多尝试 10 次,失败后等待时间逐渐增加 |
| 注册 / 重新发送 | 每个 IP 每小时 5 次(共用额度);每个邮箱重新发送还需等待 60 秒 |
| 登录 | 连续失败 5 次后锁定账户 15 分钟,10 次后锁定 1 小时,20 次后锁定 24 小时;每个 IP 每分钟最多 20 次、每小时最多 100 次。组织强制使用 SSO 时返回 403。 |
| 访问令牌 | expires_in 为 86400(24 小时);通过 Authorization: Bearer 发送,切勿发送至 verification.didit.me |
| 应用 | 只有组织所有者和管理员可以创建、读取或更新应用(否则返回 403);无法查看的组织或应用返回 404 |
| 错误 | 429 响应包含 Retry-After 标头 |
找回遗失的 API 密钥: 登录,调用 GET /organizations/me/ 和 GET /organizations/me/{org_id}/applications/,然后从应用记录中读取 api_key。
工作流
基础 URL: https://verification.didit.me/v3
工作流是会话运行的检查项列表,按顺序排列。每个版本都有一个 uuid(创建会话时将其作为 workflow_id 传入,在此处将其作为 {settings_uuid} 传入),并有一个供同一工作流所有版本共享的 workflow_id(第 1 版中,它与 uuid 相同)。新会话使用最新的 published 版本。创建时没有 workflow_type 字段:KYC 还是 KYB 由功能决定。
| 方法 | 路径 | 备注 |
|---|---|---|
GET | /v3/workflows/ | 分页格式为 {count, next, previous, results[]},按最新优先;limit(默认值为 50)、offset |
POST | /v3/workflows/ | 返回包含完整配置的 201。不具备幂等性。每个应用最多可创建 50 个工作流。 |
GET | /v3/workflows/{settings_uuid}/ | 单个版本的完整配置(功能开关、阈值、documents_allowed、workflow_graph、重试策略、价格) |
PATCH | /v3/workflows/{settings_uuid}/ | 允许的字段与创建时相同;返回包含生成版本的 200(见下文版本管理) |
DELETE | /v3/workflows/{settings_uuid}/ | 204。仅删除该版本(其他版本保留)。会话保留其结果;其中的工作流引用会变为 null。 |
列表行字段: uuid、workflow_id、version、status(draft/published)、has_draft、workflow_label、workflow_type(图工作流为 null)、is_default、is_archived、is_white_label_enabled、features(以 " + " 连接的单个字符串,例如 "OCR + LIVENESS + FACE_MATCH")、total_price、min_price、max_price、is_simple_workflow、is_editable、workflow_url、max_retry_attempts、retry_window_days、session_expiration_time、created_by、updated_at。
创建请求体(严格白名单:任何其他键,包括 workflow_type 或扁平的 is_*_enabled 标志,都会返回 400)
| 请求体 | 类型 | 默认值 | 说明 |
|---|---|---|---|
features | 数组 | - | 必填,至少 1 项。条目格式为 {"feature": "<UPPERCASE>", "config": {...}, "label": "optional"},按执行顺序排列 |
workflow_label | 字符串 | ID Verification | 最多 50 个字符;务必设置 |
status | 字符串 | published | 不传则发布;设为 "draft" 则保存但不发布 |
is_default | 布尔值 | - | 新会话的默认工作流 |
is_white_label_enabled | 布尔值 | false | 应用白标品牌 |
is_desktop_allowed | 布尔值 | false | 允许在桌面浏览器中使用此流程 |
max_retry_attempts | 整数 | 3 | 拒绝后可重试 0-10 次(0 表示首次拒绝后即阻止) |
retry_window_days | 整数或 null | 7 | 1-365;null = 不限时间 |
face_liveness_max_attempts | 整数 | 3 | 每个会话可提交 1-3 次活体检测 |
face_match_max_attempts | 整数 | 3 | 每个会话可提交 1-3 次人脸匹配 |
session_expiration_time | 整数 | 604800 | 未完成的会话过期前的秒数:3600 至 2419200 |
功能值: OCR、NFC、LIVENESS、FACE_MATCH、PROOF_OF_ADDRESS、QUESTIONNAIRE、DOCUMENT_AI、PHONE_VERIFICATION、EMAIL_VERIFICATION、DATABASE_VALIDATION、AML、IP_ANALYSIS、AGE_ESTIMATION、KYB_REGISTRY、KYB_DOCUMENTS、KYB_KEY_PEOPLE。
| 目标 | 功能(按顺序) |
|---|---|
| 完整 KYC(身份证件 + 自拍) | OCR、LIVENESS、FACE_MATCH,可选 NFC、AML、IP_ANALYSIS |
| 年龄门禁 | AGE_ESTIMATION(自身会运行活体检测;config.enable_id_verification_fallback 会将年龄处于临界范围的用户转入证件验证) |
| 地址证明 | PROOF_OF_ADDRESS |
| 问卷 | QUESTIONNAIRE,并设置 config.questionnaire_uuid |
| 自定义证件 | DOCUMENT_AI(参见 didit-document-ai 技能) |
| 仅电子邮件 / 电话 | EMAIL_VERIFICATION / PHONE_VERIFICATION |
| KYB(企业) | KYB_REGISTRY、KYB_DOCUMENTS、KYB_KEY_PEOPLE,可选 AML |
排序和组合规则(否则返回 400): |
IP_ANALYSIS、AML、DATABASE_VALIDATION和KYB_KEY_PEOPLE不能作为第一个特征。FACE_MATCH和NFC必须放在OCR之后;DATABASE_VALIDATION和个人AML也应放在OCR之后(或在 KYB 中将AML放在KYB_REGISTRY之后)。KYB_DOCUMENTS和KYB_KEY_PEOPLE必须放在KYB_REGISTRY之后。- KYB 特征只能与
AML、DOCUMENT_AI、QUESTIONNAIRE、PHONE_VERIFICATION、EMAIL_VERIFICATION、IP_ANALYSIS组合;不能与个人特征(OCR、LIVENESS、FACE_MATCH、NFC、PROOF_OF_ADDRESS、DATABASE_VALIDATION、AGE_ESTIMATION)组合。 QUESTIONNAIRE需要config.questionnaire_uuid(此应用的问卷);KYB_DOCUMENTS需要config.kyb_required_document_groups,且其中至少包含一个组。
各特征通用的 config 键(完整列表见特征配置;分数和阈值范围为 0–100;操作值为大写的 DECLINE、REVIEW、NO_ACTION):
| 特征 | 键 |
|---|---|
OCR | documents_allowed({"USA": {"DL": {"enabled": 1, "sides": 2}}};省略、设为 null 或 {} 表示允许所有国家和证件)、duplicated_user_action |
LIVENESS | face_liveness_method(PASSIVE、ACTIVE_3D、FLASHING;大写)、face_liveness_score_decline_threshold、face_liveness_score_review_threshold |
FACE_MATCH | face_match_score_decline_threshold、face_match_score_review_threshold |
AML | aml_score_approve_threshold、aml_score_review_threshold |
AGE_ESTIMATION | minimum_age_threshold、borderline_minimum_age_threshold、borderline_maximum_age_threshold(1–100)、enable_id_verification_fallback |
QUESTIONNAIRE | questionnaire_uuid(创建问卷时返回的 questionnaire_id) |
wf = requests.post("https://verification.didit.me/v3/workflows/",
headers={"x-api-key": API_KEY},
json={"workflow_label": "KYC + AML", "features": [
{"feature": "OCR", "config": {"duplicated_user_action": "REVIEW"}},
{"feature": "LIVENESS", "config": {"face_liveness_method": "PASSIVE"}},
{"feature": "FACE_MATCH", "config": {"face_match_score_decline_threshold": 40,
"face_match_score_review_threshold": 60}},
{"feature": "AML", "config": {"aml_score_approve_threshold": 80}},
]}).json()
workflow_uuid = wf["uuid"]
PATCH 时的版本控制:
| 当前版本 | 发送的 status | 结果 |
|---|---|---|
| 已发布 | 无 | 原位更新(uuid 和 version 不变) |
| 已发布 | "published" | 返回新的已发布版本(新的 uuid,version + 1);该组中的任何草稿都会被删除。之后请使用返回的 uuid。 |
| 已发布 | "draft" | 400 "Cannot revert a published version to draft." |
| 草稿 | "published" | 草稿已更新并发布 |
| 草稿 | 无或 "draft" | 草稿已更新,并保持为草稿 |
会话
基础 URL: https://verification.didit.me/v3
生命周期: 创建会话,用户在 url 处完成验证,通过 webhook 或轮询获取判定结果,可选择进行审核(更新状态、重新提交、更正数据)。
状态: Not Started、In Progress、Approved、Declined、In Review、Expired、Abandoned、Kyc Expired、Resubmitted、Awaiting User(KYB 正在等待其关键人员)。没有 Pending 状态。
速率限制(每个密钥每分钟): 所有 GET 请求为 600;所有 POST/PATCH/DELETE 请求为 300。POST /v3/session/ 有单独的 600 次限制,但也计入 300 次写入限制,因此请按 300 次规划。update-data 和 update-poa-data 各为 10 次;generate-pdf 为 50 次。429 响应包含 Retry-After。
| 方法 | 路径 | 用途 |
|---|---|---|
POST | /v3/session/ | 创建会话 |
GET | /v3/session/{sessionId}/decision/ | 获取完整结果 |
GET | /v3/sessions/ | 列出并筛选会话 |
DELETE | /v3/session/{sessionId}/delete/ | 删除一个 KYC 或 KYB 会话 |
POST | /v3/sessions/delete/ | 批量删除 KYC 会话 |
GET | /v3/sessions/delete/{job_id}/ | 轮询批量删除任务 |
PATCH | /v3/session/{sessionId}/update-status/ | 批准、拒绝或重新提交 |
POST | /v3/session/{sessionId}/resubmission-preview/ | 预览重新提交邮件 |
PATCH | /v3/session/{sessionId}/features/{nodeId}/update-status/ | 设置一个步骤的状态 |
PATCH | /v3/session/{sessionId}/update-aml-hit-status/ | 审核一条 AML 命中记录 |
PATCH | /v3/session/{sessionId}/bulk-update-aml-hit-status/ | 审核多条 AML 命中记录 |
PATCH | /v3/session/{sessionId}/update-data/ | 更正提取的身份证件数据 |
PATCH | /v3/session/{sessionId}/update-poa-data/ | 更正地址证明数据 |
PATCH | /v3/session/{sessionId}/kyb/{companyUuid}/update-data/ | 更正 KYB 公司数据 |
PATCH | /v3/session/{sessionId}/kyb/parties/{partyUuid}/ | 跳过或恢复 KYB 关键人员 |
GET | /v3/session/{sessionId}/generate-pdf/ | PDF 报告 |
POST | /v3/session/{sessionId}/share/ | 生成供其他应用使用的共享令牌 |
POST | /v3/session/import-shared/ | 导入共享会话 |
GET/POST | /v3/sessions/{session_id}/reviews/ | 活动记录 / 添加备注 |
POST | /v3/session/{sessionId}/sandbox/arm/ | 仅限沙盒:启用测试场景 |
1. 创建会话
POST /v3/session/
| 请求体 | 类型 | 必填 | 描述 |
|---|---|---|---|
workflow_id | uuid | 是 | 工作流 uuid |
vendor_data | string | 否 | 您的用户或业务 ID。将会话关联到用户/业务实体,并用于重复检测。如果存在具有相同 vendor_data 和工作流的未完成会话,则返回该会话(201,并更新 callback 和 metadata),而不会创建新会话。 |
callback | url | 否 | 流程结束后的重定向地址;Didit 会附加 verificationSessionId 和 status |
callback_method | string | 否 | initiator(默认)、completer 或 both |
metadata | JSON | 否 | 任意 JSON(建议使用对象);会在判定结果和 Webhook 中原样返回 |
language | string | 否 | UI 语言:ISO 639-1 代码或 pt-BR、zh-CN、zh-TW、cnr;默认根据浏览器检测 |
contact_details | object | 否 | email、phone(E.164)、send_notification_emails、email_lang:预填邮箱/电话步骤并发送状态邮件 |
expected_details | object | 否 | 与用户提交的信息进行比对的值(不匹配项将成为警告),见下文 |
portrait_image | base64 | 有条件必填 | 参考人脸,最大 2 MB,格式为 JPEG/PNG/WebP/TIFF。生物识别身份验证工作流以及在人脸匹配先于 ID 验证执行的人脸图工作流均需提供,除非该 vendor_data 对应的用户已有已存储的人脸(否则返回 400)。 |
multi_account_segment | string | 否 | 最多 64 个字符。重复人脸检查只会比较同一分段的会话;黑名单不受此项影响。 |
sandbox_scenario | string | 否 | 仅限沙盒应用(正式环境中返回 400):来自沙盒测试的场景标识 |
expected_details 键 | 描述 |
|---|---|
first_name、last_name | 模糊匹配 |
date_of_birth | YYYY-MM-DD |
gender | M 或 F |
nationality、country、id_country、poa_country | ISO 3166-1 alpha-3;对于身份证件,id_country 优先于 country |
address | 用于地址证明匹配的可读地址;需要提供 country 或 poa_country(否则返回 400) |
identification_number | 预期的证件号、个人编号或税号 |
ip_address | 预期 IP |
expected_document_types | P、ID、DL、RP、HIC、TC、SSC 数组 |
company_name、registry_country、registration_number | KYB 会话:预填注册信息搜索;registry_country 为 ISO alpha-2 代码或细分地区,例如 US-CA |
响应(201):
{
"session_id": "11111111-2222-3333-4444-555555555555",
"session_number": 1234,
"session_token": "abcdef123456",
"url": "https://verify.didit.me/session/abcdef123456",
"vendor_data": "user-123",
"metadata": {"plan": "pro"},
"status": "Not Started",
"workflow_id": "a1b2c3d4-5678-90ab-cdef-111111111111",
"workflow_version": 1,
"callback": "https://yourdomain.com/verified"
}
将用户引导至 url,或将 session_token 传递给 SDK(参见 didit-sdk-integration)。
2. 获取会话(获取判定结果)
GET /v3/session/{sessionId}/decision/
顶层键:session_id、session_kind、session_number、session_url、status、workflow_id、features、vendor_data、metadata、expected_details、contact_details、callback、created_at、expires_at、environment、resubmissions、reviews,以及每项功能对应的一个数组:id_verifications、nfc_verifications、liveness_checks、face_matches、phone_verifications、email_verifications、poa_verifications、document_ai_documents、questionnaire_responses、aml_screenings、ip_analyses、database_validations(KYB:registry_checks、key_people_checks、document_verifications)。每个功能块都包含其 node_id,下文的审核端点会用到该值。媒体 URL 为预签名 URL,会过期(约 4 小时):不要存储这些 URL,应重新获取判定结果。
3. 列出会话
GET /v3/sessions/
| 查询参数 | 描述 |
|---|---|
session_kind | user(默认)、business 或 all |
status | 例如 Approved、Declined、In Review |
vendor_data | 精确匹配 |
workflow_id、country、search、date_from、date_to | 常用筛选条件 |
limit / offset | 页大小(默认 50)/跳过的行数 |
响应(200): {count, next, previous, results[]},按时间从新到旧排列。每行包含 session_kind(user 或 business)。
4. 删除会话
DELETE /v3/session/{sessionId}/delete/ # one KYC or KYB session (KYB also deletes its key-people verifications)
POST /v3/sessions/delete/ # KYC sessions in bulk
GET /v3/sessions/delete/{job_id}/ # poll a bulk job
删除不可撤销:会话及其媒体、提取的数据、审核记录和人脸嵌入都会被删除(除非保留人脸模板)。不会发送 webhook。不会移除由该会话创建的阻止列表条目,也不会移除 User/Business 实体(请使用 lists 和 users/businesses 端点)。
| 请求体(两个端点均可选) | 描述 |
|---|---|
retain_face_embeddings | true 会在会话的 User 上保留一个不含图像的人脸模板(重复检测仍可正常工作);false 会删除该模板;省略时使用应用策略 |
face_retention_days | 1-3650;保留模板时必填,且应用未设置期限 |
face_retention_deadline | 模板的未来日期时间硬性过期时间 |
deletion_instruction | operational_session_delete(默认)或 privacy_erasure(数据主体请求:清除该 User 的所有保留模板;不能与 retain_face_embeddings: true 同时使用) |
instruction_id | 您的参考编号(最长 255 个字符),会保留在审计记录中 |
session_numbers | 仅批量操作:仅包含数字的字符串,例如 ["1201", "1202"](除非设置 delete_all,否则必填) |
delete_all | 仅批量操作:删除该应用的所有 KYC 会话 |
- 单个删除:
200{session_id, session_number, face_retention_outcome, biometric_template_uuid, biometric_template_expires_at, deleted_child_verifications};face_retention_outcome为deleted、retained_with_user、none或ineligible_no_vendor_user。重复调用会返回404;出现503后请重试请求。 - 批量删除:最多 20 个会话时返回
200{"results": [...]};超过 20 个时返回202和{job_id, status, ...}。轮询任务,直到status为COMPLETED或FAILED(此前为PENDING、PROCESSING);结果会报告total、processed、outcomes、deleted_child_verifications、error。
5. 更新会话状态(批准、拒绝、重新提交)
PATCH /v3/session/{sessionId}/update-status/
| 请求体 | 类型 | 必填 | 描述 |
|---|---|---|---|
new_status | string | 是 | Approved、Declined 或 Resubmitted |
comment | string | 否 | 原因,会存储在会话的审核记录中 |
nodes_to_resubmit | array | 否 | 用于 Resubmitted:[{"node_id": "ocr", "feature": "OCR"}]。省略时会自动选择已尝试且需要重新提交的步骤。 |
send_email | boolean | 否 | 向用户发送电子邮件(默认 false) |
email_address | string | 有条件必填 | 当 send_email 为 true 时必填 |
email_language | string | 否 | 默认 en |
email_preview_token | string | 否 | 来自重新提交预览的 preview_token;仅在使用 send_email 时适用。如果电子邮件内容已更改或令牌已过期(15 分钟),则返回 409。 |
- 允许的当前状态:
Approved、Declined、In Review、Kyc Expired、Abandoned、Resubmitted。状态为Not Started、In Progress、Awaiting User和Expired的会话会返回400。新状态必须与当前状态不同。 - 响应(200):
{"session_id": "..."}。会触发status.updated。 node_id: 从决策的功能块中读取。使用POST /v3/workflows/构建的工作流使用功能的 slug(ocr、liveness、face_match等);通过控制台构建的图使用feature_ocr_1等 ID。- 重新提交: 所选步骤的数据会被删除,过期时间重新开始计时,同一个
url可再次使用。服务端步骤(AML、DATABASE_VALIDATION、IP_ANALYSIS)会在无需用户参与的情况下重新运行;不能直接重新提交KYB_REGISTRY和KYB_KEY_PEOPLE。
先预览重新提交邮件(可选): 使用 nodes_to_resubmit、email_address、email_language 调用 POST /v3/session/{sessionId}/resubmission-preview/。此操作不会更改任何内容,也不会发送邮件;会返回 recipient、sender、subject、html、nodes_to_resubmit、requires_user_action 和 preview_token。然后调用 update-status,并设置 new_status: "Resubmitted"、相同的选择、send_email: true 和 email_preview_token。
6. 步骤和 AML 命中项审核
| 端点 | 请求体 | 说明 |
|---|---|---|
PATCH /v3/session/{sessionId}/features/{nodeId}/update-status/ | new_status(Approved、Declined、In Review;必填)、comment | 单个步骤的状态(对于非图工作流,将 default 用作 nodeId)。必须与当前状态不同。返回 {session_id, node_id, feature_type, new_status}。不适用于独立 API 会话。触发 data.updated。 |
PATCH /v3/session/{sessionId}/update-aml-hit-status/ | hit_id、review_status(均必填)、node_id | hit_id 是 AML 检查中 hits 条目的 id。触发 data.updated。 |
PATCH /v3/session/{sessionId}/bulk-update-aml-hit-status/ | hit_updates: [{"hit_id", "review_status"}]、node_id | 要么全部成功,要么全部不变:未知的 hit_id 会返回 404,且不会更改任何内容。 |
review_status:Unreviewed、Confirmed Match、False Positive、Inconclusive。审核者的决定会在持续监控重新筛查时保留。如果工作流中有多项 AML 检查,node_id(请求体或查询参数)用于指定其中一项。
7. 更正提取的数据
仅发送需要更改的字段。如果工作流中有多项同类检查,请传递 node_id(请求体或查询参数)。KYC 和 PoA 更正会触发 data.updated(触发 manual_review)。
| 端点 | 会话状态 | 字段 |
|---|---|---|
PATCH /v3/session/{sessionId}/update-data/ | Approved、Declined、In Review、Kyc Expired | document_type、document_subtype、document_number、personal_number、date_of_birth、date_of_issue、expiration_date、issuing_state、first_name、last_name、gender(M/F/U)、address、place_of_birth、nationality、marital_status、extra_fields、parsed_address |
PATCH /v3/session/{sessionId}/update-poa-data/ | 同上 | issuing_state、document_type、document_language、issuer、issue_date、poa_address、name_on_document、extra_fields、poa_parsed_address |
PATCH /v3/session/{sessionId}/kyb/{companyUuid}/update-data/ | 任意 | company_name、registration_number、country_code、region、incorporation_date、registration_date、dissolution_date、tax_number、legal_address、company_type、registry_status、verification_status、alternative_names、nature_of_business、registered_capital、registered_capital_amount、registered_capital_currency、website、email、phone、legal_entity_identifier、location_of_registration、vat_number、control_scheme。{} 会原样返回公司信息,不做更改。需要 Businesses 写入权限。 |
PATCH /v3/session/{sessionId}/kyb/parties/{partyUuid}/ | 任意 | is_skipped(必填):true 会将关键人物从关键人员检查中移除(例如,其 KYC 会话已删除),并重新计算业务会话;false 会将其重新纳入。需要 Businesses 写入权限。 |
8. 生成 PDF 报告
GET /v3/session/{sessionId}/generate-pdf/
返回 application/pdf(附件)。仅适用于状态为 Approved、Declined、In Review 或 Kyc Expired 的 KYC 会话,以及状态为 Approved、Declined 或 In Review 的 KYB 会话;其他状态会返回 403。需要具有范围限定密钥的 Media 读取权限。每分钟最多 50 次。
9. 共享与导入(应用间复用 KYC)
POST /v3/session/{sessionId}/share/
POST /v3/session/import-shared/
| 共享请求体 | 必需 | 描述 |
|---|---|---|
for_application_id | 是 | 将要导入的 Didit 应用的 UUID(不是你自己的应用) |
ttl_in_seconds | 否 | 60-86400,默认值为 3600 |
Approved、Declined 或 In Review 状态的会话均可共享(否则返回 400),并返回 200 {share_token, for_application_id, session_kind}。
| 导入请求体 | 必需 | 描述 |
|---|---|---|
share_token | 是 | 来自共享应用的令牌 |
trust_review | 是 | true 保留原始状态;false 会将导入的会话设为 In Review |
workflow_id | 是 | 导入应用的工作流 uuid(否则返回 404) |
vendor_data | 否 | 你的用户 ID |
导入成功后返回 201,并附带新会话的审核结果。每个应用只能导入一次会话(再次导入时返回 403);令牌过期、无效或属于其他应用时返回 400。
10. 会话审核(活动动态)
GET /v3/sessions/{session_id}/reviews/
POST /v3/sessions/{session_id}/reviews/
- GET(KYC 会话):分页返回
{count, next, previous, results[]};每项包含uuid、activity_type(COMMENT、STATUS_UPDATED、KYC_DATA_UPDATED、POA_DATA_UPDATED、AML_HIT_STATUS_UPDATED等)、actor_display、actor_email、actor_type(API_KEY、CONSOLE_USER、SYSTEM)、previous_status、new_status、comment、mentioned_emails、previous_value、new_value、changed_fields、metadata、created_at。 - POST 仅添加备注:
comment和new_status均为可选;new_status(任意会话状态)只是标签。它不会更改会话状态,也不会发送 webhook。响应为201{user, new_status, comment, created_at}。如需批准或拒绝,请使用 update-status。
11. 沙盒:启用场景
使用标头 Session-Token: <session_token>(不是 x-api-key)并发送请求体 {"scenario": "<slug>"},调用 POST /v3/session/{sessionId}/sandbox/arm/,即可在用户开始之前应用沙盒场景。返回 {session_id, scenario, status};验证已开始时返回 400,实时应用则返回 404。场景 slug 和魔法值请参阅:沙盒测试。
批量导入(迁移)
从 CSV 或 NDJSON 文件导入历史验证记录,文件需符合 Didit 的规范架构(请先将之前服务商的导出数据映射到该架构)。
POST /v3/session/imports/ # JSON {source_file_url, ...} or multipart with `file`
GET /v3/session/imports/template/?import_type= # canonical CSV header for that import type
GET /v3/session/imports/{importId}/ # job status and counters
GET /v3/session/imports/{importId}/errors/ # per-row errors (row_number, external_id, error, raw_row)
| 请求体 | 必需 | 描述 |
|---|---|---|
source_file_url 或 file | 是(二选一) | 文件的公开 URL,或 multipart 上传。两者都提供或都不提供时返回 400。最大 25 MB。 |
import_type | 否 | user_verification(默认值)、business_verification(需要 KYB 工作流)、status_rules、transactions |
workflow_id | 除 transactions 外必需 | 工作流 uuid;user_verification 不接受 KYB 工作流 |
source_format | 否 | csv 或 ndjson。上传文件的格式根据扩展名确定(.csv、.ndjson);其他扩展名会返回 400。 |
- 默认关闭导入功能,由 Didit 按组织启用(否则返回
403);沙盒应用会返回403。 - 每个应用只能有一个进行中的导入任务(任务运行时返回
429)。 201任务包含:uuid、status(PENDING、PROCESSING、COMPLETED、FAILED、PAUSED、CANCELLED)、import_type、source_format、source_filename、total_rows、processed_rows、created_count、updated_count、skipped_count、failed_count、last_error、时间戳。- 导入的记录会标记为
metadata.imported_from: "generic"。
列表(拦截/允许/自定义)
匹配拦截列表会拒绝后续验证或筛查;允许列表和自定义列表则用于工作流条件和规则。列表的相关文档请参阅上方链接的文档页面。
list_type:blocklist(每种条目类型对应一个系统列表,会自动创建;无法创建、重命名或删除)、allowlist、custom。entry_type:face、document、phone、email、ip_address、device_fingerprint、wallet_address、bank_account、user、business、country、key。
| 方法 | 路径 | 说明 |
|---|---|---|
GET | /v3/lists/ | 筛选条件:list_type、entry_type;ordering 可设为 created_at、entry_count、last_entry_added_at(前缀 - 表示降序;默认 -created_at);limit、offset |
POST | /v3/lists/ | name(每个应用内唯一,如果已被占用则返回 400)、list_type(allowlist 或 custom)、entry_type、description |
GET | /v3/lists/{list_uuid}/ | 获取单个列表 |
PATCH | /v3/lists/{list_uuid}/ | name、description;系统列表会返回 400 |
DELETE | /v3/lists/{list_uuid}/ | 204;仅限允许列表和自定义列表 |
GET | /v3/lists/{list_uuid}/entries/ | search、reference_session_id、limit、offset |
POST | /v3/lists/{list_uuid}/entries/ | 添加条目(见下文);返回 201 |
POST | /v3/lists/{list_uuid}/entries/face-upload/ | 从图片添加人脸 |
DELETE | /v3/lists/{list_uuid}/entries/{entry_uuid}/ | 204;如果是系统拦截列表,还会解除对匹配实体的拦截 |
查找拦截列表 uuid: GET /v3/lists/?list_type=blocklist&entry_type=face(或 document、phone……)。
| 条目主体 | 必填 | 说明 |
|---|---|---|
value | 有条件必填 | 条目值(电子邮箱、E.164 电话号码、IP 或 CIDR、alpha-3 国家代码等)。除非提供 reference_session_id,否则必填。 |
reference_session_id | 有条件必填 | 根据列表的 entry_type 从会话中获取值(face、document、phone、email、ip_address、device_fingerprint) |
face_image_source | 否 | 带有 reference_session_id 的人脸拦截列表:liveness(默认)、front_image_camera_front、back_image_camera_front(用户拍摄证件时拍摄的自拍照) |
reference_node_id | 否 | 与证件采集的 face_image_source 搭配使用:指定要使用自拍照的 ID 验证节点 |
reference_object_uuid | 否 | 来源交易、用户或企业,用于追溯 |
display_label、comment | 否 | 标签和原因 |
metadata | 否 | 例如 {"reference_type": "vendor_user"} |
人脸上传主体: image(不带 data: 前缀的 base64 JPG 或 PNG,最大 2 MB),以及可选的 comment。仅适用于人脸拦截列表或人脸允许列表(自定义列表和其他条目类型会返回 400)。未检测到人脸:返回 400;检测到多张人脸:使用面积最大的一张。
拦截列表匹配会触发警告,例如 FACE_IN_BLOCKLIST、POSSIBLE_FACE_IN_BLOCKLIST、ID_DOCUMENT_IN_BLOCKLIST、PHONE_NUMBER_IN_BLOCKLIST、EMAIL_IN_BLOCKLIST、IP_ADDRESS_IN_BLOCKLIST、DEVICE_FINGERPRINT_IN_BLOCKLIST。
问卷
由 QUESTIONNAIRE 工作流功能运行的自定义表单。
| 方法 | 路径 | 说明 |
|---|---|---|
GET | /v3/questionnaires/ | 分页格式为 {count, next, previous, results[]} |
POST | /v3/questionnaires/ | 201;响应中的 questionnaire_id 是 config.questionnaire_uuid 的取值 |
GET | /v3/questionnaires/{questionnaire_uuid}/ | 单个问卷 |
PATCH | /v3/questionnaires/{questionnaire_uuid}/ | 部分更新 |
DELETE | /v3/questionnaires/{questionnaire_uuid}/ | 204 |
| 正文 | 必填 | 说明 |
|---|---|---|
title | 是 | 最多 255 个字符 |
languages | 是 | 必须包含 "en" |
form_elements | 是 | 至少包含一个元素 |
default_language | 否 | 默认为 en;必须包含在 languages 中 |
description | 否 | 向用户显示 |
is_active | 否 | 默认为 true |
status | 否 | 省略则发布;设为 draft 则保存但不发布 |
| 元素字段 | 说明 |
|---|---|
element_type | 必填。 short_text、long_text、paragraph、dropdown、single_choice、multiple_choice、number、image、file_upload、time、email、address、phone、country、date_picker、consent、section_header、separator、heading(不支持 checkbox 或 date) |
label | 必填。 为 languages 中的每种语言提供翻译:{"en": "Occupation?"} |
id | 可选稳定 ID(自动生成 q1、q2……) |
description、placeholder | 翻译对象 |
is_required | 默认为 false |
options | dropdown、single_choice、multiple_choice 必填:[{"value": "employed", "label": {"en": "Employed"}}](value 可选) |
max_files | 1-5,适用于 file_upload 和 image |
validation | short_text/long_text:pattern、min_length、max_length;number:min、max |
API 会构建简单的线性问卷。分支、条件问题和可重复组需在 Console 中构建:element_type: "repeatable_group" 以及 branches、required_if 和 repeatable_config 字段会返回 400。Console 构建的可重复组的答案会以 REPEATABLE_GROUP 元素的形式返回在决策中。
q = requests.post("https://verification.didit.me/v3/questionnaires/",
headers={"x-api-key": API_KEY},
json={
"title": "Employment Details",
"languages": ["en"],
"default_language": "en",
"form_elements": [
{"element_type": "short_text", "label": {"en": "Occupation?"}, "is_required": True},
{"element_type": "single_choice", "label": {"en": "Employment status"},
"options": [{"label": {"en": "Employed"}}, {"label": {"en": "Student"}}]},
],
}).json()
questionnaire_uuid = q["questionnaire_id"]
用户(KYC)
按 vendor_data 标识的已验证个人。用户的 status 是监控状态,而非验证决定:ACTIVE、FLAGGED 或 BLOCKED。
| 方法 | 路径 | 说明 |
|---|---|---|
GET | /v3/users/ | limit(默认 50)、offset |
POST | /v3/users/create/ | 201 返回完整用户记录;重复的 vendor_data 返回 400 |
GET | /v3/users/{vendor_data}/ | 单个用户 |
PATCH | /v3/users/{vendor_data}/ | 仅发送要更改的字段(metadata 会整体替换) |
PATCH | /v3/users/{vendor_data}/update-status/ | status(必填)、可选的 reason;BLOCKED 还会将 vendor_data 添加到系统封锁名单。触发 user.status.updated。 |
POST | /v3/users/delete/ | vendor_data_list、didit_internal_id_list(可组合),或 delete_all: true;返回 {deleted} |
GET | /v3/users/{vendor_data}/generate-pdf/ | 包含该用户可报告的 KYC 会话的 PDF(最新 20 个);没有会话时返回 403 |
POST | /v3/organization/{organization_id}/application/{application_id}/vendor-users/by-id/{didit_internal_id}/faces/upload/ | 添加可信人脸:image(base64 JPG/PNG,最大 2 MB)、comment。用于重复检测和人脸搜索索引,不会加入封锁名单。返回 201。 |
创建/更新字段:vendor_data(创建时必填)、full_name、display_name、date_of_birth(YYYY-MM-DD)、status(默认 ACTIVE)、metadata(对象)、approved_emails、approved_phones、issuing_states。
列表行字段:didit_internal_id、vendor_data、display_name、full_name、effective_name、date_of_birth、status、portrait_image_url、session_count、approved_count、declined_count、in_review_count、issuing_states、approved_emails、approved_phones、features、features_list、first_session_at、last_session_at、last_activity_at、tags、created_at。
AML 持续监控(用户和企业)
POST /v3/users/aml-monitoring/
POST /v3/businesses/aml-monitoring/
GET /v3/aml-monitoring/jobs/{job_id}/
请求体:is_enabled(必填)、estimate_only(默认 false:返回费用估算,不做任何更改)、vendor_data_list 和/或 didit_internal_id_list(标识符总数最多 1000 个)。最多 20 个档案会内联处理(任务完成后返回 200);更多档案则返回 202 并在后台运行。任务字段:job_id、status(PENDING、PROCESSING、COMPLETED、FAILED)、is_enabled、target_type、total、processed、outcomes、results[]、error、created_at、completed_at。额度不足时返回 403 和 estimate。定价页面列出的 AML 监控价格为每年 $0.07。
生物识别模板
应用删除会话后(通过 retain_face_embeddings 或应用的保留政策)保留的无图像人脸模板,可让重复检测继续运行。仅限 API 密钥使用。
| 方法 | 路径 | 说明 |
|---|---|---|
GET | /v3/biometric-templates/ | 筛选条件:vendor_data(子串)、vendor_user_uuid、status、source_type(session_delete、automatic_retention、backfill)、retained_from、retained_to、ordering(retained_at、expires_at,可加 -);limit、offset |
GET | /v3/biometric-templates/count/ | 使用相同筛选条件返回 {count} |
GET | /v3/biometric-templates/{template_uuid}/ | 单个模板 |
DELETE | /v3/biometric-templates/{template_uuid}/ | 清除:{uuid, outcome}(purged 或 already_purged) |
POST | /v3/biometric-templates/delete/ | template_uuids 或 delete_all: true(以及用于缩小范围的筛选条件):{results: [{uuid, outcome}]} |
企业(KYB)
按 vendor_data 标识的已验证公司,具有相同的 ACTIVE/FLAGGED/BLOCKED 监控状态。
GET /v3/businesses/ # limit, offset
POST /v3/businesses/create/ # vendor_data, display_name, legal_name, registration_number, country_code (ISO alpha-2), status, metadata
GET /v3/businesses/{vendor_data}/
PATCH /v3/businesses/{vendor_data}/ # display_name, legal_name, registration_number, country_code, status, metadata
PATCH /v3/businesses/{vendor_data}/update-status/ # status (required), optional reason; fires business.status.updated
POST /v3/businesses/delete/ # vendor_data_list, didit_internal_id_list, or delete_all: true -> {deleted}
POST /v3/businesses/aml-monitoring/ # see AML Ongoing Monitoring above
KYB 注册查询(无会话)
| 端点 | 请求体 | 价格 |
|---|---|---|
POST /v3/kyb/search/ | country_code(必填;ISO alpha-2,US 需要指定州,例如 US-CA)、name 和/或 registration_number、search_type(contains)、vendor_data、metadata、webhook_url | 每次成功搜索且有付费来源结果,收费 $0.50 |
POST /v3/kyb/select/ | kyb_response_id(必填)、vendor_data、metadata | 简版资料和高管,$2.00(价格因国家而异) |
POST /v3/kyb/shareholders/ | 与 select 相同 | 简版资料加直接股东,按国家收费 $5.00-$22.00 |
POST /v3/kyb/ubo/ | 与 select 相同 | 股东加最终受益所有人,按国家收费 $9.00-$96.00 |
kyb_response_id 来自同一应用中的搜索,且有效期很短:请尽快调用 select;不要存储它,而应重新搜索。使用 webhook_url 时,搜索会立即返回(search_status: "pending"),之后 Didit 会 POST 一个未签名的 kyb.registry_search.resolved 回调(请求头 X-Didit-Unsigned-Callback: true);请通过 request_id 匹配。注册查询仍在处理中时,股东和 UBO 调用可能会返回 202。
交易
交易监控有自己的技能:使用 didit-transaction-monitoring 创建交易、执行 Travel Rule 交换、筛查钱包和管理规则;用户事件则使用 didit-event-monitoring。基本路由如下:
GET /v3/transactions/ # limit, offset
POST /v3/transactions/ # required: transaction_id, transaction_category, transaction_details, subject{vendor_data, full_name, ...}
GET /v3/transactions/{uuid}/ # Didit's transaction uuid from the create response, NOT your transaction_id
transaction_category:finance、kyc、travel_rule、user_event、audit_trail_event、gambling_bet、gambling_limit_change、gambling_bonus_change。
账单
| 端点 | 请求体 | 响应 |
|---|---|---|
GET /v3/billing/balance/ | - | {"balance": "142.5000", "auto_refill_enabled": true, "auto_refill_amount": "100.0000", "auto_refill_threshold": "10.0000"};未设置时,自动充值相关值为 null |
POST /v3/billing/top-up/ | amount_in_dollars(必填,最低 50)、success_url、cancel_url(请明确传入两者) | 200 {"checkout_session_id": "cs_...", "checkout_session_url": "https://checkout.stripe.com/..."} |
向用户展示 checkout_session_url 以便付款;付款结算后,余额会增加。充值错误(400)以 JSON 数组形式返回,例如 ["Amount must be at least $50."]。采用年度方案的组织会收到 400,并需通过客户经理充值。
自定义(品牌)
GET /v3/customization/
PATCH /v3/customization/ # application/json for settings, multipart/form-data for images
| PATCH 字段 | 说明 |
|---|---|
color_primary、color_secondary、color_background、color_panel、color_panel_10、color_on_panel_1、color_on_panel_2、color_on_background、color_button_1、color_button_2、color_button_text_1、color_button_text_2、color_pill_text | 十六进制颜色值 |
border_radius_panel、border_radius_buttons、font_family、font_weight | 布局和字体 |
app_public_name、privacy_policy_url、skip_welcome_screen、disable_login_with_didit、hide_progress_bar、callback_seconds | 流程选项 |
image_square、image_rectangular、image_favicon | 多部分上传(徽标和网站图标) |
delete_logo_square、delete_logo_rectangular、delete_favicon | 设为 true 可移除图片 |
只会更改你发送的字段。自定义域名和白标电子邮件只能在 Business Console 中设置(此处会返回 400)。
Webhook 目标
可注册任意数量的目标,每个目标都可设置自己的 URL、载荷版本、事件和签名密钥。
| 方法 | 路径 | 说明 |
|---|---|---|
GET | /v3/webhook/destinations/ | 按创建时间从早到晚排列的 uuid、label、url、enabled、webhook_version、subscribed_events、subscribed_events_count、deliveries_count、failed_deliveries_count、average_response_time_ms、error_rate_percentage、last_delivery_at、created_at、updated_at 数组。列表项中不包含密钥。 |
POST | /v3/webhook/destinations/ | 返回 201,包含 secret_shared_key 和投递 summary |
GET | /v3/webhook/destinations/{destination_uuid}/ | 包含 secret_shared_key |
PATCH | /v3/webhook/destinations/{destination_uuid}/ | 字段与创建时相同;subscribed_events 会被替换,而非合并。密钥不会轮换。 |
DELETE | /v3/webhook/destinations/{destination_uuid}/ | 返回 204;重复删除会返回 404 |
| 创建请求体 | 必填 | 说明 |
|---|---|---|
label | 是 | 名称,最多 255 个字符 |
url | 是 | HTTPS 端点,在每个应用中必须唯一(如果已使用,则返回 400) |
subscribed_events | 实际上必填 | 要投递的事件(见下文列表)。[] 会返回 400;省略此字段会创建一个不会收到任何内容的目标。 |
webhook_version | 否 | v1、v2 或 v3;请使用 v3 |
enabled | 否 | 默认为 true;设为 false 可暂停该目标 |
dest = requests.post(
"https://verification.didit.me/v3/webhook/destinations/",
headers={"x-api-key": API_KEY},
json={"label": "Prod", "url": "https://yourdomain.com/webhooks/didit", "webhook_version": "v3",
"subscribed_events": ["status.updated", "data.updated"]},
).json()
secret = dest["secret_shared_key"] # store it in your secrets manager
# Pause a destination without deleting it
requests.patch(f"https://verification.didit.me/v3/webhook/destinations/{dest['uuid']}/",
headers={"x-api-key": API_KEY}, json={"enabled": False})
Webhook 事件与签名
Didit 会向订阅了该事件的每个已启用目标发送 JSON POST 请求(User-Agent: DiditWebhook/2.0 +https://didit.me)。
事件(webhook_type) | 触发时机 |
|---|---|
status.updated | KYC 或 KYB 会话的状态发生变化(KYB 载荷会添加 session_kind: "business" 和 business_session_id) |
data.updated | 事后编辑会话数据时(审核人员更正、步骤状态或 AML 命中状态发生变化) |
user.status.updated / user.data.updated | 用户的 ACTIVE/FLAGGED/BLOCKED 状态或个人资料数据发生变化 |
business.status.updated / business.data.updated | 企业的状态或数据发生变化 |
activity.created | 可在 subscribed_events 中接受,但不会针对实时流量发送 |
transaction.created / transaction.status.updated | 创建交易并生成首个判定时/交易状态发生变化时 |
travel_rule.status.updated | Travel Rule 交换的状态发生变化 |
会话事件封装:
| 字段 | 说明 |
|---|---|
event_id | 在不同目标和重试请求中保持相同:请据此去重 |
webhook_type | 上述事件之一 |
timestamp | 派发时的 Unix 秒数(每次重试都会刷新;与 X-Timestamp 相同) |
created_at | 记录上次更新时的 Unix 秒数 |
application_id, environment | environment 为 live 或 sandbox |
session_id, status | 状态使用会话标签(Approved、Kyc Expired 等) |
workflow_id, workflow_version, vendor_data, metadata | 设置时提供 |
sandbox_scenario | 沙盒会话中已启用的场景;否则为 null |
trigger | 可选:manual_review、manual_step_update、ongoing_monitoring |
decision | 仅当 status 为 Approved、Declined、In Review 或 Abandoned 时提供;架构与判定端点相同 |
resubmit_info | 当 status 为 Resubmitted 时提供 {nodes_to_resubmit, reasons} |
**投递:**请快速响应 2xx 并异步处理。遇到 5xx、404、超时或连接失败时,最多重试 2 次(约 1 分钟后重试一次,再约 4 分钟后重试一次);其他 3xx/4xx 响应不会重试。
签名标头
| 标头 | 签名内容 | 用途 |
|---|---|---|
X-Timestamp | 分发时的 Unix 秒数 | 如果与当前时间相差超过 300 秒,则拒绝 |
X-Signature-V2 | 规范化 JSON 的 HMAC-SHA256(十六进制):解析请求体,将整数值的浮点数转换为整数,使用 json.dumps(..., sort_keys=True, separators=(",", ":"), ensure_ascii=False)。不添加时间戳前缀。 | 推荐:可兼容会重新编码 JSON 的框架 |
X-Signature | 原始请求体字节的 HMAC-SHA256(十六进制) | 适用于可以读取原始请求体的情况 |
X-Signature-Simple | "{timestamp}:{session_id}:{status}:{webhook_type}" 的 HMAC-SHA256(对于没有 session_id 的事件,则使用 "{timestamp}::{status}:{webhook_type}") | 已弃用:仅覆盖信封,不包含 decision。如果依赖此签名,请在采取操作前从 API 重新获取记录。 |
密钥是目标的 secret_shared_key。
import hashlib
import hmac
import json
import time
def shorten_floats(value):
"""Whole-number floats become ints, recursively (87.0 -> 87), as Didit does before signing."""
if isinstance(value, dict):
return {k: shorten_floats(v) for k, v in value.items()}
if isinstance(value, list):
return [shorten_floats(v) for v in value]
if isinstance(value, float) and value.is_integer():
return int(value)
return value
def verify_webhook(body: bytes, headers: dict, secret: str, now: int | None = None, tolerance: int = 300) -> bool:
"""Verify a Didit webhook. `body` is the raw request body, `headers` the request headers (any casing)."""
h = {str(k).lower(): v for k, v in headers.items()}
try:
ts = int(h.get("x-timestamp", ""))
except (TypeError, ValueError):
return False
current = now if now is not None else int(time.time())
if abs(current - ts) > tolerance:
return False
if isinstance(body, str):
body = body.encode("utf-8")
key = secret.encode("utf-8")
candidates = []
try:
canonical = json.dumps(
shorten_floats(json.loads(body)), sort_keys=True, separators=(",", ":"), ensure_ascii=False
)
v2 = hmac.new(key, canonical.encode("utf-8"), hashlib.sha256).hexdigest()
candidates.append((h.get("x-signature-v2"), v2))
except (ValueError, TypeError):
pass
raw = hmac.new(key, body, hashlib.sha256).hexdigest()
candidates.append((h.get("x-signature"), raw))
return any(sig and hmac.compare_digest(str(sig), expected) for sig, expected in candidates)
# Minimal Flask receiver
import os
from flask import Flask, request, abort
app = Flask(__name__)
@app.post("/webhooks/didit")
def didit_webhook():
body = request.get_data() # raw bytes, before any JSON parsing
if not verify_webhook(body, dict(request.headers), os.environ["DIDIT_WEBHOOK_SECRET"]):
abort(401)
event = request.get_json()
# dedupe on event["event_id"], then queue work by event["webhook_type"]
return {"ok": True}
错误响应(所有端点)
| 代码 | 含义 | 操作 |
|---|---|---|
400 | 请求无效 | 查看响应正文中的字段错误 |
401 | API 密钥已过期 | 轮换密钥,或在 Developers > API keys 中创建新密钥 |
403 | 缺少 API 密钥、密钥错误或已撤销;受限密钥无权访问此端点;请求来自密钥 IP 允许列表之外;或额度不足 | 查看 detail 或 error 中的消息:修正 x-api-key 标头或密钥权限,或充值 |
404 | 未找到资源,或会话超出受限密钥的工作流/仅限已批准项的范围 | 检查 ID 和密钥限制 |
409 | update-status:email_preview_token 已不匹配(内容已更改或已超过 15 分钟) | 重新预览,然后重试 |
429 | 速率限制:每个密钥每分钟最多 300 个 POST/PATCH/DELETE 请求和 600 个 GET 请求 | 等待 Retry-After 指定的秒数,然后重试 |
503 | 删除会话或用户时,存储依赖项不可用 | 重复发送相同请求 |
账户设置端点(apx.didit.me/auth/v2)使用 Bearer 令牌:格式错误或已过期的令牌返回 401;未提供令牌,或你不是组织的所有者或管理员时返回 403;返回 429 时会附带 Retry-After。
常见工作流
完整 KYC 入驻流程
1. POST /programmatic/register/ + POST /programmatic/verify-email/ -> application.api_key
2. POST /v3/workflows/ -> features [OCR, LIVENESS, FACE_MATCH, AML]; keep wf["uuid"]
3. POST /v3/webhook/destinations/ -> url + subscribed_events ["status.updated", "data.updated"]; store secret_shared_key
4. POST /v3/session/ -> workflow_id + vendor_data; send the user to url
5. Webhook status.updated -> verify_webhook(), dedupe on event_id
6. GET /v3/session/{id}/decision/ -> read results (re-fetch for fresh media URLs)
人工审核与阻止列表
1. Webhook: status "In Review"
2. GET /v3/session/{id}/decision/ -> inspect warnings, AML hits, node_ids
3. AML hits: PATCH .../update-aml-hit-status/ -> False Positive / Confirmed Match
4. Legit: PATCH .../update-status/ {"new_status": "Approved", "comment": "..."}
Fraud: PATCH .../update-status/ {"new_status": "Declined", "comment": "..."}
GET /v3/lists/?list_type=blocklist&entry_type=face -> blocklist uuid
POST /v3/lists/{uuid}/entries/ {"reference_session_id": "<session_id>"}
(repeat with entry_type=document for the ID document)
要求用户重新完成某个步骤
1. GET /v3/session/{id}/decision/ -> node_id of the failed step (e.g. "ocr")
2. POST /v3/session/{id}/resubmission-preview/ -> preview_token (optional)
3. PATCH /v3/session/{id}/update-status/ -> new_status "Resubmitted", nodes_to_resubmit,
send_email true, email_address, email_preview_token
4. The same url works again; status.updated fires when the user finishes
在多个应用之间复用 KYC
App A: POST /v3/session/{id}/share/ {"for_application_id": "<app B uuid>"} -> share_token
App B: POST /v3/session/import-shared/ {"share_token", "trust_review": true, "workflow_id": "<app B workflow uuid>"}
工作流中的问卷
1. POST /v3/questionnaires/ -> questionnaire_id
2. POST /v3/workflows/ -> {"features": [{"feature": "OCR"}, {"feature": "QUESTIONNAIRE",
"config": {"questionnaire_uuid": "<questionnaire_id>"}}]}
3. POST /v3/session/ -> workflow_id = the new workflow's uuid
数据主体信息删除
1. DELETE /v3/session/{id}/delete/ {"deletion_instruction": "privacy_erasure", "instruction_id": "ticket-123"}
2. POST /v3/users/delete/ {"vendor_data_list": ["user-123"]}
创建会话前检查余额
1. GET /v3/billing/balance/ -> balance
2. If low: POST /v3/billing/top-up/ {"amount_in_dollars": 50, "success_url": ..., "cancel_url": ...}
3. POST /v3/session/
实用脚本
setup_account.py:注册、验证、重新发送验证码、登录
pip install requests
read -rs DIDIT_PASSWORD && export DIDIT_PASSWORD # optional: otherwise each command prompts
python scripts/setup_account.py register [email protected]
# (check email for the 6-character code)
python scripts/setup_account.py verify [email protected] A3K9F2 # prints org uuid, app uuid, api_key
python scripts/setup_account.py resend-otp [email protected]
python scripts/setup_account.py login [email protected]
密码来自 DIDIT_PASSWORD 环境变量,或者通过不回显输入的提示输入。切勿将密码放在
命令行中:其他本地用户可以在进程列表中读取密码,而且密码还会保留在 shell 历史记录和 Agent 日志中。
为兼容旧版调用方,仍支持位置参数密码,但脚本会打印警告。
Agent 在没有终端的情况下运行这些命令时,脚本无法提示输入:请让用户在 Agent 的环境中导出
DIDIT_PASSWORD,而不是将密码粘贴到对话中。
manage_workflows.py:工作流增删改查
export DIDIT_API_KEY="your_key"
python scripts/manage_workflows.py list --limit 50
python scripts/manage_workflows.py create --label "My KYC" --liveness --face-match
python scripts/manage_workflows.py create --label "Age check" --features '[{"feature": "AGE_ESTIMATION"}]'
python scripts/manage_workflows.py get <uuid>
python scripts/manage_workflows.py update <uuid> --label "Renamed KYC"
python scripts/manage_workflows.py update <uuid> --features '[{"feature":"OCR"},{"feature":"AML"}]' --status published
python scripts/manage_workflows.py delete <uuid>
create_session.py:创建、获取和列出会话
export DIDIT_API_KEY="your_key"
python scripts/create_session.py create --workflow-id <uuid> --vendor-data user-123
python scripts/create_session.py create --workflow-id <uuid> --vendor-data user-123 \
--callback https://yourdomain.com/verified --metadata '{"plan": "pro"}'
python scripts/create_session.py get <session_id>
python scripts/create_session.py list --status Approved --limit 20 --offset 0
所有脚本都可以作为库导入:
from scripts.setup_account import register, verify_email, resend_otp, login
from scripts.manage_workflows import list_workflows, create_workflow, update_workflow
from scripts.create_session import create_session, get_decision, list_sessions