curl -X POST 'https://verification.didit.me/v3/id-verification/' \
-H 'x-api-key: YOUR_API_KEY' \
-F 'front_image=@./id_front.jpg' \
-F 'back_image=@./id_back.jpg' \
-F 'perform_document_liveness=true' \
-F 'save_api_request=true' \
-F 'vendor_data=user-123'from didit import Didit
# Reads DIDIT_API_KEY.
client = Didit()
result = client.id_verification.verify(
front_image=open("front_image.jpg", "rb"),
back_image=open("back_image.jpg", "rb"),
perform_document_liveness=True,
save_api_request=True,
vendor_data="user-123",
metadata={"flow": "onboarding"},
)
print(result)import Didit, { fileFromPath } from "@didit-protocol/sdk-node";
// Reads DIDIT_API_KEY.
const didit = new Didit();
const result = await didit.idVerification.verify({
front_image: await fileFromPath("front_image.jpg"),
back_image: await fileFromPath("back_image.jpg"),
perform_document_liveness: true,
save_api_request: true,
vendor_data: "user-123",
metadata: { flow: "onboarding" },
});
console.log(result);ctx := context.Background()
// Reads DIDIT_API_KEY.
client := didit.NewClient()
result, err := client.IDVerification.Verify(ctx, didit.IDVerificationVerifyParams{
FrontImage: didit.FileFromPath("front_image.jpg"),
BackImage: didit.Some(didit.FileFromPath("back_image.jpg")),
PerformDocumentLiveness: didit.Bool(true),
SaveAPIRequest: didit.Bool(true),
VendorData: didit.String("user-123"),
Metadata: didit.Some(map[string]any{"flow": "onboarding"}),
})
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.IdVerificationVerifyParams;
// Reads DIDIT_API_KEY.
Didit client = new Didit();
var result = client.idVerification().verify(IdVerificationVerifyParams.builder()
.frontImage(Path.of("front_image.jpg"))
.backImage(Path.of("back_image.jpg"))
.performDocumentLiveness(true)
.saveApiRequest(true)
.vendorData("user-123")
.metadata(Map.of("flow", "onboarding"))
.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->idVerification->verify([
'front_image' => File::fromPath('front_image.jpg'),
'back_image' => File::fromPath('back_image.jpg'),
'perform_document_liveness' => true,
'save_api_request' => true,
'vendor_data' => 'user-123',
'metadata' => ['flow' => 'onboarding'],
]);
print_r($result->toArray());require "didit"
# Reads DIDIT_API_KEY.
didit = Didit::Client.new
result = didit.id_verification.verify(
front_image: Pathname("front_image.jpg"),
back_image: Pathname("back_image.jpg"),
perform_document_liveness: true,
save_api_request: true,
vendor_data: "user-123",
metadata: { flow: "onboarding" }
)
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.IdVerification.VerifyAsync(new IdVerificationVerifyParams
{
FrontImage = FileUpload.FromPath("front_image.jpg"),
BackImage = FileUpload.FromPath("back_image.jpg"),
PerformDocumentLiveness = true,
SaveApiRequest = true,
VendorData = "user-123",
Metadata = new Dictionary<string, object> { ["flow"] = "onboarding" },
});
Console.WriteLine(JsonSerializer.Serialize(result));{
"request_id": "11d219ed-d59c-4b1d-8d65-9b933f12d5b8",
"id_verification": {
"status": "Approved",
"document_type": "Identity Card",
"document_subtype": "ID_CARD_GENERIC",
"document_number": "CBX164224",
"personal_number": "20446581H",
"portrait_image": "https://<media-host>/ocr/11d219ed-d59c-4b1d-8d65-9b933f12d5b8-portrait_image-8c2f.jpg?signature=...",
"front_image": "https://<media-host>/ocr/11d219ed-d59c-4b1d-8d65-9b933f12d5b8-front_image-4a1e.jpg?signature=...",
"back_image": "https://<media-host>/ocr/11d219ed-d59c-4b1d-8d65-9b933f12d5b8-back_image-77b0.jpg?signature=...",
"front_image_camera_front": null,
"back_image_camera_front": null,
"front_image_camera_front_face_match_score": null,
"back_image_camera_front_face_match_score": null,
"front_image_quality_score": {
"focus_score": 78,
"brightness_score": 83.2,
"brightness_issue": "ok",
"is_document_fully_visible": true,
"resolution_score": 40.7,
"overall_score": 70.2
},
"back_image_quality_score": {
"focus_score": 100,
"brightness_score": 95.6,
"brightness_issue": "ok",
"is_document_fully_visible": true,
"resolution_score": 43,
"overall_score": 84.4
},
"date_of_birth": "1980-01-13",
"age": 46,
"expiration_date": "2032-03-31",
"date_of_issue": "2022-03-31",
"issuing_state": "ESP",
"issuing_state_name": "Spain",
"first_name": "Julio Francisco",
"last_name": "Fores Sena",
"full_name": "Julio Francisco Fores Sena",
"gender": "M",
"address": "Brda. Urb. El Cardonal 0052 52 Po3 B,Taco,San Cristobal De La Laguna,Santa Cruz De Tenerife",
"formatted_address": "Av. el Cardonal, 52, b, 38108 La Laguna, Santa Cruz de Tenerife, Spain",
"place_of_birth": "Valencia, Valencia",
"marital_status": "UNKNOWN",
"nationality": "ESP",
"extra_fields": {
"first_surname": "Fores",
"second_surname": "Sena"
},
"mrz": {
"surname": "FORES SENA",
"name": "JULIO FRANCISCO",
"country": "ESP",
"nationality": "ESP",
"birth_date": "800113",
"expiry_date": "320331",
"sex": "M",
"document_type": "ID",
"document_number": "CBX164224",
"optional_data": "20446581H",
"optional_data_2": "",
"birth_date_hash": "9",
"expiry_date_hash": "8",
"document_number_hash": "3",
"final_hash": "3",
"personal_number": "20446581H",
"warnings": [],
"errors": [],
"mrz_type": "TD1",
"mrz_string": "IDESPCBX164224320446581H<<<<<<\n8001139M3203318ESP<<<<<<<<<<<3\nFORES<SENA<<JULIO<FRANCISCO<<<",
"mrz_key": "CBX164224380011393203318"
},
"parsed_address": {
"street_1": "Avenida el Cardonal 52",
"street_2": "b",
"city": "La Laguna",
"region": "Canarias",
"country": "ES",
"postal_code": "38108",
"address_type": "Avenida",
"formatted_address": "Av. el Cardonal, 52, b, 38108 La Laguna, Santa Cruz de Tenerife, Spain",
"raw_results": {
"address_components": [
{
"long_name": "b",
"short_name": "b",
"types": [
"subpremise"
]
},
{
"long_name": "52",
"short_name": "52",
"types": [
"street_number"
]
},
{
"long_name": "Avenida el Cardonal",
"short_name": "Av. el Cardonal",
"types": [
"route"
]
},
{
"long_name": "La Laguna",
"short_name": "La Laguna",
"types": [
"locality",
"political"
]
},
{
"long_name": "Spain",
"short_name": "ES",
"types": [
"country",
"political"
]
},
{
"long_name": "38108",
"short_name": "38108",
"types": [
"postal_code"
]
}
],
"formatted_address": "Av. el Cardonal, 52, b, 38108 La Laguna, Santa Cruz de Tenerife, Spain",
"geometry": {
"location": {
"lat": 28.4501161,
"lng": -16.3004407
},
"location_type": "ROOFTOP"
},
"types": [
"street_address",
"subpremise"
]
},
"document_location": {
"latitude": 28.4501161,
"longitude": -16.3004407
},
"label": "Spain Identity Card Address",
"is_verified": true,
"category": "Residential"
},
"warnings": [],
"barcodes": []
},
"vendor_data": "user-123",
"metadata": {
"flow": "onboarding"
},
"created_at": "2026-06-12T02:21:56.013573+00:00"
}身份证件验证 API:证件 OCR 与真伪鉴别
Didit 支持 220+ 国家和地区、14,000+ 种证件的身份验证,涵盖真伪鉴别、OCR、MRZ,推理耗时低于 2 秒,按量付费,无需签订合同。
curl -X POST 'https://verification.didit.me/v3/id-verification/' \
-H 'x-api-key: YOUR_API_KEY' \
-F 'front_image=@./id_front.jpg' \
-F 'back_image=@./id_back.jpg' \
-F 'perform_document_liveness=true' \
-F 'save_api_request=true' \
-F 'vendor_data=user-123'from didit import Didit
# Reads DIDIT_API_KEY.
client = Didit()
result = client.id_verification.verify(
front_image=open("front_image.jpg", "rb"),
back_image=open("back_image.jpg", "rb"),
perform_document_liveness=True,
save_api_request=True,
vendor_data="user-123",
metadata={"flow": "onboarding"},
)
print(result)import Didit, { fileFromPath } from "@didit-protocol/sdk-node";
// Reads DIDIT_API_KEY.
const didit = new Didit();
const result = await didit.idVerification.verify({
front_image: await fileFromPath("front_image.jpg"),
back_image: await fileFromPath("back_image.jpg"),
perform_document_liveness: true,
save_api_request: true,
vendor_data: "user-123",
metadata: { flow: "onboarding" },
});
console.log(result);ctx := context.Background()
// Reads DIDIT_API_KEY.
client := didit.NewClient()
result, err := client.IDVerification.Verify(ctx, didit.IDVerificationVerifyParams{
FrontImage: didit.FileFromPath("front_image.jpg"),
BackImage: didit.Some(didit.FileFromPath("back_image.jpg")),
PerformDocumentLiveness: didit.Bool(true),
SaveAPIRequest: didit.Bool(true),
VendorData: didit.String("user-123"),
Metadata: didit.Some(map[string]any{"flow": "onboarding"}),
})
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.IdVerificationVerifyParams;
// Reads DIDIT_API_KEY.
Didit client = new Didit();
var result = client.idVerification().verify(IdVerificationVerifyParams.builder()
.frontImage(Path.of("front_image.jpg"))
.backImage(Path.of("back_image.jpg"))
.performDocumentLiveness(true)
.saveApiRequest(true)
.vendorData("user-123")
.metadata(Map.of("flow", "onboarding"))
.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->idVerification->verify([
'front_image' => File::fromPath('front_image.jpg'),
'back_image' => File::fromPath('back_image.jpg'),
'perform_document_liveness' => true,
'save_api_request' => true,
'vendor_data' => 'user-123',
'metadata' => ['flow' => 'onboarding'],
]);
print_r($result->toArray());require "didit"
# Reads DIDIT_API_KEY.
didit = Didit::Client.new
result = didit.id_verification.verify(
front_image: Pathname("front_image.jpg"),
back_image: Pathname("back_image.jpg"),
perform_document_liveness: true,
save_api_request: true,
vendor_data: "user-123",
metadata: { flow: "onboarding" }
)
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.IdVerification.VerifyAsync(new IdVerificationVerifyParams
{
FrontImage = FileUpload.FromPath("front_image.jpg"),
BackImage = FileUpload.FromPath("back_image.jpg"),
PerformDocumentLiveness = true,
SaveApiRequest = true,
VendorData = "user-123",
Metadata = new Dictionary<string, object> { ["flow"] = "onboarding" },
});
Console.WriteLine(JsonSerializer.Serialize(result));{
"request_id": "11d219ed-d59c-4b1d-8d65-9b933f12d5b8",
"id_verification": {
"status": "Approved",
"document_type": "Identity Card",
"document_subtype": "ID_CARD_GENERIC",
"document_number": "CBX164224",
"personal_number": "20446581H",
"portrait_image": "https://<media-host>/ocr/11d219ed-d59c-4b1d-8d65-9b933f12d5b8-portrait_image-8c2f.jpg?signature=...",
"front_image": "https://<media-host>/ocr/11d219ed-d59c-4b1d-8d65-9b933f12d5b8-front_image-4a1e.jpg?signature=...",
"back_image": "https://<media-host>/ocr/11d219ed-d59c-4b1d-8d65-9b933f12d5b8-back_image-77b0.jpg?signature=...",
"front_image_camera_front": null,
"back_image_camera_front": null,
"front_image_camera_front_face_match_score": null,
"back_image_camera_front_face_match_score": null,
"front_image_quality_score": {
"focus_score": 78,
"brightness_score": 83.2,
"brightness_issue": "ok",
"is_document_fully_visible": true,
"resolution_score": 40.7,
"overall_score": 70.2
},
"back_image_quality_score": {
"focus_score": 100,
"brightness_score": 95.6,
"brightness_issue": "ok",
"is_document_fully_visible": true,
"resolution_score": 43,
"overall_score": 84.4
},
"date_of_birth": "1980-01-13",
"age": 46,
"expiration_date": "2032-03-31",
"date_of_issue": "2022-03-31",
"issuing_state": "ESP",
"issuing_state_name": "Spain",
"first_name": "Julio Francisco",
"last_name": "Fores Sena",
"full_name": "Julio Francisco Fores Sena",
"gender": "M",
"address": "Brda. Urb. El Cardonal 0052 52 Po3 B,Taco,San Cristobal De La Laguna,Santa Cruz De Tenerife",
"formatted_address": "Av. el Cardonal, 52, b, 38108 La Laguna, Santa Cruz de Tenerife, Spain",
"place_of_birth": "Valencia, Valencia",
"marital_status": "UNKNOWN",
"nationality": "ESP",
"extra_fields": {
"first_surname": "Fores",
"second_surname": "Sena"
},
"mrz": {
"surname": "FORES SENA",
"name": "JULIO FRANCISCO",
"country": "ESP",
"nationality": "ESP",
"birth_date": "800113",
"expiry_date": "320331",
"sex": "M",
"document_type": "ID",
"document_number": "CBX164224",
"optional_data": "20446581H",
"optional_data_2": "",
"birth_date_hash": "9",
"expiry_date_hash": "8",
"document_number_hash": "3",
"final_hash": "3",
"personal_number": "20446581H",
"warnings": [],
"errors": [],
"mrz_type": "TD1",
"mrz_string": "IDESPCBX164224320446581H<<<<<<\n8001139M3203318ESP<<<<<<<<<<<3\nFORES<SENA<<JULIO<FRANCISCO<<<",
"mrz_key": "CBX164224380011393203318"
},
"parsed_address": {
"street_1": "Avenida el Cardonal 52",
"street_2": "b",
"city": "La Laguna",
"region": "Canarias",
"country": "ES",
"postal_code": "38108",
"address_type": "Avenida",
"formatted_address": "Av. el Cardonal, 52, b, 38108 La Laguna, Santa Cruz de Tenerife, Spain",
"raw_results": {
"address_components": [
{
"long_name": "b",
"short_name": "b",
"types": [
"subpremise"
]
},
{
"long_name": "52",
"short_name": "52",
"types": [
"street_number"
]
},
{
"long_name": "Avenida el Cardonal",
"short_name": "Av. el Cardonal",
"types": [
"route"
]
},
{
"long_name": "La Laguna",
"short_name": "La Laguna",
"types": [
"locality",
"political"
]
},
{
"long_name": "Spain",
"short_name": "ES",
"types": [
"country",
"political"
]
},
{
"long_name": "38108",
"short_name": "38108",
"types": [
"postal_code"
]
}
],
"formatted_address": "Av. el Cardonal, 52, b, 38108 La Laguna, Santa Cruz de Tenerife, Spain",
"geometry": {
"location": {
"lat": 28.4501161,
"lng": -16.3004407
},
"location_type": "ROOFTOP"
},
"types": [
"street_address",
"subpremise"
]
},
"document_location": {
"latitude": 28.4501161,
"longitude": -16.3004407
},
"label": "Spain Identity Card Address",
"is_verified": true,
"category": "Residential"
},
"warnings": [],
"barcodes": []
},
"vendor_data": "user-123",
"metadata": {
"flow": "onboarding"
},
"created_at": "2026-06-12T02:21:56.013573+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、pdf。最大上传大小:10 MB(超出限制的文件将被拒绝并返回 400)。PDF 在进行 OCR 之前会渲染为图像;加密的 PDF 需要提供 front_image_password。图像会自动压缩至约 0.5 MB 并应用 EXIF 方向矫正。请上传完整、未裁剪且证件四角均可见的拍摄件。
当 front_image 为加密 PDF 时用于解密的密码。发送未附带(或附带错误)密码的加密 PDF 将返回 400。
证件背面:证件有背面时请务必发送(许多身份证件在背面带有 MRZ 或条形码;省略背面仅会在响应中使 MRZ 和背面字段保持为空,此 endpoint 不会触发缺少 MRZ 的警告)。格式和大小限制与 front_image 相同。省略时,响应中的 back_image 和背面字段为 null。
当 back_image 为加密 PDF 时用于解密的密码。
对两张图像进行呈现欺诈筛查:屏幕重放(SCREEN_CAPTURE_DETECTED)、打印副本(PRINTED_COPY_DETECTED)以及肖像篡改(PORTRAIT_MANIPULATION_DETECTED)。出现上述任何一种情况都会自动拒绝。默认启用;设置为 false 可跳过欺诈筛查并减少延迟。启用后,若提供商未返回可用评分,响应结果为包含 DOCUMENT_LIVENESS_NOT_COMPUTED 警告的 In Review,而非 Approved。
true
已接受并验证(1–120),但目前未被此 endpoint 应用,绝不会因该字段生成 MINIMUM_AGE_NOT_MET 警告。请根据返回的 date_of_birth/age 执行年龄规则,或使用带有年龄限制的验证会话工作流。
1 <= x <= 120当无法读取到期日期时的处理操作(EXPIRATION_DATE_NOT_DETECTED)。默认为 NO_ACTION,因为许多证件上并未印有到期日期。注意:无论此选项如何设置,已检测到且已过期的到期日期始终会导致拒绝(DOCUMENT_EXPIRED)。
NO_ACTION, DECLINE 当提取的 MRZ 未通过校验位验证(MRZ_VALIDATION_FAILED)时采取的操作。在此 endpoint 上,缺少 MRZ 不会触发警告。仅适用于带有 MRZ 的证件。此 endpoint 不支持 REVIEW,并会返回 400。
NO_ACTION, DECLINE 当提取的数据存在内部不一致时的处理操作:DATA_INCONSISTENT、MRZ_AND_DATA_EXTRACTED_FROM_OCR_NOT_SAME(目视区与 MRZ 不一致)或 DOCUMENT_NAME_DIFFERENT_FROM_OTHER_APPROVED_DOCUMENTS。
NO_ACTION, DECLINE 当拍摄时关键打印字段(身份证件号码、姓名、出生日期或到期日期)被物理遮挡(CRITICAL_FIELD_OCCLUSION_DETECTED)时的处理操作。默认拒绝,与该 endpoint 的其他证件完整性风险相同:遮挡报告核对所需的号码属于涂抹证件的表现。无论哪种方式,被遮挡字段读取到的值都会从提取结果中丢弃,因此通常会伴随相应的 *_NOT_DETECTED 警告。该 endpoint 不支持 REVIEW 并会返回 400。
NO_ACTION, DECLINE 当号码不符合其签发机构针对该证件类型所使用的格式(DOCUMENT_NUMBER_FORMAT_MISMATCH、PERSONAL_NUMBER_FORMAT_MISMATCH)时的处理操作。默认为 NO_ACTION,即报告警告而不改变状态。该 endpoint 不支持 REVIEW 并会返回 400。
NO_ACTION, DECLINE 印有拉丁和非拉丁文本(阿拉伯语、西里尔字母、中日韩字符等)的证件上姓名/地址字段的首选文字系统。latin 返回音译/拉丁值;non_latin 优先返回原生文字系统。
latin, non_latin 为 true(默认)时,将此次调用持久化为 API 类型的会话,在 Business Console 中可见,可使用返回的 request_id 通过 GET /v3/session/{sessionId}/decision/ 检索,通过 status.updated Webhook 发出通知,并将证件图像作为媒体 URL 返回。为 false 时,不存储任何内容,request_id 为临时 UUID,且图像以 base64 JPEG 字符串形式内联返回。
true
可选的不透明字符串(您的内部用户 ID、邮箱、UUID 等),存储在持久化会话中并在响应中回显。可用于将 API 调用与您自己的记录相关联,并在稍后筛选会话。
"user-123"
与会话一同存储(当 save_api_request=true 时)并在响应中原样返回的可选 JSON 对象。在 multipart 请求中,请将其作为 JSON 编码的字符串字段发送(例如 metadata={"flow":"onboarding"}),它将被解析为对象。
{ "flow": "onboarding" }
响应
证件已处理。id_verification.status 为 Approved、Declined 或 In Review;检测到的每个问题都在 id_verification.warnings 中逐项列出。当所请求的证件活体检查未产生可用结果时返回 In Review(DOCUMENT_LIVENESS_NOT_COMPUTED)。有问题的证件仍会返回 200 并附带 status: "Declined" — 请检查响应体,而不仅仅是 HTTP 状态码。当 save_api_request=true 时,request_id 为持久化的会话 ID,图像字段为短期有效的媒体 URL;当 save_api_request=false 时,它们是内联的 Base64 JPEG 字符串。
当 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)。