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 に圧縮されます)
- 鮮明で正面を向き、明るく撮影された顔が 1 つ。検出された顔のうち最大のものが
age_estimationの判定対象になります - 精度:全体の平均絶対誤差(MAE)は 3.5 歳、18 歳未満では 1.5 歳です(下の表を参照)
料金: 0.10 ドル(呼び出し成功 1 回あたり。単独の呼び出しに無料枠はありません)。この料金は 2026 年 11 月 1 日までの表示価格です。同日、Didit の料金が変更され、月 500 回の無料チェックは月 10 ドル分の無料クレジットに切り替わります。最新の料金は didit.me/pricing をご確認ください。
判定: 警告が1 つでもあると却下されます。warnings が空の場合に限り、status は Approved になります。このエンドポイントに In Review はありません。method は常に PASSIVE です。
このエンドポイントで利用できない機能: ブロックリストおよび顔の重複チェック、MULTIPLE_FACES_DETECTED、年齢が境界に近い場合の ID 確認へのフォールバック、国ごとの年齢制限。これらはワークフロー機能です(適応型年齢推定を参照)。
保存(save_api_request、デフォルトは true): 呼び出しは API セッションとして保存されます(Business Console、status.updated Webhook、および GET /v3/session/{request_id}/decision/ を利用でき、結果は features: ["AGE_ESTIMATION"] を含む liveness_checks[] に表示されます)。顔の切り抜き画像と参照画像が保存され、顔はアプリケーションの顔検索インデックスに追加されます(顔検索および重複検出で使用)。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 呼び出しで作成できます。
- 登録:
POST https://apx.didit.me/auth/v2/programmatic/register/に{"email": "[email protected]", "password": "MyStr0ng!Pass"}を指定します - メールを確認: 6 文字の確認コードを確認します
- 確認:
POST https://apx.didit.me/auth/v2/programmatic/verify-email/に{"email": "[email protected]", "code": "A3K9F2"}を指定します。キーはレスポンスのapplication.api_keyにあります。
クレジットの追加: 残高を確認するには GET /v3/billing/balance/ を使用します。Stripe のチェックアウトリンクを取得するには、{"amount_in_dollars": 50} を指定して POST /v3/billing/top-up/ を呼び出します。
プラットフォーム管理(ワークフロー、セッション、ユーザー、請求)の詳細については、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 | ファイル | はい | - | 顔画像(tiff/jpg/jpeg/png/webp、最大 5 MB) |
age_estimation_decline_threshold | 整数 | いいえ | 18 | 0~100。推定年齢がこの値を厳密に下回る場合、AGE_BELOW_MINIMUM が発生し、拒否されます。0 にすると年齢チェックが無効になります |
face_liveness_score_decline_threshold | 浮動小数点数 | いいえ | 30 | 0~100。ライブネスの score がこの値以下の場合、LOW_LIVENESS_SCORE が発生し、拒否されます |
rotate_image | 真偽値 | いいえ | false | 0/90/180/270 度を試し、顔検出の結果が最も良い向きを使用します。レイテンシーが増加します |
save_api_request | 真偽値 | いいえ | true | API セッションとして保存し、顔を顔検索インデックスに追加します(「概要」を参照) |
vendor_data | 文字列 | いいえ | - | ユーザー識別子。保存され、レスポンスに返されます |
metadata | JSON オブジェクト | いいえ | - | セッションとともに保存され(保存する場合)、レスポンスに返されます。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" | 1 つ以上の警告が発生 | 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 | レート制限:キーごとに 1 分あたり POST/PATCH/DELETE リクエスト 300 件、GET リクエスト 600 件 | Retry-After の秒数だけ待ってから再試行します |
レスポンスフィールドリファレンス
| フィールド | 型 | 説明 |
|---|---|---|
request_id | uuid | save_api_request=true の場合はセッション ID(GET /v3/session/{request_id}/decision/ で使用)。それ以外の場合は単発の相関 ID |
age_estimation.status | 文字列 | "Approved" または "Declined" |
age_estimation.method | 文字列 | 常に "PASSIVE" |
age_estimation.score | 浮動小数点数または null | パッシブライブネススコア(0~100)。モデルが信頼度を返さない場合は null です。null のスコアは 0 として扱われるため、LOW_LIVENESS_SCORE により拒否されます |
age_estimation.age_estimation | 浮動小数点数または null | 最も大きい顔の推定年齢(年単位、例:27.33)。年齢を推定できなかった場合(AGE_NOT_DETECTED)は null です |
age_estimation.user_image.entities[] | 配列 | 検出された顔ごとに 1 つのエントリー:age、bbox [x_min, y_min, x_max, y_max]、confidence(0~1)、gender(参考情報)。顔が見つからなかった場合は空です |
age_estimation.user_image.best_angle | 整数または null | 最良の検出結果が得られた回転角度。rotate_image=true によって補正された場合のみ 0 以外になります |
age_estimation.warnings[] | 配列 | {risk, feature, additional_data, log_type, short_description, long_description}。feature は常に LIVENESS、additional_data は常に null、log_type は常に error です |
vendor_data | 文字列または null | 送信した値が返されます |
metadata | オブジェクトまたは null | 送信した値が返されます |
created_at | 文字列 | レスポンスの 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とともに報告され、独立した Face Match として課金されることはありません)。 GET /v3/session/{sessionId}/decision/:推定値はliveness_checks[].age_estimationに含まれます。
その他の AGE_ESTIMATION 設定フィールド:face_liveness_method(ACTIVE_3D = 3D Action & Flash、最高レベルのセキュリティ、FLASHING = 3D Flash、高、PASSIVE = 単一フレーム、標準)、face_liveness_score_decline_threshold、face_liveness_score_review_threshold。ワークフローセッションでは、ブロックリストと重複顔のスクリーニングも実行されます。
国別の年齢制限(ワークフローモード)
Business Console で書類の発行国ごとに設定します(州や地域の上書き設定は書類から照合されます)。ワークフローが ID 書類を検証する際に適用され、適応型フォールバックも対象となります。範囲外の年齢は拒否または審査にできます。例:
| 国 | 最低年齢 | 最高年齢 | 州の上書き設定 |
|---|---|---|---|
| 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