关于 didit-biometric-age-estimation
通过面部图像估算年龄,并在同一请求中进行被动活体检测。该 Didit API 技能适用于低摩擦年龄门槛检查,结果不能作为法定年龄证明。
主要功能
- 01根据面部图像估算年龄
- 02执行被动活体检测
- 03设置年龄与活体拒绝阈值
- 04可旋转图像以辅助人脸检测
- 05将结果保存为 API 会话
适用场景
- 01为线上注册设置年龄门槛
- 02人脸或活体检查失败时要求重拍
- 03将临界年龄估算转交证件核验
MCP 相关
此技能介绍 Didit Age Estimation API;输入未说明 MCP 服务或 MCP 专用接口。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ didit-protocol/ skills --skill didit-biometric-age-estimation安装后在 Claude Code 中输入/didit-biometric-age-estimation确认已加载。
附带文件scripts/estimate_age.py
详细介绍
Didit 年龄估算 API
概述
从人脸图像估算一个人的年龄,并在同一次调用中运行被动活体检测,以拦截伪造。年龄是根据人脸由模型预测的,并非通过证件核验:请将其用于年龄门槛和低摩擦检查,而不要将其作为法定年龄证明。
主要限制:
- 允许的文件扩展名:tiff、jpg、jpeg、png、webp(不支持 PDF)
- 最大文件大小:5 MB(处理前会将图像压缩至约 0.3 MB)
- 需要一张清晰、正面、光线充足的人脸图像。检测到的最大人脸决定
age_estimation的结果 - 准确度:总体平均绝对误差(MAE)为 3.5 年;未满 18 岁人群为 1.5 年(见下表)
定价:$0.10(每次成功调用;独立调用没有免费额度)。这些是截至 2026 年 11 月 1 日的标价,届时 Didit 将调整定价,每月 500 次免费检查将改为每月 $10 的免费额度。请访问 didit.me/pricing 查看当前价格。
判定:出现任何警告都会被拒绝。只有在 warnings 为空时,status 才为 Approved。此端点不会返回 In Review。method 始终为 PASSIVE。
**此端点不提供:**阻止列表和重复人脸筛查、MULTIPLE_FACES_DETECTED、针对临界年龄的证件核验回退,以及按国家/地区设置的年龄限制。这些是工作流功能(见自适应年龄估算)。
**保存(save_api_request,默认值为 true):**调用会作为 API 会话保存(可在 Business Console 中查看、触发 status.updated webhook,并可通过 GET /v3/session/{request_id}/decision/ 查询;结果显示在 liveness_checks[] 中,且 features: ["AGE_ESTIMATION"]),人脸裁剪图和参考图像也会被存储,并将该人脸添加到应用的人脸搜索索引中(供 Face Search 和重复检测使用)。设为 false 时不会存储任何内容,也无法通过 request_id 查询。
**沙盒:**沙盒 API 密钥会在请求验证后返回静态的 Approved 载荷(age_estimation: 30,无警告);不会保存或计费。
**API 参考:**https://docs.didit.me/standalone-apis/age-estimation **功能指南:**https://docs.didit.me/core-technology/age-estimation/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/age-estimation/
请求头
| 请求头 | 值 | 必需 |
|---|---|---|
x-api-key | 你的 API 密钥 | 是 |
Content-Type | multipart/form-data(由你的 HTTP 客户端设置) | 是 |
请求参数(multipart/form-data)
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
user_image | file | 是 | - | 人脸图像(tiff/jpg/jpeg/png/webp,最大 5 MB) |
age_estimation_decline_threshold | integer | 否 | 18 | 0-100。估算年龄严格低于此值时,会触发 AGE_BELOW_MINIMUM 并拒绝。0 表示禁用年龄检查 |
face_liveness_score_decline_threshold | float | 否 | 30 | 0-100。活体检测 score 小于或等于此值时,会触发 LOW_LIVENESS_SCORE 并拒绝 |
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 f:
response = requests.post(
"https://verification.didit.me/v3/age-estimation/",
headers={"x-api-key": "YOUR_API_KEY"},
files={"user_image": ("selfie.jpg", f, "image/jpeg")},
data={"age_estimation_decline_threshold": "21", "vendor_data": "user-123"},
timeout=60,
)
response.raise_for_status()
result = response.json()["age_estimation"]
print(result["status"], result["age_estimation"], result["score"])
const formData = new FormData();
formData.append("user_image", selfieFile);
formData.append("age_estimation_decline_threshold", "21");
formData.append("vendor_data", "user-123");
const response = await fetch("https://verification.didit.me/v3/age-estimation/", {
method: "POST",
headers: { "x-api-key": "YOUR_API_KEY" },
body: formData,
});
const { age_estimation } = await response.json();
响应(200 OK)
{
"request_id": "0c40ba43-64ab-4e2e-b4b8-7d1f12f81bc1",
"age_estimation": {
"status": "Approved",
"method": "PASSIVE",
"score": 97.5,
"user_image": {
"entities": [
{"age": 27.33, "bbox": [40, 40, 100, 100], "confidence": 0.7177750468254089, "gender": "male"}
],
"best_angle": 0
},
"age_estimation": 27.33,
"warnings": []
},
"vendor_data": "user-123",
"metadata": null,
"created_at": "2026-06-12T02:24:11.512941+00:00"
}
结果对象和估算年龄字段同名:通过 age_estimation.age_estimation 读取年龄。
状态值与处理方式
| 状态 | 含义 | 操作 |
|---|---|---|
"Approved" | 无警告:年龄达到或超过阈值,且活体检测通过 | 继续执行您的流程 |
"Declined" | 至少触发一项警告 | 读取 warnings[].risk(参见警告标签) |
错误响应
| 代码 | 含义 | 操作 |
|---|---|---|
400 | 请求无效(缺少图像、文件超过 5 MB、扩展名不受支持、阈值超出范围) | 查看响应正文中的字段错误 |
400 | {"error": "Invalid user image format."}:扩展名有效,但无法解码文件 | 重新编码图像(JPEG 或 PNG)后重试 |
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 |
age_estimation.status | string | "Approved" 或 "Declined" |
age_estimation.method | string | 始终为 "PASSIVE" |
age_estimation.score | float 或 null | 0-100 的被动活体检测分数。模型未返回置信度时为 null;null 分数按 0 计算,因此会触发 LOW_LIVENESS_SCORE 并拒绝 |
age_estimation.age_estimation | float 或 null | 最大人脸的估算年龄(年),例如 27.33。无法估算年龄时为 null(AGE_NOT_DETECTED) |
age_estimation.user_image.entities[] | array | 每张检测到的人脸对应一条记录:age、bbox [x_min, y_min, x_max, y_max]、confidence(0-1)、gender(仅供参考)。未检测到人脸时为空 |
age_estimation.user_image.best_angle | integer 或 null | 检测效果最佳的旋转角度;仅当 rotate_image=true 且图像得到校正时才非零 |
age_estimation.warnings[] | array | {risk, feature, additional_data, log_type, short_description, long_description}。feature 始终为 LIVENESS,additional_data 始终为 null,log_type 始终为 error |
vendor_data | string 或 null | 原样返回您发送的内容 |
metadata | object 或 null | 原样返回您发送的内容 |
created_at | string | 响应的 ISO 8601 UTC 时间 |
各年龄段的准确度
| 年龄段 | MAE(年) | 置信度 |
|---|---|---|
| 未满 18 岁 | 1.5 | 高 |
| 18-25 岁 | 2.8 | 高 |
| 26-40 岁 | 3.2 | 高 |
| 41-60 岁 | 3.9 | 中高 |
| 60 岁以上 | 4.5 | 中 |
警告标签
此端点的所有警告严重级别均为 error,并会拒绝请求。
| 标签 | 触发条件 |
|---|---|
NO_FACE_DETECTED | 活体检测模型未检测到人脸 |
LOW_LIVENESS_SCORE | 活体检测 score 小于或等于 face_liveness_score_decline_threshold。不会与 NO_FACE_DETECTED 同时触发 |
LIVENESS_FACE_ATTACK | 检测到呈现攻击(照片的照片、屏幕、面具) |
AGE_NOT_DETECTED | 无法估算人脸年龄(age_estimation 为 null) |
AGE_BELOW_MINIMUM | 估算年龄严格小于 age_estimation_decline_threshold。比较的是未舍入的估算值,因此在阈值为 18 时,17.9 会被拒绝 |
此端点不会触发 FACE_IN_BLOCKLIST、POSSIBLE_DUPLICATED_FACE 和 MULTIPLE_FACES_DETECTED;这些标签仅会出现在工作流会话中。
常见工作流
基本年龄门槛
1. Capture the user's selfie
2. POST /v3/age-estimation/ with user_image and age_estimation_decline_threshold=18 (or 21)
3. "Approved" -> estimated age is at or above the threshold and the selfie is live
"Declined" -> check warnings[].risk:
AGE_BELOW_MINIMUM -> under the threshold (see borderline note below)
AGE_NOT_DETECTED / NO_FACE_DETECTED -> ask for a retake: one clear, well-lit face
LOW_LIVENESS_SCORE / LIVENESS_FACE_ATTACK -> possible spoof, do not approve
4. Read the estimate itself at age_estimation.age_estimation
对于接近阈值的估算结果,建议进行证件核验:将临界用户转至 ID 验证(didit-id-document-verification),或使用下方的自适应工作流自动处理。
自适应年龄估算(工作流模式)
仅限工作流:ID 验证回退和按国家/地区设置的限制不适用于 POST /v3/age-estimation/。请创建包含 AGE_ESTIMATION 功能的工作流(参见 didit-verification-management),并让用户通过托管会话完成流程:
- 使用类似以下内容的请求正文调用
POST /v3/workflows/:
{
"workflow_label": "Adaptive Age",
"features": [
{
"feature": "AGE_ESTIMATION",
"config": {
"enable_id_verification_fallback": true,
"minimum_age_threshold": 18,
"borderline_minimum_age_threshold": 16,
"borderline_maximum_age_threshold": 25,
"face_liveness_method": "PASSIVE"
}
}
]
}
- 使用返回的
workflow_id调用POST /v3/session/,并将用户引导至会话 URL。 - 用户拍摄自拍照,系统据此估算年龄(工作流会按整岁比较年龄):
- 启用回退(
enable_id_verification_fallback: true):年龄低于borderline_minimum_age_threshold时会触发AGE_BELOW_MINIMUM并拒绝;处于临界范围内、最高不超过borderline_maximum_age_threshold的年龄,或无法估算年龄时,会继续进行 ID 验证;明确通过的用户则通过自拍照完成验证。 - 关闭回退:无法估算年龄时会触发
AGE_NOT_DETECTED;年龄低于minimum_age_threshold时会触发AGE_BELOW_MINIMUM。
- 启用回退(
- 回退流程启动时,系统会根据按国家/地区设置的年龄限制核验证件上的出生日期,并将证件肖像与年龄估算自拍照进行人脸匹配(结果报告在
face_matches[]中,其中node_id为年龄估算节点;不会作为单独的人脸匹配项目计费)。 GET /v3/session/{sessionId}/decision/:估算结果位于liveness_checks[].age_estimation中。
其他 AGE_ESTIMATION 配置字段:face_liveness_method(ACTIVE_3D = 3D 动作与闪光,安全性最高;FLASHING = 3D 闪光,安全性高;PASSIVE = 单帧,标准)、face_liveness_score_decline_threshold、face_liveness_score_review_threshold。工作流会话还会执行阻止名单和重复人脸筛查。
按国家/地区设置年龄限制(工作流模式)
在 Business Console 中按证件签发国家/地区配置(根据证件匹配州/地区覆盖项),并在工作流核验身份证件时应用,包括自适应回退流程。超出年龄范围时可以拒绝或转入审核。例如:
| 国家/地区 | 最小年龄 | 最大年龄 | 州覆盖项 |
|---|---|---|---|
| USA | 18 | - | Mississippi:21,Alabama:19 |
| KOR | 19 | - | - |
| GBR | 18 | 65 | - |
| ARE | 21 | - | - |
在 Console 中使用“Apply age of majority”按钮填入各国家/地区的法定成年年龄,然后进行调整。
实用脚本
estimate_age.py:通过命令行根据人脸图像估算年龄。--threshold 会作为 age_estimation_decline_threshold 发送,因此年龄判定由 API 本身完成。
# Requires: pip install requests
export DIDIT_API_KEY="your_api_key"
python scripts/estimate_age.py selfie.jpg
python scripts/estimate_age.py photo.png --threshold 21 --vendor-data user-123
python scripts/estimate_age.py photo.png --liveness-threshold 50 --rotate --no-save