curl -X POST "https://verification.didit.me/v3/database-validation/" \
-H "x-api-key: YOUR_API_KEY" \
-F "issuing_state=BRA" \
-F "services=bra_cpf_facial" \
-F "vendor_data=user-1234" \
-F "consent=true" \
-F "tax_number=11111111111" \
-F "selfie=@./selfie.jpg"
from didit import Didit
# Reads DIDIT_API_KEY.
client = Didit()
result = client.database_validation.validate(
issuing_state="BRA",
services=["bra_cpf_facial"],
consent=True,
tax_number="11111111111",
vendor_data="user-1234",
selfie=open("selfie.jpg", "rb"),
)
print(result)
import Didit, { fileFromPath } from "@didit-protocol/sdk-node";
// Reads DIDIT_API_KEY.
const didit = new Didit();
const result = await didit.databaseValidation.validate({
issuing_state: "BRA",
services: ["bra_cpf_facial"],
consent: true,
tax_number: "11111111111",
vendor_data: "user-1234",
selfie: await fileFromPath("selfie.jpg"),
});
console.log(result);
ctx := context.Background()
// Reads DIDIT_API_KEY.
client := didit.NewClient()
result, err := client.DatabaseValidation.Validate(ctx, didit.DatabaseValidationValidateParams{
IssuingState: "BRA",
Services: didit.Some([]string{"bra_cpf_facial"}),
Consent: didit.Bool(true),
TaxNumber: didit.String("11111111111"),
VendorData: didit.String("user-1234"),
Selfie: didit.Some(didit.FileFromPath("selfie.jpg")),
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("%+v\n", result)
import java.nio.file.Path;
import java.util.List;
import me.didit.Didit;
import me.didit.types.DatabaseValidationValidateParams;
// Reads DIDIT_API_KEY.
Didit client = new Didit();
var result = client.databaseValidation().validate(DatabaseValidationValidateParams.builder()
.issuingState("BRA")
.services(List.of("bra_cpf_facial"))
.consent(true)
.taxNumber("11111111111")
.vendorData("user-1234")
.selfie(Path.of("selfie.jpg"))
.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->databaseValidation->validate([
'issuing_state' => 'BRA',
'services' => ['bra_cpf_facial'],
'consent' => true,
'tax_number' => '11111111111',
'vendor_data' => 'user-1234',
'selfie' => File::fromPath('selfie.jpg'),
]);
print_r($result->toArray());
require "didit"
# Reads DIDIT_API_KEY.
didit = Didit::Client.new
result = didit.database_validation.validate(
issuing_state: "BRA",
services: ["bra_cpf_facial"],
consent: true,
tax_number: "11111111111",
vendor_data: "user-1234",
selfie: Pathname("selfie.jpg")
)
puts result.to_h
using System;
using System.Text.Json;
using Didit;
// Reads DIDIT_API_KEY.
using var client = new DiditClient();
var result = await client.DatabaseValidation.ValidateAsync(new DatabaseValidationValidateParams
{
IssuingState = "BRA",
Services = new string[] { "bra_cpf_facial" },
Consent = true,
TaxNumber = "11111111111",
VendorData = "user-1234",
Selfie = FileUpload.FromPath("selfie.jpg"),
});
Console.WriteLine(JsonSerializer.Serialize(result));
{
"request_id": "req_01H…",
"status": "Approved",
"issuing_state": "BRA",
"match_type": "full_match",
"validations": [
{
"outcome_code": "MATCH",
"service_id": "bra_cpf_facial",
"service_name": "Brazil - CPF + face match (Datavalid)",
"source_data": {
"date_of_birth": "1990-01-01",
"face_match_probability": "Altíssima probabilidade",
"face_match_score": "0.990",
"first_name": "John",
"identification_number": "SAMPLE-ID-12345",
"last_name": "Doe",
"name_match_score": "1.000",
"verifications": {
"identification_number": true
}
},
"validation": {
"identification_number": "full_match"
}
}
]
}
{
"request_id": "req_01H…",
"status": "Declined",
"issuing_state": "BRA",
"match_type": "no_match",
"validations": [
{
"outcome_code": "NO_MATCH",
"service_id": "bra_cpf_facial",
"service_name": "Brazil - CPF + face match (Datavalid)",
"source_data": {
"identification_number": "NO_MATCH"
},
"validation": {
"identification_number": "no_match"
}
}
]
}
{
"request_id": "req_01H…",
"status": "Declined",
"issuing_state": "BRA",
"match_type": "no_match",
"validations": [
{
"outcome_code": "BIOMETRIC_NO_MATCH",
"service_id": "bra_cpf_facial",
"service_name": "Brazil - CPF + face match (Datavalid)",
"source_data": {
"identification_number": "NO_MATCH"
},
"validation": {
"identification_number": "no_match"
}
}
]
}
{
"request_id": "req_01H…",
"status": "In Review",
"issuing_state": "BRA",
"match_type": "no_match",
"validations": [
{
"outcome_code": "BIOMETRIC_IMAGE_UNUSABLE",
"service_id": "bra_cpf_facial",
"service_name": "Brazil - CPF + face match (Datavalid)",
"source_data": {
"identification_number": "NO_MATCH"
},
"validation": {
"identification_number": "no_match"
}
}
]
}
{
"request_id": "req_01H…",
"status": "In Review",
"issuing_state": "BRA",
"match_type": "full_match",
"validations": [
{
"outcome_code": "INCONCLUSIVE",
"service_id": "bra_cpf_facial",
"service_name": "Brazil - CPF + face match (Datavalid)",
"source_data": {
"date_of_birth": "1990-01-01",
"first_name": "John",
"identification_number": "SAMPLE-ID-12345",
"last_name": "Doe",
"name_match_score": "1.000"
},
"validation": {
"identification_number": "full_match"
}
}
]
}
🇧🇷 巴西
巴西 CPF 人脸比对(Datavalid)API:身份匹配
通过 Didit 查询巴西权威数据库,完成 CPF 与人脸比对(Datavalid)。按次计费,单次低至 $0.45,无合同、无最低消费。
POST
/
v3
/
database-validation
/
curl -X POST "https://verification.didit.me/v3/database-validation/" \
-H "x-api-key: YOUR_API_KEY" \
-F "issuing_state=BRA" \
-F "services=bra_cpf_facial" \
-F "vendor_data=user-1234" \
-F "consent=true" \
-F "tax_number=11111111111" \
-F "selfie=@./selfie.jpg"
from didit import Didit
# Reads DIDIT_API_KEY.
client = Didit()
result = client.database_validation.validate(
issuing_state="BRA",
services=["bra_cpf_facial"],
consent=True,
tax_number="11111111111",
vendor_data="user-1234",
selfie=open("selfie.jpg", "rb"),
)
print(result)
import Didit, { fileFromPath } from "@didit-protocol/sdk-node";
// Reads DIDIT_API_KEY.
const didit = new Didit();
const result = await didit.databaseValidation.validate({
issuing_state: "BRA",
services: ["bra_cpf_facial"],
consent: true,
tax_number: "11111111111",
vendor_data: "user-1234",
selfie: await fileFromPath("selfie.jpg"),
});
console.log(result);
ctx := context.Background()
// Reads DIDIT_API_KEY.
client := didit.NewClient()
result, err := client.DatabaseValidation.Validate(ctx, didit.DatabaseValidationValidateParams{
IssuingState: "BRA",
Services: didit.Some([]string{"bra_cpf_facial"}),
Consent: didit.Bool(true),
TaxNumber: didit.String("11111111111"),
VendorData: didit.String("user-1234"),
Selfie: didit.Some(didit.FileFromPath("selfie.jpg")),
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("%+v\n", result)
import java.nio.file.Path;
import java.util.List;
import me.didit.Didit;
import me.didit.types.DatabaseValidationValidateParams;
// Reads DIDIT_API_KEY.
Didit client = new Didit();
var result = client.databaseValidation().validate(DatabaseValidationValidateParams.builder()
.issuingState("BRA")
.services(List.of("bra_cpf_facial"))
.consent(true)
.taxNumber("11111111111")
.vendorData("user-1234")
.selfie(Path.of("selfie.jpg"))
.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->databaseValidation->validate([
'issuing_state' => 'BRA',
'services' => ['bra_cpf_facial'],
'consent' => true,
'tax_number' => '11111111111',
'vendor_data' => 'user-1234',
'selfie' => File::fromPath('selfie.jpg'),
]);
print_r($result->toArray());
require "didit"
# Reads DIDIT_API_KEY.
didit = Didit::Client.new
result = didit.database_validation.validate(
issuing_state: "BRA",
services: ["bra_cpf_facial"],
consent: true,
tax_number: "11111111111",
vendor_data: "user-1234",
selfie: Pathname("selfie.jpg")
)
puts result.to_h
using System;
using System.Text.Json;
using Didit;
// Reads DIDIT_API_KEY.
using var client = new DiditClient();
var result = await client.DatabaseValidation.ValidateAsync(new DatabaseValidationValidateParams
{
IssuingState = "BRA",
Services = new string[] { "bra_cpf_facial" },
Consent = true,
TaxNumber = "11111111111",
VendorData = "user-1234",
Selfie = FileUpload.FromPath("selfie.jpg"),
});
Console.WriteLine(JsonSerializer.Serialize(result));
{
"request_id": "req_01H…",
"status": "Approved",
"issuing_state": "BRA",
"match_type": "full_match",
"validations": [
{
"outcome_code": "MATCH",
"service_id": "bra_cpf_facial",
"service_name": "Brazil - CPF + face match (Datavalid)",
"source_data": {
"date_of_birth": "1990-01-01",
"face_match_probability": "Altíssima probabilidade",
"face_match_score": "0.990",
"first_name": "John",
"identification_number": "SAMPLE-ID-12345",
"last_name": "Doe",
"name_match_score": "1.000",
"verifications": {
"identification_number": true
}
},
"validation": {
"identification_number": "full_match"
}
}
]
}
{
"request_id": "req_01H…",
"status": "Declined",
"issuing_state": "BRA",
"match_type": "no_match",
"validations": [
{
"outcome_code": "NO_MATCH",
"service_id": "bra_cpf_facial",
"service_name": "Brazil - CPF + face match (Datavalid)",
"source_data": {
"identification_number": "NO_MATCH"
},
"validation": {
"identification_number": "no_match"
}
}
]
}
{
"request_id": "req_01H…",
"status": "Declined",
"issuing_state": "BRA",
"match_type": "no_match",
"validations": [
{
"outcome_code": "BIOMETRIC_NO_MATCH",
"service_id": "bra_cpf_facial",
"service_name": "Brazil - CPF + face match (Datavalid)",
"source_data": {
"identification_number": "NO_MATCH"
},
"validation": {
"identification_number": "no_match"
}
}
]
}
{
"request_id": "req_01H…",
"status": "In Review",
"issuing_state": "BRA",
"match_type": "no_match",
"validations": [
{
"outcome_code": "BIOMETRIC_IMAGE_UNUSABLE",
"service_id": "bra_cpf_facial",
"service_name": "Brazil - CPF + face match (Datavalid)",
"source_data": {
"identification_number": "NO_MATCH"
},
"validation": {
"identification_number": "no_match"
}
}
]
}
{
"request_id": "req_01H…",
"status": "In Review",
"issuing_state": "BRA",
"match_type": "full_match",
"validations": [
{
"outcome_code": "INCONCLUSIVE",
"service_id": "bra_cpf_facial",
"service_name": "Brazil - CPF + face match (Datavalid)",
"source_data": {
"date_of_birth": "1990-01-01",
"first_name": "John",
"identification_number": "SAMPLE-ID-12345",
"last_name": "Doe",
"name_match_score": "1.000"
},
"validation": {
"identification_number": "full_match"
}
}
]
}
SERPRO Datavalid v4 pf-facial:依据 Receita Federal 校验 CPF(必填),并将实时自拍照与 Senatran 存储的 CNH 照片进行比对(必填)。可选择筛查姓名和出生日期。Didit 通过
POST /v3/database-validation/ 提供该服务,以便您将提交的数据与权威来源进行核对,并获得标准化的匹配结果。输入格式:tax_number 接受巴西 CPF(恰好 11 位数字)。
覆盖范围
- 覆盖率: ~50%
- 国家/地区: 巴西
- 服务 ID:
bra_cpf_facial - 数据领域: 生物识别
- 类别: 国家身份证登记
输入参数
| 字段 | 必填 | 示例 |
|---|---|---|
tax_number | 是 | 11111111111 |
selfie | 是 | @./selfie.jpg |
first_name | 否 | John |
last_name | 否 | Doe |
date_of_birth | 否 | 1990-01-01 |
vendor_data | 否 | user-1234 |
- 必填输入:
tax_number、selfie - 可选输入:
first_name、last_name、date_of_birth、vendor_data - 同意: 必填
- 工作流可用性: 可在工作流中使用
- 覆盖率: ~50%
- 价格: 每次成功查询 $0.45
请求体参数
string
默认值:"BRA"
必填
该数据库服务的 ISO 3166-1 alpha-3 国家/地区代码。示例:
BRAstring
默认值:"bra_cpf_facial"
必填
包含此服务 ID 的数组。固定该服务可将请求限定在此特定数据库内。示例:
bra_cpf_facialboolean
默认值:"true"
必填
终端用户对此服务的明确同意。示例:
truestring
默认值:"11111111111"
必填
税号或财政识别号。示例:
11111111111file
必填
用于生物识别数据库核验的自拍照文件。支持的格式:JPEG、PNG 或 WebP。示例:
@./selfie.jpgstring
需要验证的名字。示例:
Johnstring
需要验证的姓氏。示例:
Doestring
出生日期,格式为
YYYY-MM-DD。示例:1990-01-01string
默认值:"user-1234"
贵方为该用户设定的稳定用户标识,例如内部用户 ID。Didit 使用该标识将单独的检查关联到同一终端用户,并减少重复检测的干扰。示例:
user-1234输入规则与校验说明
- 巴西 CPF(恰好 11 位数字)
tax_number只能包含数字;发送请求前请去除空格、连字符和标点符号。tax_number长度必须恰好为 11 个字符。
调用方法
curl -X POST "https://verification.didit.me/v3/database-validation/" \
-H "x-api-key: YOUR_API_KEY" \
-F "issuing_state=BRA" \
-F "services=bra_cpf_facial" \
-F "vendor_data=user-1234" \
-F "consent=true" \
-F "tax_number=11111111111" \
-F "selfie=@./selfie.jpg"
from didit import Didit
# Reads DIDIT_API_KEY.
client = Didit()
result = client.database_validation.validate(
issuing_state="BRA",
services=["bra_cpf_facial"],
consent=True,
tax_number="11111111111",
vendor_data="user-1234",
selfie=open("selfie.jpg", "rb"),
)
print(result)
import Didit, { fileFromPath } from "@didit-protocol/sdk-node";
// Reads DIDIT_API_KEY.
const didit = new Didit();
const result = await didit.databaseValidation.validate({
issuing_state: "BRA",
services: ["bra_cpf_facial"],
consent: true,
tax_number: "11111111111",
vendor_data: "user-1234",
selfie: await fileFromPath("selfie.jpg"),
});
console.log(result);
ctx := context.Background()
// Reads DIDIT_API_KEY.
client := didit.NewClient()
result, err := client.DatabaseValidation.Validate(ctx, didit.DatabaseValidationValidateParams{
IssuingState: "BRA",
Services: didit.Some([]string{"bra_cpf_facial"}),
Consent: didit.Bool(true),
TaxNumber: didit.String("11111111111"),
VendorData: didit.String("user-1234"),
Selfie: didit.Some(didit.FileFromPath("selfie.jpg")),
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("%+v\n", result)
import java.nio.file.Path;
import java.util.List;
import me.didit.Didit;
import me.didit.types.DatabaseValidationValidateParams;
// Reads DIDIT_API_KEY.
Didit client = new Didit();
var result = client.databaseValidation().validate(DatabaseValidationValidateParams.builder()
.issuingState("BRA")
.services(List.of("bra_cpf_facial"))
.consent(true)
.taxNumber("11111111111")
.vendorData("user-1234")
.selfie(Path.of("selfie.jpg"))
.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->databaseValidation->validate([
'issuing_state' => 'BRA',
'services' => ['bra_cpf_facial'],
'consent' => true,
'tax_number' => '11111111111',
'vendor_data' => 'user-1234',
'selfie' => File::fromPath('selfie.jpg'),
]);
print_r($result->toArray());
require "didit"
# Reads DIDIT_API_KEY.
didit = Didit::Client.new
result = didit.database_validation.validate(
issuing_state: "BRA",
services: ["bra_cpf_facial"],
consent: true,
tax_number: "11111111111",
vendor_data: "user-1234",
selfie: Pathname("selfie.jpg")
)
puts result.to_h
using System;
using System.Text.Json;
using Didit;
// Reads DIDIT_API_KEY.
using var client = new DiditClient();
var result = await client.DatabaseValidation.ValidateAsync(new DatabaseValidationValidateParams
{
IssuingState = "BRA",
Services = new string[] { "bra_cpf_facial" },
Consent = true,
TaxNumber = "11111111111",
VendorData = "user-1234",
Selfie = FileUpload.FromPath("selfie.jpg"),
});
Console.WriteLine(JsonSerializer.Serialize(result));
每次成功调用都返回 HTTP 200。outcome_code 字段说明实际结果,例如区分真实的生物识别不匹配(BIOMETRIC_NO_MATCH)与无法读取的自拍照(BIOMETRIC_IMAGE_UNUSABLE)。显示的 status 为默认功能状态;您配置的部分匹配 / 无匹配操作可以覆盖该状态。MATCH:登记机构已确认身份,且所有已检查字段均匹配。{
"request_id": "req_01H…",
"status": "Approved",
"issuing_state": "BRA",
"match_type": "full_match",
"validations": [
{
"outcome_code": "MATCH",
"service_id": "bra_cpf_facial",
"service_name": "Brazil - CPF + face match (Datavalid)",
"source_data": {
"date_of_birth": "1990-01-01",
"face_match_probability": "Altíssima probabilidade",
"face_match_score": "0.990",
"first_name": "John",
"identification_number": "SAMPLE-ID-12345",
"last_name": "Doe",
"name_match_score": "1.000",
"verifications": {
"identification_number": true
}
},
"validation": {
"identification_number": "full_match"
}
}
]
}
NO_MATCH:登记机构未返回与所提交数据匹配的结果。{
"request_id": "req_01H…",
"status": "Declined",
"issuing_state": "BRA",
"match_type": "no_match",
"validations": [
{
"outcome_code": "NO_MATCH",
"service_id": "bra_cpf_facial",
"service_name": "Brazil - CPF + face match (Datavalid)",
"source_data": {
"identification_number": "NO_MATCH"
},
"validation": {
"identification_number": "no_match"
}
}
]
}
BIOMETRIC_NO_MATCH:人脸比对分数低于接受阈值,即自拍照与登记照片并非同一人。{
"request_id": "req_01H…",
"status": "Declined",
"issuing_state": "BRA",
"match_type": "no_match",
"validations": [
{
"outcome_code": "BIOMETRIC_NO_MATCH",
"service_id": "bra_cpf_facial",
"service_name": "Brazil - CPF + face match (Datavalid)",
"source_data": {
"identification_number": "NO_MATCH"
},
"validation": {
"identification_number": "no_match"
}
}
]
}
BIOMETRIC_IMAGE_UNUSABLE:无法处理该自拍照(为空、未检测到人脸、质量低,或登记机构无法读取)。请提示用户重新拍摄自拍照。{
"request_id": "req_01H…",
"status": "In Review",
"issuing_state": "BRA",
"match_type": "no_match",
"validations": [
{
"outcome_code": "BIOMETRIC_IMAGE_UNUSABLE",
"service_id": "bra_cpf_facial",
"service_name": "Brazil - CPF + face match (Datavalid)",
"source_data": {
"identification_number": "NO_MATCH"
},
"validation": {
"identification_number": "no_match"
}
}
]
}
INCONCLUSIVE:登记机构已确认 CPF(以及您发送的姓名和出生日期),但无法进行人脸比对:该 CPF 没有存档的参考照片,或自拍照无法使用(未检测到人脸、图像尺寸不符、质量低,或检测到多张人脸)。已确认的字段保留在 validation 中,因此 match_type 会反映这些字段;但强制性的人脸检查尚未完成,因此该检查将提交人工审核。请要求用户提供新的自拍照;对于没有照片存档的用户,改用证件验证。{
"request_id": "req_01H…",
"status": "In Review",
"issuing_state": "BRA",
"match_type": "full_match",
"validations": [
{
"outcome_code": "INCONCLUSIVE",
"service_id": "bra_cpf_facial",
"service_name": "Brazil - CPF + face match (Datavalid)",
"source_data": {
"date_of_birth": "1990-01-01",
"first_name": "John",
"identification_number": "SAMPLE-ID-12345",
"last_name": "Doe",
"name_match_score": "1.000"
},
"validation": {
"identification_number": "full_match"
}
}
]
}
返回数据
source_data 中实际返回的字段取决于登记机构的返回内容。bra_cpf_facial 的生成示例目前记录了以下标准化结构:
date_of_birthfirst_nameidentification_numberlast_namename_match_score
定价与 SLA
巴西:CPF + 人脸比对(Datavalid)查询仅在 Didit 从校验源收到确定结果时计费。- 单次调用价格: $0.45 USD。
- 计费方式: 按成功查询计费。当登记机构无法访问、缺少必填字段,或请求在到达校验源之前即被拒绝时,不收费。
- 延迟: 典型 p95 低于 2 秒。
- 可用性: Didit 侧每季度 99.9%;下游数据源的可用性因国家/地区和数据集而异。
关于此数据源
这是官方政府数据源:SERPRO Datavalid,由巴西联邦数据处理服务机构运营。CPF 会与 Receita Federal 进行核对,自拍照则与 Senatran(全国驾驶证登记库)为该人员保存的肖像进行比对。 由于肖像来自 CNH(驾驶证)记录,只有持有 CNH 的人员才会在系统中留有人脸数据。这也是覆盖率约为成年人口 50% 的原因:数据具有权威性,但从未领取过驾驶证的巴西人没有相应数据。 需要更广泛的覆盖范围吗? 请改用 BRA - Unico IDCloud(CPF + 自拍照)。该服务通过 Unico 的私有生物识别库覆盖约 96% 的巴西成年人,费用为 $0.20,而此处为 $0.45。当你特别需要以政府登记库作为权威数据源时,选择 Datavalid;当你需要核验所有人员时,选择 IDCloud。延伸阅读
最后修改于 2026年11月7日