关于 didit-face-match
用于调用 Didit Face Match API 比较两张人脸图像的技能,返回相似度分数和审核状态,并支持设置阈值及可选图像旋转。
主要功能
- 01比较两张人脸图像
- 02返回相似度分数和状态
- 03设置拒绝阈值
- 04可选旋转图像以检测人脸
- 05提供人脸框及估算信息
适用场景
- 01比较自拍与证件头像
- 02核验两张提交图像是否为同一人
- 03按指定阈值评估人脸相似度
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ didit-protocol/ skills --skill didit-face-match安装后在 Claude Code 中输入/didit-face-match确认已加载。
附带文件scripts/match_faces.py
详细介绍
Didit 人脸匹配 API
概述
比较两张人脸图像,以确定它们是否显示同一个人。返回相似度分数(0-100)和 Approved / Declined 状态。
主要限制:
- 允许的文件扩展名:tiff、jpg、jpeg、png、webp(不支持 PDF)
- 最大文件大小:每张图像 5 MB(处理前会将图像压缩至约 0.5 MB)
user_image和ref_image均为必填项- 为获得最佳效果,每张图像请提交一张清晰、正面、光线充足的人脸照片
定价:$0.05(每次成功调用;独立调用没有免费额度)。这些是截至 2026 年 11 月 1 日的标价,届时 Didit 将调整定价,每月 500 次免费检查将变为每月 $10 的免费额度。请查看 didit.me/pricing 了解当前价格。
判定:只有当分数严格高于 face_match_score_decline_threshold(默认值为 30)时,结果才为 Approved。分数小于或等于该值时,将返回 Declined 和 LOW_FACE_MATCH_SIMILARITY。如果无法对任何人脸进行评分,调用仍会返回 HTTP 200,状态为 Declined,并附带 NO_REFERENCE_IMAGE。此端点不提供 In Review 状态;仅可配置阈值。
人脸搜索索引:此端点绝不会录入人脸,也不会执行阻止列表或重复项筛查。如需这些功能,请使用 POST /v3/passive-liveness/(didit-liveness-detection)或 POST /v3/face-search/(didit-face-search)。
**保存(save_api_request,默认值为 true):**调用会保存为 API 会话(Business Console、GET /v3/session/{request_id}/decision/、status.updated webhook),两张图像都会作为该会话的人脸匹配源图像和目标图像存储。设为 false 时不会存储任何内容,也无法通过 request_id 查找。
**沙盒:**沙盒 API 密钥在请求验证后会返回固定的 Approved 载荷;不会保存或计费。
**功能:**相似度评分、可配置的拒绝阈值、每张人脸的人脸边界框及模型估算的年龄和性别(仅供参考)、可选的非直立人脸旋转功能。
API 参考: https://docs.didit.me/standalone-apis/face-match 功能指南: https://docs.didit.me/core-technology/face-match/overview
身份验证
每个请求都需要 x-api-key 标头。请使用你在 Didit Business Console 的 Developers > API keys 下找到的应用 API 密钥,或者以编程方式创建账户和密钥(参见入门指南)。具有自定义访问权限的命名密钥需要 Sessions 写入权限才能运行独立检查;仅限于部分工作流或已批准会话的密钥无法运行此类检查。
入门指南(还没有账户?)
如果你还没有 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/ 查看余额;使用 {"amount_in_dollars": 50} 调用 POST /v3/billing/top-up/ 获取 Stripe 结账链接。
如需完整的平台管理功能(工作流、会话、用户、账单),请参阅 didit-verification-management 技能。
端点
POST https://verification.didit.me/v3/face-match/
标头
| 标头 | 值 | 必填 |
|---|---|---|
x-api-key | 你的 API 密钥 | 是 |
Content-Type | multipart/form-data(由你的 HTTP 客户端设置) | 是 |
请求参数(multipart/form-data)
| 参数 | 类型 | 必填 | 默认值 | 限制 | 描述 |
|---|---|---|---|---|---|
user_image | file | 是 | - | tiff/jpg/jpeg/png/webp,最大 5 MB | 要验证的人脸(例如自拍) |
ref_image | file | 是 | - | 同上 | 参考人脸(例如证件照或已登记的照片) |
face_match_score_decline_threshold | float | 否 | 30 | 0-100 | 分数小于或等于此值时,以 LOW_FACE_MATCH_SIMILARITY 为由拒绝;严格高于此值则通过 |
rotate_image | boolean | 否 | false | - | 尝试将两张图片分别旋转 0/90/180/270 度,并使用人脸检测效果最佳的方向。这会增加延迟 |
save_api_request | boolean | 否 | true | - | 保存为 API 会话并存储两张图片(见概述) |
vendor_data | string | 否 | - | - | 你的用户标识符,会被存储并在响应中原样返回 |
metadata | JSON object | 否 | - | multipart 中以 JSON 编码的字符串形式传递 | 随会话存储(保存时),并在响应中原样返回 |
示例
import requests
with open("selfie.jpg", "rb") as selfie, open("id_photo.jpg", "rb") as portrait:
response = requests.post(
"https://verification.didit.me/v3/face-match/",
headers={"x-api-key": "YOUR_API_KEY"},
files={
"user_image": ("selfie.jpg", selfie, "image/jpeg"),
"ref_image": ("id_photo.jpg", portrait, "image/jpeg"),
},
data={"face_match_score_decline_threshold": "50", "vendor_data": "user-123"},
timeout=60,
)
response.raise_for_status()
face_match = response.json()["face_match"]
print(face_match["status"], face_match["score"])
const formData = new FormData();
formData.append("user_image", selfieFile);
formData.append("ref_image", referenceFile);
formData.append("face_match_score_decline_threshold", "50");
formData.append("vendor_data", "user-123");
const response = await fetch("https://verification.didit.me/v3/face-match/", {
method: "POST",
headers: { "x-api-key": "YOUR_API_KEY" },
body: formData,
});
const { face_match } = await response.json();
响应(200 OK)
{
"request_id": "f9f5a777-8002-44c6-baaf-128bcfd6e226",
"face_match": {
"status": "Approved",
"score": 99.41,
"user_image": {
"entities": [
{"bbox": [661, 728, 1688, 2188], "confidence": 0.732973, "age": 26.91, "gender": "male"}
],
"best_angle": 0
},
"ref_image": {
"entities": [
{"bbox": [653, 745, 1691, 2185], "confidence": 0.722082, "age": 27.0, "gender": "male"}
],
"best_angle": 0
},
"warnings": []
},
"vendor_data": "user-123",
"metadata": null,
"created_at": "2026-06-12T01:04:42.763237+00:00"
}
状态值与处理方式
| 状态 | 含义 | 操作 |
|---|---|---|
"Approved" | 分数严格高于阈值 | 人脸匹配,继续处理 |
"Declined" | 分数小于或等于阈值(LOW_FACE_MATCH_SIMILARITY),或无法为任何人脸对评分(NO_REFERENCE_IMAGE) | 检查 warnings。对于 NO_REFERENCE_IMAGE,请索取更清晰的图片(对于侧向拍摄的图片,可尝试设置 rotate_image=true) |
错误响应
| 代码 | 含义 | 操作 |
|---|---|---|
400 | 请求无效(缺少图片、文件超过 5 MB、扩展名不受支持、阈值超出 0-100 范围) | 查看响应正文中的字段错误信息 |
401 | API 密钥已过期 | 轮换密钥,或在 Developers > API keys 中创建新密钥 |
403 | 缺少、错误或已撤销的 API 密钥;无权访问此端点的受限密钥;请求来自密钥 IP 允许列表之外;或积分不足 | 查看 detail 或 error 中的消息:修正 x-api-key 请求头或密钥访问权限,或充值 |
429 | 速率限制:每个密钥每分钟最多 300 次 POST/PATCH/DELETE 请求和 600 次 GET 请求 | 等待 Retry-After 秒后重试 |
响应字段参考
| 字段 | 类型 | 描述 |
|---|---|---|
request_id | uuid | 当 save_api_request=true 时为会话 ID(与 GET /v3/session/{request_id}/decision/ 配合使用);否则为一次性关联 ID |
face_match.status | string | "Approved" 或 "Declined" |
face_match.score | float or null | 0-100 的相似度(越高表示越相似)。保存时四舍五入到小数点后 2 位;save_api_request=false 时返回原始浮点数。无法为任何人脸对评分时,该值为 null(已保存)或 0(未保存),且始终伴随 NO_REFERENCE_IMAGE |
face_match.user_image.entities[] | array | 每个检测到的人脸对应一个条目:bbox [x_min, y_min, x_max, y_max]、confidence(0-1)、age、gender。年龄和性别仅供参考,不会影响判断 |
face_match.user_image.best_angle | integer | 检测效果最佳时的旋转角度(0、90、180、270);仅当 rotate_image=true 且图片经旋转纠正时为非零值 |
face_match.ref_image | object | 与 user_image 结构相同,表示参考图片 |
face_match.warnings[] | array | {risk, feature, additional_data, log_type, short_description, long_description}。feature 始终为 FACEMATCH,additional_data 始终为 null |
vendor_data | string or null | 原样返回你发送的内容 |
metadata | object or null | 原样返回你发送的内容 |
created_at | string | 响应时间,采用 ISO 8601 UTC 格式 |
警告标签
| 标签 | 严重性 | 拒绝 | 触发条件 |
|---|---|---|---|
NO_REFERENCE_IMAGE | error | 是 | 无法对任何人脸对进行评分(例如,其中一张图片中没有可用的人脸) |
LOW_FACE_MATCH_SIMILARITY | error | 是 | 分数小于或等于 face_match_score_decline_threshold |
此端点不会触发 NO_FACE_DETECTED:缺少人脸时会显示为 NO_REFERENCE_IMAGE。
**安全最佳实践:**仅存储
status、score和request_id。设置save_api_request=true后,可通过会话决策获取已存储图片的限时 URL(默认有效期为 4 小时),因此无需在自己的服务器上保留生物特征图片。
选择阈值
- 默认值
30较宽松。提高该值(例如设为50到60)可加强验证;超出 0 到 100 范围的值会返回400。 - 比较规则是“严格高于阈值才通过”:阈值为
50时,分数为50.0会被拒绝。 - 独立端点只有拒绝阈值。托管工作流(
FACE_MATCH功能)另有一个face_match_score_review_threshold,会将介于两个阈值之间的分数设为“In Review”。 - 将
score与你自己的处理结果一同记录,并根据对误匹配的容忍度调整阈值。
常见工作流
自拍照与身份证件对比
1. POST /v3/passive-liveness/ with the selfie -> confirm it is live (didit-liveness-detection)
2. POST /v3/id-verification/ with the document -> extract and check it (didit-id-document-verification)
3. POST /v3/face-match/ with user_image=selfie, ref_image=document portrait
4. All Approved -> the live person matches the document
若要在一个会话中通过托管流程完成这三项操作,请使用包含 OCR、LIVENESS 和 FACE_MATCH 的工作流(参见 didit-kyc-onboarding 技能)。
实用脚本
export DIDIT_API_KEY="your_api_key"
python scripts/match_faces.py selfie.jpg id_photo.jpg
python scripts/match_faces.py selfie.jpg id_photo.jpg --threshold 50 --rotate --vendor-data user-123
python scripts/match_faces.py selfie.jpg id_photo.jpg --no-save --metadata '{"flow": "login"}'