curl -X POST https://verification.didit.me/v3/database-validation/ \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"issuing_state": "BRA",
"services": ["bra_cpf"],
"identification_number": "12345678900",
"first_name": "John",
"last_name": "Doe",
"date_of_birth": "1980-01-01",
"vendor_data": "user-1234"
}'import os, requests
resp = requests.post(
"https://verification.didit.me/v3/database-validation/",
headers={"x-api-key": os.environ["DIDIT_API_KEY"]},
json={
"issuing_state": "BRA",
"services": ["bra_cpf"],
"identification_number": "12345678900",
"first_name": "John",
"last_name": "Doe",
"date_of_birth": "1980-01-01",
"vendor_data": "user-1234",
},
timeout=45,
)
resp.raise_for_status()
dv = resp.json()["database_validation"]
print(dv["status"], dv["match_type"]) # e.g. Approved full_match
# Biometric services need a selfie via multipart/form-data:
# requests.post(..., data={"issuing_state": "ARG", "services": '["arg_renaper"]',
# "identification_number": "12345678", "gender": "M", ...},
# files={"selfie": open("selfie.jpg", "rb")})const res = await fetch('https://verification.didit.me/v3/database-validation/', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
issuing_state: 'BRA',
services: ['bra_cpf'],
identification_number: '12345678900',
first_name: 'John',
last_name: 'Doe',
date_of_birth: '1980-01-01',
vendor_data: 'user-1234',
}),
});
const data = await res.json();
console.log(data.database_validation.status, data.database_validation.match_type);<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://verification.didit.me/v3/database-validation/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'issuing_state' => 'BRA',
'services' => [
'bra_cpf'
],
'validation_type' => '<string>',
'consent' => false,
'identification_number' => '<string>',
'first_name' => 'John',
'last_name' => 'Doe',
'middle_name' => '<string>',
'full_name' => '<string>',
'date_of_birth' => '1980-01-01',
'personal_number' => '<string>',
'tax_number' => '<string>',
'document_number' => '<string>',
'expiration_date' => '2030-01-15',
'date_of_issue' => '2015-06-20',
'nationality' => '<string>',
'address' => [
'street_1' => '<string>',
'street_2' => '<string>',
'city' => '<string>',
'region' => '<string>',
'postal_code' => '<string>',
'country' => '<string>'
],
'address_element_1' => '<string>',
'address_element_2' => '<string>',
'address_element_3' => '<string>',
'address_element_4' => '<string>',
'address_element_5' => '<string>',
'postal_code' => '<string>',
'driver_license_number' => '<string>',
'driver_license_card_number' => '<string>',
'driver_license_state' => '<string>',
'driver_license_version' => '<string>',
'passport_number' => '<string>',
'passport_expiration_date' => '2023-12-25',
'passport_file_number' => '<string>',
'passport_issue_country' => '<string>',
'medicare_card_number' => '<string>',
'immi_card_number' => '<string>',
'immi_card_expiry_date' => '2023-12-25',
'citizenship_certificate_number' => '<string>',
'birth_registration_number' => '<string>',
'birth_registration_date' => '2023-12-25',
'birth_registration_state' => '<string>',
'marriage_certificate_number' => '<string>',
'change_of_name_certificate_number' => '<string>',
'first_partner_name' => '<string>',
'last_partner_name' => '<string>',
'voter_id' => '<string>',
'epic_card' => '<string>',
'pan' => '<string>',
'national_id' => '<string>',
'cic' => '<string>',
'identificador_ciudadano' => '<string>',
'ocr' => '<string>',
'voter_number' => '<string>',
'emission_number' => '<string>',
'bvn' => '<string>',
'bank_card_number' => '<string>',
'ssn' => '<string>',
'phone' => '<string>',
'landline' => '<string>',
'email' => 'jsmith@example.com',
'country_of_residence' => 'US',
'partial_match_action' => 'NO_ACTION',
'no_match_action' => 'DECLINE',
'save_api_request' => true,
'vendor_data' => '<string>',
'metadata' => [
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://verification.didit.me/v3/database-validation/"
payload := strings.NewReader("{\n \"issuing_state\": \"BRA\",\n \"services\": [\n \"bra_cpf\"\n ],\n \"validation_type\": \"<string>\",\n \"consent\": false,\n \"identification_number\": \"<string>\",\n \"first_name\": \"John\",\n \"last_name\": \"Doe\",\n \"middle_name\": \"<string>\",\n \"full_name\": \"<string>\",\n \"date_of_birth\": \"1980-01-01\",\n \"personal_number\": \"<string>\",\n \"tax_number\": \"<string>\",\n \"document_number\": \"<string>\",\n \"expiration_date\": \"2030-01-15\",\n \"date_of_issue\": \"2015-06-20\",\n \"nationality\": \"<string>\",\n \"address\": {\n \"street_1\": \"<string>\",\n \"street_2\": \"<string>\",\n \"city\": \"<string>\",\n \"region\": \"<string>\",\n \"postal_code\": \"<string>\",\n \"country\": \"<string>\"\n },\n \"address_element_1\": \"<string>\",\n \"address_element_2\": \"<string>\",\n \"address_element_3\": \"<string>\",\n \"address_element_4\": \"<string>\",\n \"address_element_5\": \"<string>\",\n \"postal_code\": \"<string>\",\n \"driver_license_number\": \"<string>\",\n \"driver_license_card_number\": \"<string>\",\n \"driver_license_state\": \"<string>\",\n \"driver_license_version\": \"<string>\",\n \"passport_number\": \"<string>\",\n \"passport_expiration_date\": \"2023-12-25\",\n \"passport_file_number\": \"<string>\",\n \"passport_issue_country\": \"<string>\",\n \"medicare_card_number\": \"<string>\",\n \"immi_card_number\": \"<string>\",\n \"immi_card_expiry_date\": \"2023-12-25\",\n \"citizenship_certificate_number\": \"<string>\",\n \"birth_registration_number\": \"<string>\",\n \"birth_registration_date\": \"2023-12-25\",\n \"birth_registration_state\": \"<string>\",\n \"marriage_certificate_number\": \"<string>\",\n \"change_of_name_certificate_number\": \"<string>\",\n \"first_partner_name\": \"<string>\",\n \"last_partner_name\": \"<string>\",\n \"voter_id\": \"<string>\",\n \"epic_card\": \"<string>\",\n \"pan\": \"<string>\",\n \"national_id\": \"<string>\",\n \"cic\": \"<string>\",\n \"identificador_ciudadano\": \"<string>\",\n \"ocr\": \"<string>\",\n \"voter_number\": \"<string>\",\n \"emission_number\": \"<string>\",\n \"bvn\": \"<string>\",\n \"bank_card_number\": \"<string>\",\n \"ssn\": \"<string>\",\n \"phone\": \"<string>\",\n \"landline\": \"<string>\",\n \"email\": \"jsmith@example.com\",\n \"country_of_residence\": \"US\",\n \"partial_match_action\": \"NO_ACTION\",\n \"no_match_action\": \"DECLINE\",\n \"save_api_request\": true,\n \"vendor_data\": \"<string>\",\n \"metadata\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://verification.didit.me/v3/database-validation/")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"issuing_state\": \"BRA\",\n \"services\": [\n \"bra_cpf\"\n ],\n \"validation_type\": \"<string>\",\n \"consent\": false,\n \"identification_number\": \"<string>\",\n \"first_name\": \"John\",\n \"last_name\": \"Doe\",\n \"middle_name\": \"<string>\",\n \"full_name\": \"<string>\",\n \"date_of_birth\": \"1980-01-01\",\n \"personal_number\": \"<string>\",\n \"tax_number\": \"<string>\",\n \"document_number\": \"<string>\",\n \"expiration_date\": \"2030-01-15\",\n \"date_of_issue\": \"2015-06-20\",\n \"nationality\": \"<string>\",\n \"address\": {\n \"street_1\": \"<string>\",\n \"street_2\": \"<string>\",\n \"city\": \"<string>\",\n \"region\": \"<string>\",\n \"postal_code\": \"<string>\",\n \"country\": \"<string>\"\n },\n \"address_element_1\": \"<string>\",\n \"address_element_2\": \"<string>\",\n \"address_element_3\": \"<string>\",\n \"address_element_4\": \"<string>\",\n \"address_element_5\": \"<string>\",\n \"postal_code\": \"<string>\",\n \"driver_license_number\": \"<string>\",\n \"driver_license_card_number\": \"<string>\",\n \"driver_license_state\": \"<string>\",\n \"driver_license_version\": \"<string>\",\n \"passport_number\": \"<string>\",\n \"passport_expiration_date\": \"2023-12-25\",\n \"passport_file_number\": \"<string>\",\n \"passport_issue_country\": \"<string>\",\n \"medicare_card_number\": \"<string>\",\n \"immi_card_number\": \"<string>\",\n \"immi_card_expiry_date\": \"2023-12-25\",\n \"citizenship_certificate_number\": \"<string>\",\n \"birth_registration_number\": \"<string>\",\n \"birth_registration_date\": \"2023-12-25\",\n \"birth_registration_state\": \"<string>\",\n \"marriage_certificate_number\": \"<string>\",\n \"change_of_name_certificate_number\": \"<string>\",\n \"first_partner_name\": \"<string>\",\n \"last_partner_name\": \"<string>\",\n \"voter_id\": \"<string>\",\n \"epic_card\": \"<string>\",\n \"pan\": \"<string>\",\n \"national_id\": \"<string>\",\n \"cic\": \"<string>\",\n \"identificador_ciudadano\": \"<string>\",\n \"ocr\": \"<string>\",\n \"voter_number\": \"<string>\",\n \"emission_number\": \"<string>\",\n \"bvn\": \"<string>\",\n \"bank_card_number\": \"<string>\",\n \"ssn\": \"<string>\",\n \"phone\": \"<string>\",\n \"landline\": \"<string>\",\n \"email\": \"jsmith@example.com\",\n \"country_of_residence\": \"US\",\n \"partial_match_action\": \"NO_ACTION\",\n \"no_match_action\": \"DECLINE\",\n \"save_api_request\": true,\n \"vendor_data\": \"<string>\",\n \"metadata\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://verification.didit.me/v3/database-validation/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"issuing_state\": \"BRA\",\n \"services\": [\n \"bra_cpf\"\n ],\n \"validation_type\": \"<string>\",\n \"consent\": false,\n \"identification_number\": \"<string>\",\n \"first_name\": \"John\",\n \"last_name\": \"Doe\",\n \"middle_name\": \"<string>\",\n \"full_name\": \"<string>\",\n \"date_of_birth\": \"1980-01-01\",\n \"personal_number\": \"<string>\",\n \"tax_number\": \"<string>\",\n \"document_number\": \"<string>\",\n \"expiration_date\": \"2030-01-15\",\n \"date_of_issue\": \"2015-06-20\",\n \"nationality\": \"<string>\",\n \"address\": {\n \"street_1\": \"<string>\",\n \"street_2\": \"<string>\",\n \"city\": \"<string>\",\n \"region\": \"<string>\",\n \"postal_code\": \"<string>\",\n \"country\": \"<string>\"\n },\n \"address_element_1\": \"<string>\",\n \"address_element_2\": \"<string>\",\n \"address_element_3\": \"<string>\",\n \"address_element_4\": \"<string>\",\n \"address_element_5\": \"<string>\",\n \"postal_code\": \"<string>\",\n \"driver_license_number\": \"<string>\",\n \"driver_license_card_number\": \"<string>\",\n \"driver_license_state\": \"<string>\",\n \"driver_license_version\": \"<string>\",\n \"passport_number\": \"<string>\",\n \"passport_expiration_date\": \"2023-12-25\",\n \"passport_file_number\": \"<string>\",\n \"passport_issue_country\": \"<string>\",\n \"medicare_card_number\": \"<string>\",\n \"immi_card_number\": \"<string>\",\n \"immi_card_expiry_date\": \"2023-12-25\",\n \"citizenship_certificate_number\": \"<string>\",\n \"birth_registration_number\": \"<string>\",\n \"birth_registration_date\": \"2023-12-25\",\n \"birth_registration_state\": \"<string>\",\n \"marriage_certificate_number\": \"<string>\",\n \"change_of_name_certificate_number\": \"<string>\",\n \"first_partner_name\": \"<string>\",\n \"last_partner_name\": \"<string>\",\n \"voter_id\": \"<string>\",\n \"epic_card\": \"<string>\",\n \"pan\": \"<string>\",\n \"national_id\": \"<string>\",\n \"cic\": \"<string>\",\n \"identificador_ciudadano\": \"<string>\",\n \"ocr\": \"<string>\",\n \"voter_number\": \"<string>\",\n \"emission_number\": \"<string>\",\n \"bvn\": \"<string>\",\n \"bank_card_number\": \"<string>\",\n \"ssn\": \"<string>\",\n \"phone\": \"<string>\",\n \"landline\": \"<string>\",\n \"email\": \"jsmith@example.com\",\n \"country_of_residence\": \"US\",\n \"partial_match_action\": \"NO_ACTION\",\n \"no_match_action\": \"DECLINE\",\n \"save_api_request\": true,\n \"vendor_data\": \"<string>\",\n \"metadata\": {}\n}"
response = http.request(request)
puts response.read_body{
"request_id": "7f9a1c0e-1f2b-4f6e-9d3a-2b1c0e7f9a1c",
"database_validation": {
"status": "Approved",
"issuing_state": "BRA",
"validation_type": "one_by_one",
"screened_data": {
"tax_number": "12345678900",
"first_name": "John",
"last_name": "Doe",
"date_of_birth": "1980-01-01"
},
"match_type": "full_match",
"validations": [
{
"validation": {
"full_name": "full_match",
"date_of_birth": "full_match",
"identification_number": "full_match"
},
"outcome_code": "MATCH",
"outcome_detail": "200",
"service_id": "bra_cpf",
"service_name": "Brazil - CPF status check",
"source_data": {
"identification_number": "12345678900",
"first_name": "JOHN",
"last_name": "DOE",
"date_of_birth": "1980-01-01",
"lgpd_minor": false,
"minor_under_16": false,
"minor_under_18": false
}
}
],
"warnings": []
},
"vendor_data": "user-1234",
"metadata": null,
"created_at": "2026-06-11T10:30:00.000000+00:00"
}Database Validation API
Validate a person’s identity data against official government and registry sources — CPF in Brazil, RENAPER in Argentina, DNI registries in Spain and Peru, INE in Mexico, and 100+ more services across 60+ countries.
Service selection. Each country exposes one or more catalog services identified by a service_id (e.g. bra_cpf, arg_renaper, pan_cedula_sib). Pin the services you want with the services array — if you omit it, exactly one default service runs (the longest-established live service for the country). Sending services also switches the response to the extended shape with services_used and match_score. Discover services, their required fields, and prices via GET /v1/organization/database-validation-countries/ (a catalog endpoint not documented in this spec) or the Business Console workflow editor. Some services are flagged requires_consent=true in the catalog and demand consent=true; others require onboarding for your organization before they can be called.
Input fields. identification_number is a universal field that maps to the right country-specific field automatically (see its description). Country format rules are enforced before any provider is called (e.g. BRA CPF must be exactly 11 digits) and format failures are never billed. Biometric services need a selfie upload (multipart only); Argentina RENAPER additionally requires gender.
Results. Each service returns a field-by-field validation map plus a vendor-neutral outcome_code (MATCH, PARTIAL_MATCH, NO_MATCH, DOCUMENT_NOT_FOUND, INVALID_DOCUMENT_FORMAT, INVALID_INPUT, MINOR_BLOCKED, DECEASED, BIOMETRIC_NO_MATCH, BIOMETRIC_IMAGE_UNUSABLE, INCONCLUSIVE, DOCUMENT_SUPERSEDED, REGISTRY_UNAVAILABLE, REGISTRY_ERROR). Note the distinctions: NO_MATCH is a definitive mismatch, INCONCLUSIVE means the registry could not confirm either way (review, not decline), and BIOMETRIC_IMAGE_UNUSABLE is a technical selfie problem (retake), unlike the definitive BIOMETRIC_NO_MATCH. The overall match_type aggregates across services (any full → full_match, else any partial → partial_match, else no_match) and no_match_action/partial_match_action translate it into the final status. validation_type is derived: two_by_two when two or more distinct services produced a full match (on the identification number, on full name + date of birth together, or on the address without contradictions), else one_by_one.
Persistence. save_api_request defaults to true: the result is stored as a session (request_id works with GET /v3/session/{sessionId}/decision/), appears in the console, and fires a status.updated webhook. It also controls the validations shape — per-service objects when saved, a merged {field: match} map when not.
Billing. Per-service: each service that returns a billable result is charged its own catalog price. Failed or skipped services are not billed, and requests rejected with 400 cost nothing. The pre-flight balance check covers the sum of the selected services’ prices (403 when short).
Failures. When no selected service returns a usable result, the API returns 400 with validation_errors if every unanswered attempt explicitly refused the input (provider_rejected_input, retryable: false). Correct the input before trying again. Otherwise it returns 502 with validation_errors (empty_provider_response, retryable: true), including mixed input rejection and unavailable fallback attempts; nothing is billed (a session is still recorded with status Not Finished when save_api_request=true). When only some services fail, the 200 response carries their failures in database_validation.errors.
Sandbox. Keys from sandbox applications skip the registry calls and billing and return a static full_match response — the sandbox payload always includes services_used and match_score: 100 regardless of how services was sent, so don’t validate the live extended-shape gating or the 0.0–1.0 match_score fraction against sandbox responses.
Send the request as application/json, or as multipart/form-data when uploading a selfie.
curl -X POST https://verification.didit.me/v3/database-validation/ \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"issuing_state": "BRA",
"services": ["bra_cpf"],
"identification_number": "12345678900",
"first_name": "John",
"last_name": "Doe",
"date_of_birth": "1980-01-01",
"vendor_data": "user-1234"
}'import os, requests
resp = requests.post(
"https://verification.didit.me/v3/database-validation/",
headers={"x-api-key": os.environ["DIDIT_API_KEY"]},
json={
"issuing_state": "BRA",
"services": ["bra_cpf"],
"identification_number": "12345678900",
"first_name": "John",
"last_name": "Doe",
"date_of_birth": "1980-01-01",
"vendor_data": "user-1234",
},
timeout=45,
)
resp.raise_for_status()
dv = resp.json()["database_validation"]
print(dv["status"], dv["match_type"]) # e.g. Approved full_match
# Biometric services need a selfie via multipart/form-data:
# requests.post(..., data={"issuing_state": "ARG", "services": '["arg_renaper"]',
# "identification_number": "12345678", "gender": "M", ...},
# files={"selfie": open("selfie.jpg", "rb")})const res = await fetch('https://verification.didit.me/v3/database-validation/', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
issuing_state: 'BRA',
services: ['bra_cpf'],
identification_number: '12345678900',
first_name: 'John',
last_name: 'Doe',
date_of_birth: '1980-01-01',
vendor_data: 'user-1234',
}),
});
const data = await res.json();
console.log(data.database_validation.status, data.database_validation.match_type);<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://verification.didit.me/v3/database-validation/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'issuing_state' => 'BRA',
'services' => [
'bra_cpf'
],
'validation_type' => '<string>',
'consent' => false,
'identification_number' => '<string>',
'first_name' => 'John',
'last_name' => 'Doe',
'middle_name' => '<string>',
'full_name' => '<string>',
'date_of_birth' => '1980-01-01',
'personal_number' => '<string>',
'tax_number' => '<string>',
'document_number' => '<string>',
'expiration_date' => '2030-01-15',
'date_of_issue' => '2015-06-20',
'nationality' => '<string>',
'address' => [
'street_1' => '<string>',
'street_2' => '<string>',
'city' => '<string>',
'region' => '<string>',
'postal_code' => '<string>',
'country' => '<string>'
],
'address_element_1' => '<string>',
'address_element_2' => '<string>',
'address_element_3' => '<string>',
'address_element_4' => '<string>',
'address_element_5' => '<string>',
'postal_code' => '<string>',
'driver_license_number' => '<string>',
'driver_license_card_number' => '<string>',
'driver_license_state' => '<string>',
'driver_license_version' => '<string>',
'passport_number' => '<string>',
'passport_expiration_date' => '2023-12-25',
'passport_file_number' => '<string>',
'passport_issue_country' => '<string>',
'medicare_card_number' => '<string>',
'immi_card_number' => '<string>',
'immi_card_expiry_date' => '2023-12-25',
'citizenship_certificate_number' => '<string>',
'birth_registration_number' => '<string>',
'birth_registration_date' => '2023-12-25',
'birth_registration_state' => '<string>',
'marriage_certificate_number' => '<string>',
'change_of_name_certificate_number' => '<string>',
'first_partner_name' => '<string>',
'last_partner_name' => '<string>',
'voter_id' => '<string>',
'epic_card' => '<string>',
'pan' => '<string>',
'national_id' => '<string>',
'cic' => '<string>',
'identificador_ciudadano' => '<string>',
'ocr' => '<string>',
'voter_number' => '<string>',
'emission_number' => '<string>',
'bvn' => '<string>',
'bank_card_number' => '<string>',
'ssn' => '<string>',
'phone' => '<string>',
'landline' => '<string>',
'email' => 'jsmith@example.com',
'country_of_residence' => 'US',
'partial_match_action' => 'NO_ACTION',
'no_match_action' => 'DECLINE',
'save_api_request' => true,
'vendor_data' => '<string>',
'metadata' => [
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://verification.didit.me/v3/database-validation/"
payload := strings.NewReader("{\n \"issuing_state\": \"BRA\",\n \"services\": [\n \"bra_cpf\"\n ],\n \"validation_type\": \"<string>\",\n \"consent\": false,\n \"identification_number\": \"<string>\",\n \"first_name\": \"John\",\n \"last_name\": \"Doe\",\n \"middle_name\": \"<string>\",\n \"full_name\": \"<string>\",\n \"date_of_birth\": \"1980-01-01\",\n \"personal_number\": \"<string>\",\n \"tax_number\": \"<string>\",\n \"document_number\": \"<string>\",\n \"expiration_date\": \"2030-01-15\",\n \"date_of_issue\": \"2015-06-20\",\n \"nationality\": \"<string>\",\n \"address\": {\n \"street_1\": \"<string>\",\n \"street_2\": \"<string>\",\n \"city\": \"<string>\",\n \"region\": \"<string>\",\n \"postal_code\": \"<string>\",\n \"country\": \"<string>\"\n },\n \"address_element_1\": \"<string>\",\n \"address_element_2\": \"<string>\",\n \"address_element_3\": \"<string>\",\n \"address_element_4\": \"<string>\",\n \"address_element_5\": \"<string>\",\n \"postal_code\": \"<string>\",\n \"driver_license_number\": \"<string>\",\n \"driver_license_card_number\": \"<string>\",\n \"driver_license_state\": \"<string>\",\n \"driver_license_version\": \"<string>\",\n \"passport_number\": \"<string>\",\n \"passport_expiration_date\": \"2023-12-25\",\n \"passport_file_number\": \"<string>\",\n \"passport_issue_country\": \"<string>\",\n \"medicare_card_number\": \"<string>\",\n \"immi_card_number\": \"<string>\",\n \"immi_card_expiry_date\": \"2023-12-25\",\n \"citizenship_certificate_number\": \"<string>\",\n \"birth_registration_number\": \"<string>\",\n \"birth_registration_date\": \"2023-12-25\",\n \"birth_registration_state\": \"<string>\",\n \"marriage_certificate_number\": \"<string>\",\n \"change_of_name_certificate_number\": \"<string>\",\n \"first_partner_name\": \"<string>\",\n \"last_partner_name\": \"<string>\",\n \"voter_id\": \"<string>\",\n \"epic_card\": \"<string>\",\n \"pan\": \"<string>\",\n \"national_id\": \"<string>\",\n \"cic\": \"<string>\",\n \"identificador_ciudadano\": \"<string>\",\n \"ocr\": \"<string>\",\n \"voter_number\": \"<string>\",\n \"emission_number\": \"<string>\",\n \"bvn\": \"<string>\",\n \"bank_card_number\": \"<string>\",\n \"ssn\": \"<string>\",\n \"phone\": \"<string>\",\n \"landline\": \"<string>\",\n \"email\": \"jsmith@example.com\",\n \"country_of_residence\": \"US\",\n \"partial_match_action\": \"NO_ACTION\",\n \"no_match_action\": \"DECLINE\",\n \"save_api_request\": true,\n \"vendor_data\": \"<string>\",\n \"metadata\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://verification.didit.me/v3/database-validation/")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"issuing_state\": \"BRA\",\n \"services\": [\n \"bra_cpf\"\n ],\n \"validation_type\": \"<string>\",\n \"consent\": false,\n \"identification_number\": \"<string>\",\n \"first_name\": \"John\",\n \"last_name\": \"Doe\",\n \"middle_name\": \"<string>\",\n \"full_name\": \"<string>\",\n \"date_of_birth\": \"1980-01-01\",\n \"personal_number\": \"<string>\",\n \"tax_number\": \"<string>\",\n \"document_number\": \"<string>\",\n \"expiration_date\": \"2030-01-15\",\n \"date_of_issue\": \"2015-06-20\",\n \"nationality\": \"<string>\",\n \"address\": {\n \"street_1\": \"<string>\",\n \"street_2\": \"<string>\",\n \"city\": \"<string>\",\n \"region\": \"<string>\",\n \"postal_code\": \"<string>\",\n \"country\": \"<string>\"\n },\n \"address_element_1\": \"<string>\",\n \"address_element_2\": \"<string>\",\n \"address_element_3\": \"<string>\",\n \"address_element_4\": \"<string>\",\n \"address_element_5\": \"<string>\",\n \"postal_code\": \"<string>\",\n \"driver_license_number\": \"<string>\",\n \"driver_license_card_number\": \"<string>\",\n \"driver_license_state\": \"<string>\",\n \"driver_license_version\": \"<string>\",\n \"passport_number\": \"<string>\",\n \"passport_expiration_date\": \"2023-12-25\",\n \"passport_file_number\": \"<string>\",\n \"passport_issue_country\": \"<string>\",\n \"medicare_card_number\": \"<string>\",\n \"immi_card_number\": \"<string>\",\n \"immi_card_expiry_date\": \"2023-12-25\",\n \"citizenship_certificate_number\": \"<string>\",\n \"birth_registration_number\": \"<string>\",\n \"birth_registration_date\": \"2023-12-25\",\n \"birth_registration_state\": \"<string>\",\n \"marriage_certificate_number\": \"<string>\",\n \"change_of_name_certificate_number\": \"<string>\",\n \"first_partner_name\": \"<string>\",\n \"last_partner_name\": \"<string>\",\n \"voter_id\": \"<string>\",\n \"epic_card\": \"<string>\",\n \"pan\": \"<string>\",\n \"national_id\": \"<string>\",\n \"cic\": \"<string>\",\n \"identificador_ciudadano\": \"<string>\",\n \"ocr\": \"<string>\",\n \"voter_number\": \"<string>\",\n \"emission_number\": \"<string>\",\n \"bvn\": \"<string>\",\n \"bank_card_number\": \"<string>\",\n \"ssn\": \"<string>\",\n \"phone\": \"<string>\",\n \"landline\": \"<string>\",\n \"email\": \"jsmith@example.com\",\n \"country_of_residence\": \"US\",\n \"partial_match_action\": \"NO_ACTION\",\n \"no_match_action\": \"DECLINE\",\n \"save_api_request\": true,\n \"vendor_data\": \"<string>\",\n \"metadata\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://verification.didit.me/v3/database-validation/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"issuing_state\": \"BRA\",\n \"services\": [\n \"bra_cpf\"\n ],\n \"validation_type\": \"<string>\",\n \"consent\": false,\n \"identification_number\": \"<string>\",\n \"first_name\": \"John\",\n \"last_name\": \"Doe\",\n \"middle_name\": \"<string>\",\n \"full_name\": \"<string>\",\n \"date_of_birth\": \"1980-01-01\",\n \"personal_number\": \"<string>\",\n \"tax_number\": \"<string>\",\n \"document_number\": \"<string>\",\n \"expiration_date\": \"2030-01-15\",\n \"date_of_issue\": \"2015-06-20\",\n \"nationality\": \"<string>\",\n \"address\": {\n \"street_1\": \"<string>\",\n \"street_2\": \"<string>\",\n \"city\": \"<string>\",\n \"region\": \"<string>\",\n \"postal_code\": \"<string>\",\n \"country\": \"<string>\"\n },\n \"address_element_1\": \"<string>\",\n \"address_element_2\": \"<string>\",\n \"address_element_3\": \"<string>\",\n \"address_element_4\": \"<string>\",\n \"address_element_5\": \"<string>\",\n \"postal_code\": \"<string>\",\n \"driver_license_number\": \"<string>\",\n \"driver_license_card_number\": \"<string>\",\n \"driver_license_state\": \"<string>\",\n \"driver_license_version\": \"<string>\",\n \"passport_number\": \"<string>\",\n \"passport_expiration_date\": \"2023-12-25\",\n \"passport_file_number\": \"<string>\",\n \"passport_issue_country\": \"<string>\",\n \"medicare_card_number\": \"<string>\",\n \"immi_card_number\": \"<string>\",\n \"immi_card_expiry_date\": \"2023-12-25\",\n \"citizenship_certificate_number\": \"<string>\",\n \"birth_registration_number\": \"<string>\",\n \"birth_registration_date\": \"2023-12-25\",\n \"birth_registration_state\": \"<string>\",\n \"marriage_certificate_number\": \"<string>\",\n \"change_of_name_certificate_number\": \"<string>\",\n \"first_partner_name\": \"<string>\",\n \"last_partner_name\": \"<string>\",\n \"voter_id\": \"<string>\",\n \"epic_card\": \"<string>\",\n \"pan\": \"<string>\",\n \"national_id\": \"<string>\",\n \"cic\": \"<string>\",\n \"identificador_ciudadano\": \"<string>\",\n \"ocr\": \"<string>\",\n \"voter_number\": \"<string>\",\n \"emission_number\": \"<string>\",\n \"bvn\": \"<string>\",\n \"bank_card_number\": \"<string>\",\n \"ssn\": \"<string>\",\n \"phone\": \"<string>\",\n \"landline\": \"<string>\",\n \"email\": \"jsmith@example.com\",\n \"country_of_residence\": \"US\",\n \"partial_match_action\": \"NO_ACTION\",\n \"no_match_action\": \"DECLINE\",\n \"save_api_request\": true,\n \"vendor_data\": \"<string>\",\n \"metadata\": {}\n}"
response = http.request(request)
puts response.read_body{
"request_id": "7f9a1c0e-1f2b-4f6e-9d3a-2b1c0e7f9a1c",
"database_validation": {
"status": "Approved",
"issuing_state": "BRA",
"validation_type": "one_by_one",
"screened_data": {
"tax_number": "12345678900",
"first_name": "John",
"last_name": "Doe",
"date_of_birth": "1980-01-01"
},
"match_type": "full_match",
"validations": [
{
"validation": {
"full_name": "full_match",
"date_of_birth": "full_match",
"identification_number": "full_match"
},
"outcome_code": "MATCH",
"outcome_detail": "200",
"service_id": "bra_cpf",
"service_name": "Brazil - CPF status check",
"source_data": {
"identification_number": "12345678900",
"first_name": "JOHN",
"last_name": "DOE",
"date_of_birth": "1980-01-01",
"lgpd_minor": false,
"minor_under_16": false,
"minor_under_18": false
}
}
],
"warnings": []
},
"vendor_data": "user-1234",
"metadata": null,
"created_at": "2026-06-11T10:30:00.000000+00:00"
}Address-based services
For services that validate a residential or utility address, you can send a singleaddress and Didit will split it before processing the check. For the best match rate, send structured Didit address fields directly:
| Field | Meaning |
|---|---|
address_element_1 | Street address, including number and street type |
address_element_2 | Optional unit, building, floor, or extra address line |
address_element_3 | Suburb, district, locality, or neighborhood |
address_element_4 | City, town, state, province, or region |
address_element_5 | Postcode or postal code |
address value. postal_code is accepted as an alias for address_element_5.
Consent
Some database services require explicit end-user consent before the provider can be queried. The service catalog marks these rows withrequires_consent=true.
Send consent=true when the user consent applies to the selected services.
Didit rejects the request before any provider call or billing event if a selected service requires consent and you do not send it.
File uploads
Database validation usesmultipart/form-data. Biometric services that require selfie expose it as a file upload field in the API playground, so you can select an image directly instead of pasting a path or base64 string.
In code, upload the file with normal multipart syntax:
-F "selfie=@./selfie.jpg"
Validation errors
Didit validates required fields, address structure, and service-specific formats before calling the provider. For example, China registry services such aschn_national_id and chn_passport_verification expect full_name in the original Chinese script, and chn_national_id also requires a valid 15- or 18-character Chinese national ID with a correct checksum.
If a request cannot run, the API returns explicit field errors and no usage is billed. If a provider fails after preflight, the response includes validation_errors, and saved API requests store those errors in the database validation result.
Rejected input and unavailable results
When no service returns a usable result, inspect eachvalidation_errors entry before deciding whether to retry.
The HTTP status alone does not determine whether retrying is appropriate.
A 400 response with code: "provider_rejected_input" and retryable: false means every unanswered attempt explicitly refused the input.
Correct the supplied data before trying again.
These attempts are not billed.
A 502 response with code: "empty_provider_response" and retryable: true means the service could not produce a usable result for another reason.
This includes a refused input followed by an unavailable fallback or a fallback that provides no explanation.
Retry later; the response does not establish that the input is wrong.
If a database keeps failing, Didit emails the organizations that recently used it once the interruption is sustained, and again when real checks confirm it is answering — see Availability notifications.
When only some of the selected services fail, the request succeeds instead: the response is 200 and the failed services are listed under database_validation.errors[], each with the same code and retryable fields.
database_validation.status then follows the services that did answer and can be Approved, so inspect errors[] on every response and not only on a 4xx or 5xx.
A service reported there is absent from validations and services_used, and is not billed; retry that service on its own.
Other 502 errors can require corrected input.
For example, provider_invalid_input and provider_validation_error describe input the source rejected and must not be retried unchanged, even when the legacy response omits retryable.
The retry guidance for empty_provider_response does not apply to these codes.
A conclusive no-match result is a completed check, not an availability failure.Authorizations
Body
ISO 3166-1 alpha-3 country code of the registry to validate against (e.g. BRA, ESP, COL). Determines which services are available. Unsupported codes return 400 with the full list of valid options.
"BRA"
Catalog service_ids to run for this country (e.g. ["bra_cpf"]). Also accepts a single string or a comma-separated/JSON-encoded string. If omitted or empty, exactly one default service runs — the longest-established live service for the country; newer, biometric, and pay-as-you-go services must be named explicitly. Sending services switches the response to the extended shape (adds services_used and match_score). Every id must exist and be live for the issuing_state; services that require onboarding return 400 until activated for your organization. Discover available services per country via GET /v1/organization/database-validation-countries/ (a catalog endpoint not documented in this spec) or the Business Console workflow editor.
["bra_cpf"]
DEPRECATED. Accepted for backward compatibility but ignored — the response validation_type is now derived from how many services full-matched. Use services to pin specific services.
Set to true when the end user has explicitly consented to the selected validation services. Required for services flagged requires_consent=true in the catalog — without it those services return 400 with services_requiring_consent.
Universal identification number — automatically mapped to the correct country-specific field, so you can use it instead of personal_number/tax_number/document_number: ARG→document_number (DNI), BOL→document_number (CI), BRA→tax_number (CPF, 11 digits), CHL→personal_number (RUT), COL→personal_number (Cédula), CRI→personal_number (Cédula), DOM→personal_number (Cédula, 11 digits), ECU→personal_number (Cédula, 10 digits), ESP→personal_number (DNI/NIE), GTM→document_number (DPI), HND→document_number (DNI), MEX→personal_number (CURP, 18 chars), PAN→personal_number (Cédula), PER→personal_number (DNI, 8 digits), PRY→document_number (CI), SLV→document_number (DUI), URY→personal_number (CI), VEN→document_number (Cédula). It never overrides an explicitly provided country-specific field.
The individual's first name. Required by some services/countries.
"John"
The individual's last name. Required by some services/countries.
"Doe"
Middle name, used by some country services (AUS, NZL, …).
Full name — some services accept this in lieu of first/last name (e.g. CHN services, which match the native-script name).
Date of birth, YYYY-MM-DD. Required by many services.
"1980-01-01"
Government-issued unique personal identifier. Used by: CHL (RUT), COL (Cédula), CRI, DOM, ECU, ESP (DNI/NIE), MEX (CURP), PAN (Cédula), PER (DNI), URY. Consider identification_number instead.
Tax identification number. Used by: BRA (CPF, 11 digits). Consider identification_number instead.
Document number. Used by: ARG (DNI), BOL (CI), GTM (DPI), HND (DNI), PRY (CI), SLV (DUI), VEN (Cédula). Consider identification_number instead.
Type of document being validated: P passport, DL driver license, ID national ID, RP residence permit (plus SSC, HIC, WP, TC, VISA, PSC, BC, OTHER). Required by some services (e.g. ESP).
P, DL, ID, RP, SSC, HIC, WP, TC, VISA, PSC, BC, OTHER Document expiration date, YYYY-MM-DD. Required for ESP (Spain) validation.
"2030-01-15"
Document issue date, YYYY-MM-DD (fecha de expedición). Required for COL (Colombia) cédula validation.
"2015-06-20"
Nationality as ISO 3166-1 alpha-3. Required by some services.
Gender: M, F, or X (other/unknown). Required for Argentina's RENAPER validation (arg_renaper).
M, F, X Residential address. Prefer the structured object {"street_1":"123 Main St","street_2":"Apt 4B","city":"Springfield","region":"IL","postal_code":"62701","country":"US"}; a complete single-line string is still accepted. Required by address-verification services; when a service defines address requirements, missing parts return 400 with address_fields_required_by.
Show child attributes
Show child attributes
Street address including street number and type. If omitted, derived from address.
Apartment, unit, building, floor, or extra address line. Only send when you have it explicitly.
City, suburb, district, locality, or neighborhood. If omitted, derived from address.
State, province, region, or town. If omitted, derived from address.
Postcode or postal code. postal_code is accepted as an alias.
Postal code for address-based services (alias of address_element_5).
Driver licence number for government document-verification services (AUS, NZL, IND).
Physical driver licence card number, where required separately from the licence number (AUS).
Driver licence state or territory of issue (AUS).
Driver licence version code (NZL).
Passport number for government passport-verification services (AUS, NZL, IND, CHN).
Passport expiry date, YYYY-MM-DD, for passport-verification services.
Passport file number (IND).
Issuing country of the passport (ISO 3166-1 alpha-3) for passport-verification services.
Medicare card number (AUS).
Australian ImmiCard number.
Australian ImmiCard expiry date.
Citizenship certificate number (AUS).
Birth-certificate registration number (AUS).
Birth-certificate registration date (AUS).
Birth-certificate registration state (AUS).
Marriage certificate number (AUS).
Change-of-name certificate number (AUS).
First name of the partner on a marriage certificate (AUS).
Last name of the partner on a marriage certificate (AUS).
Voter registration number (IND EPIC, IRL).
India EPIC voter card number.
India PAN (Permanent Account Number).
National ID number (CHN, MYS, KEN, KHM, NGA, ZAF, …).
Mexican INE/IFE Código de Identificación de Credencial (CIC), 9 digits. Used by the MEX INE credential-validity service (mex_ine_vigencia).
Mexican INE Identificador del Ciudadano (9 digits). Used with cic for modern INE models (E/F/G/H) in mex_ine_vigencia.
Mexican INE OCR number (13 digits, back of card). Used with cic for Model D in mex_ine_vigencia.
Mexican INE Clave de Elector (18 chars). Used with emission_number for legacy IFE models (A/B/C) in mex_ine_vigencia.
Mexican INE Número de Emisión. Used with voter_number for legacy IFE models (A/B/C) in mex_ine_vigencia.
Nigerian Bank Verification Number.
Bank card number (CHN bank-card verification).
Social Security Number (USA).
Phone number for phone-verification services.
Landline number for phone-verification services.
Email address for identity-verification services.
ISO 3166-1 alpha-2 country of residence. Used by global identity-enrichment services (e.g. glb_identity_enrichment) to focus the lookup.
"US"
What a partial_match does to database_validation.status. Defaults to NO_ACTION (status stays Approved, with a warning).
DECLINE, NO_ACTION What a no_match does to database_validation.status. Defaults to DECLINE.
DECLINE, NO_ACTION Persist the validation as a session (console visibility, decision endpoint, status.updated webhook). Also changes the validations response shape: per-service objects when true (default), a merged field map when false.
Your identifier for the validated user; echoed back and stored with the session.
Free-form JSON stored with the request and echoed back.
Response
Validation completed — at least one selected service returned a usable result. Inspect database_validation.match_type for the aggregate outcome, validations for the per-service field comparisons and outcome_codes, and errors (when present) for services that failed.
Persisted session id when save_api_request=true (usable with GET /v3/session/{sessionId}/decision/); otherwise a transient correlation UUID.
Show child attributes
Show child attributes
Echo of the vendor_data you sent.
Echo of the metadata you sent.