curl -X POST 'https://verification.didit.me/v3/face-match/' \
-H 'x-api-key: YOUR_API_KEY' \
-F 'user_image=@./selfie.jpg' \
-F 'ref_image=@./id_portrait.jpg' \
-F 'face_match_score_decline_threshold=50' \
-F 'save_api_request=true' \
-F 'vendor_data=user-123'from didit import Didit
# Reads DIDIT_API_KEY.
client = Didit()
result = client.face_match.compare(
user_image=open("user_image.jpg", "rb"),
ref_image=open("ref_image.jpg", "rb"),
face_match_score_decline_threshold=50.0,
rotate_image=False,
save_api_request=True,
vendor_data="user-123",
metadata={"flow": "login"},
)
print(result)import Didit, { fileFromPath } from "@didit-protocol/sdk-node";
// Reads DIDIT_API_KEY.
const didit = new Didit();
const result = await didit.faceMatch.compare({
user_image: await fileFromPath("user_image.jpg"),
ref_image: await fileFromPath("ref_image.jpg"),
face_match_score_decline_threshold: 50.0,
rotate_image: false,
save_api_request: true,
vendor_data: "user-123",
metadata: { flow: "login" },
});
console.log(result);ctx := context.Background()
// Reads DIDIT_API_KEY.
client := didit.NewClient()
result, err := client.FaceMatch.Compare(ctx, didit.FaceMatchCompareParams{
UserImage: didit.FileFromPath("user_image.jpg"),
RefImage: didit.FileFromPath("ref_image.jpg"),
FaceMatchScoreDeclineThreshold: didit.Float(50.0),
RotateImage: didit.Bool(false),
SaveAPIRequest: didit.Bool(true),
VendorData: didit.String("user-123"),
Metadata: didit.Some(map[string]any{"flow": "login"}),
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("%+v\n", result)import java.nio.file.Path;
import java.util.Map;
import me.didit.Didit;
import me.didit.types.FaceMatchCompareParams;
// Reads DIDIT_API_KEY.
Didit client = new Didit();
var result = client.faceMatch().compare(FaceMatchCompareParams.builder()
.userImage(Path.of("user_image.jpg"))
.refImage(Path.of("ref_image.jpg"))
.faceMatchScoreDeclineThreshold(50.0)
.rotateImage(false)
.saveApiRequest(true)
.vendorData("user-123")
.metadata(Map.of("flow", "login"))
.build());
System.out.println(result);<?php
require 'vendor/autoload.php';
use Didit\DiditClient;
use Didit\File;
// Reads DIDIT_API_KEY.
$didit = new DiditClient();
$result = $didit->faceMatch->compare([
'user_image' => File::fromPath('user_image.jpg'),
'ref_image' => File::fromPath('ref_image.jpg'),
'face_match_score_decline_threshold' => 50.0,
'rotate_image' => false,
'save_api_request' => true,
'vendor_data' => 'user-123',
'metadata' => ['flow' => 'login'],
]);
print_r($result->toArray());require "didit"
# Reads DIDIT_API_KEY.
didit = Didit::Client.new
result = didit.face_match.compare(
user_image: Pathname("user_image.jpg"),
ref_image: Pathname("ref_image.jpg"),
face_match_score_decline_threshold: 50.0,
rotate_image: false,
save_api_request: true,
vendor_data: "user-123",
metadata: { flow: "login" }
)
puts result.to_husing System;
using System.Collections.Generic;
using System.Text.Json;
using Didit;
// Reads DIDIT_API_KEY.
using var client = new DiditClient();
var result = await client.FaceMatch.CompareAsync(new FaceMatchCompareParams
{
UserImage = FileUpload.FromPath("user_image.jpg"),
RefImage = FileUpload.FromPath("ref_image.jpg"),
FaceMatchScoreDeclineThreshold = 50.0,
RotateImage = false,
SaveApiRequest = true,
VendorData = "user-123",
Metadata = new Dictionary<string, object> { ["flow"] = "login" },
});
Console.WriteLine(JsonSerializer.Serialize(result));{
"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",
"race": null
}
],
"best_angle": 0
},
"ref_image": {
"entities": [
{
"bbox": [
653,
745,
1691,
2185
],
"confidence": 0.722082,
"age": 27,
"gender": "male",
"race": null
}
],
"best_angle": 0
},
"warnings": []
},
"vendor_data": "user-123",
"metadata": {
"flow": "login"
},
"created_at": "2026-06-12T01:04:42.763237+00:00"
}人脸比对 API:1:1 人脸比对
Didit 提供 1:1 人脸比对接口 POST /v3/face-match/,适用于身份验证、门禁控制和重新验证。推理耗时低于2s,按次计费,无月度最低消费。
curl -X POST 'https://verification.didit.me/v3/face-match/' \
-H 'x-api-key: YOUR_API_KEY' \
-F 'user_image=@./selfie.jpg' \
-F 'ref_image=@./id_portrait.jpg' \
-F 'face_match_score_decline_threshold=50' \
-F 'save_api_request=true' \
-F 'vendor_data=user-123'from didit import Didit
# Reads DIDIT_API_KEY.
client = Didit()
result = client.face_match.compare(
user_image=open("user_image.jpg", "rb"),
ref_image=open("ref_image.jpg", "rb"),
face_match_score_decline_threshold=50.0,
rotate_image=False,
save_api_request=True,
vendor_data="user-123",
metadata={"flow": "login"},
)
print(result)import Didit, { fileFromPath } from "@didit-protocol/sdk-node";
// Reads DIDIT_API_KEY.
const didit = new Didit();
const result = await didit.faceMatch.compare({
user_image: await fileFromPath("user_image.jpg"),
ref_image: await fileFromPath("ref_image.jpg"),
face_match_score_decline_threshold: 50.0,
rotate_image: false,
save_api_request: true,
vendor_data: "user-123",
metadata: { flow: "login" },
});
console.log(result);ctx := context.Background()
// Reads DIDIT_API_KEY.
client := didit.NewClient()
result, err := client.FaceMatch.Compare(ctx, didit.FaceMatchCompareParams{
UserImage: didit.FileFromPath("user_image.jpg"),
RefImage: didit.FileFromPath("ref_image.jpg"),
FaceMatchScoreDeclineThreshold: didit.Float(50.0),
RotateImage: didit.Bool(false),
SaveAPIRequest: didit.Bool(true),
VendorData: didit.String("user-123"),
Metadata: didit.Some(map[string]any{"flow": "login"}),
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("%+v\n", result)import java.nio.file.Path;
import java.util.Map;
import me.didit.Didit;
import me.didit.types.FaceMatchCompareParams;
// Reads DIDIT_API_KEY.
Didit client = new Didit();
var result = client.faceMatch().compare(FaceMatchCompareParams.builder()
.userImage(Path.of("user_image.jpg"))
.refImage(Path.of("ref_image.jpg"))
.faceMatchScoreDeclineThreshold(50.0)
.rotateImage(false)
.saveApiRequest(true)
.vendorData("user-123")
.metadata(Map.of("flow", "login"))
.build());
System.out.println(result);<?php
require 'vendor/autoload.php';
use Didit\DiditClient;
use Didit\File;
// Reads DIDIT_API_KEY.
$didit = new DiditClient();
$result = $didit->faceMatch->compare([
'user_image' => File::fromPath('user_image.jpg'),
'ref_image' => File::fromPath('ref_image.jpg'),
'face_match_score_decline_threshold' => 50.0,
'rotate_image' => false,
'save_api_request' => true,
'vendor_data' => 'user-123',
'metadata' => ['flow' => 'login'],
]);
print_r($result->toArray());require "didit"
# Reads DIDIT_API_KEY.
didit = Didit::Client.new
result = didit.face_match.compare(
user_image: Pathname("user_image.jpg"),
ref_image: Pathname("ref_image.jpg"),
face_match_score_decline_threshold: 50.0,
rotate_image: false,
save_api_request: true,
vendor_data: "user-123",
metadata: { flow: "login" }
)
puts result.to_husing System;
using System.Collections.Generic;
using System.Text.Json;
using Didit;
// Reads DIDIT_API_KEY.
using var client = new DiditClient();
var result = await client.FaceMatch.CompareAsync(new FaceMatchCompareParams
{
UserImage = FileUpload.FromPath("user_image.jpg"),
RefImage = FileUpload.FromPath("ref_image.jpg"),
FaceMatchScoreDeclineThreshold = 50.0,
RotateImage = false,
SaveApiRequest = true,
VendorData = "user-123",
Metadata = new Dictionary<string, object> { ["flow"] = "login" },
});
Console.WriteLine(JsonSerializer.Serialize(result));{
"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",
"race": null
}
],
"best_angle": 0
},
"ref_image": {
"entities": [
{
"bbox": [
653,
745,
1691,
2185
],
"confidence": 0.722082,
"age": 27,
"gender": "male",
"race": null
}
],
"best_angle": 0
},
"warnings": []
},
"vendor_data": "user-123",
"metadata": {
"flow": "login"
},
"created_at": "2026-06-12T01:04:42.763237+00:00"
}授权
您的应用 API 密钥,可在 Business Console 的“开发者 -> API 密钥”中获取。主密钥拥有完整访问权限。指定名称的密钥可设置作用域:针对每个资源设为无权限、只读或读写,限定于特定工作流或已通过的会话、限定于 IP 地址列表,以及设置到期日期。401 表示密钥错误、已撤销或已过期;403 表示未发送密钥、密钥无权访问该资源或操作,或请求来自其 IP 列表之外的地址;在会话路由上返回 404 表示该会话不在该密钥允许的工作流或状态范围内。没有媒体访问权限的密钥获取到的图片、视频和 PDF URL 将为 null;没有会话写入权限的密钥获取到的会话链接和 token 将为 null。请参阅 https://docs.didit.me/console/api-keys。
请求体
待验证的真人或候选人脸图像(例如自拍照)。请提交一张主体面部清晰可见且光线充足的正脸照片。允许的扩展名:tiff、jpg、jpeg、png、webp。最大上传大小:5 MB(超出限制的文件将被拒绝并返回 400)。图像在处理前会自动压缩至约 0.5 MB,因此极高分辨率并不会提高准确度。
用于比对的参考人脸图像(例如身份证件人像照或先前登记的照片)。格式和大小限制与 user_image 相同。
决定响应 status 的相似度阈值(0–100)。计算得出的分数小于或等于此值会将 status 设置为 Declined 并添加 LOW_FACE_MATCH_SIMILARITY 警告;严格高于此分数则返回 Approved。默认值 30 较为宽松,如需更严格的验证,可调高该值(例如 50–60)。超出 0–100 范围的值将返回 400。
0 <= x <= 10050
为 true 时,服务会按 90 度递增(0、90、180、270)尝试输入图像,并使用人脸检测效果最佳的方向,这对于缺少 EXIF 方向信息的移动设备拍摄非常有用。这会增加延迟,因此仅在您无法保证图像为正向时启用。
false
为 true(默认)时,将此次调用持久化为 API 类型的会话,在 Business Console 中可见,可使用返回的 request_id 通过 GET /v3/session/{sessionId}/decision/ 检索,并通过 status.updated Webhook 发出通知。为 false 时,不存储任何内容,且 request_id 仅为用于关联响应的临时 UUID。
true
可选的不透明字符串(您的内部用户 ID、邮箱、UUID 等),存储在持久化会话中并在响应中回显。可用于将 API 调用与您自己的记录相关联,并在稍后筛选会话。
"user-123"
与会话一同存储(当 save_api_request=true 时)并在响应中原样返回的可选 JSON 对象。在 multipart 请求中,请将其作为 JSON 编码的字符串字段发送(例如 metadata={"flow":"login"}),它将被解析为对象。
{ "flow": "login", "device_id": "abc123" }
响应
人脸比对已计算。face_match.score 为 0–100 的浮点数(保留两位小数);当分数严格高于 face_match_score_decline_threshold 时,status 为 Approved,否则为 Declined 并附带说明性警告。相似度较低或无法评分的人脸对仍会返回 200,请检查 face_match.status 和 face_match.warnings,而不仅仅是 HTTP 状态码。当 save_api_request=true 时,request_id 为持久化的会话 ID。
当 save_api_request=true 时持久化的会话 ID(可用于 GET /v3/session/{sessionId}/decision/);否则为一个临时的关联 UUID。
Show child attributes
Show child attributes
您发送的 vendor_data 回显,或 null。
您发送的 metadata 对象回显,或 null。
响应生成时的 ISO 8601 时间戳(UTC),例如 2026-06-12T01:04:42.763237+00:00。