> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# API CPF + coincidencia facial Brasil (Datavalid)

> CPF + coincidencia facial (Datavalid) en Brasil con Didit: consulta a base de datos oficial. Desde $0.45 por consulta, sin contratos ni mínimos.

SERPRO Datavalid v4 pf-facial: valida el CPF (obligatorio) contra la Receita Federal y compara la selfie en vivo (obligatoria) con la foto de la CNH almacenada en Senatran. Opcionalmente, verifica el nombre y la fecha de nacimiento. Didit ofrece este servicio a través de `POST /v3/database-validation/` para que puedas verificar los datos enviados contra la fuente oficial y recibir resultados de coincidencia normalizados.

## Cobertura

* **Cobertura:** \~50%
* **País:** Brasil
* **ID del servicio:** `bra_cpf_facial`
* **Dominio de datos:** Biométrico
* **Categoría:** NationalIDRegistry

Aproximadamente el 50% de los adultos brasileños pueden compararse, ya que el paso de coincidencia facial se basa en la foto de la CNH que conserva Senatran, por lo que solo se puede comparar a titulares de licencia de conducir.

## Datos de entrada

| Campo | Obligatorio | Ejemplo |
| - | -: | - |
| `tax_number` | Sí | `11111111111` |
| `selfie` | Sí | `@./selfie.jpg` |
| `first_name` | No | `John` |
| `last_name` | No | `Doe` |
| `date_of_birth` | No | `1990-01-01` |
| `vendor_data` | No | `user-1234` |

* **Datos obligatorios:** `tax_number`, `selfie`
* **Datos opcionales:** `first_name`, `last_name`, `date_of_birth`, `vendor_data`
* **Consentimiento:** Obligatorio
* **Disponibilidad en flujos:** Disponible en el workflow
* **Cobertura:** \~50%
* **Precio:** \$0.45 por consulta exitosa

## Parámetros del cuerpo

**issuing\_state** `string` *required* (default: BRA)

Código de país ISO 3166-1 alfa-3 de este servicio de base de datos.

Ejemplo: `BRA`

**services** `string` *required* (default: bra\_cpf\_facial)

Array que contiene este ID de servicio. Fijar el servicio limita la solicitud a esta base de datos concreta.

Ejemplo: `bra_cpf_facial`

**consent** `boolean` *required* (default: true)

Consentimiento explícito del usuario final para este servicio.

Ejemplo: `true`

**tax\_number** `string` *required* (default: 11111111111)

Número de identificación fiscal o tributaria.

Ejemplo: `11111111111`

**selfie** `file` *required*

Archivo de imagen de la selfie que se sube para la validación con la base de datos biométrica. Formatos aceptados: JPEG, PNG o WebP.

Ejemplo: `@./selfie.jpg`

**first\_name** `string`

Nombre de pila que se va a validar.

Ejemplo: `John`

**last\_name** `string`

Apellido que se va a validar.

Ejemplo: `Doe`

**date\_of\_birth** `string`

Fecha de nacimiento en formato `YYYY-MM-DD`.

Ejemplo: `1990-01-01`

**vendor\_data** `string` (default: user-1234)

Tu referencia estable de usuario para esta persona, como tu ID de usuario interno. Didit la usa para vincular las comprobaciones independientes al mismo usuario final y reducir el ruido en la detección de duplicados.

Ejemplo: `user-1234`

## Reglas de entrada y notas de validación

* CPF brasileño (exactamente 11 dígitos)
* `tax_number` solo debe contener dígitos; elimina espacios, guiones y signos de puntuación antes de enviar la solicitud.
* `tax_number` debe tener exactamente 11 caracteres.

## Cómo invocarlo

```bash cURL theme={null}
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"
```

```python Python theme={null}
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)
```

```javascript Node.js theme={null}
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);
```

```go Go theme={null}
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)
```

```java Java theme={null}
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 PHP theme={null}
<?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());
```

```ruby Ruby theme={null}
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
```

```csharp .NET theme={null}
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));
```

Toda llamada exitosa devuelve HTTP `200`. El campo **`outcome_code`** te indica lo que ocurrió realmente; distingue, por ejemplo, una discrepancia biométrica real (`BIOMETRIC_NO_MATCH`) de una selfie que no se pudo leer (`BIOMETRIC_IMAGE_UNUSABLE`). El `status` que se muestra es el estado predeterminado de la función; las [acciones de Partial Match / No Match](https://docs.didit.me/es/core-technology/database-validation/database-validation-warnings.md) que hayas configurado pueden sustituirlo.

**`MATCH`**: el registro confirmó la identidad y todos los campos comprobados coincidieron.

```json 200 OK — MATCH theme={null}
{
  "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`**: el registro no devolvió ninguna coincidencia para los datos enviados.

```json 200 OK — NO_MATCH theme={null}
{
  "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`**: la puntuación de coincidencia facial quedó por debajo del umbral de aceptación; la persona de la selfie no es la misma que la de la foto del registro.

```json 200 OK — BIOMETRIC_NO_MATCH theme={null}
{
  "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`**: no se pudo procesar la selfie (vacía, sin rostro, de baja calidad o el registro no pudo leerla). Pide al usuario que vuelva a tomar la selfie.

```json 200 OK — BIOMETRIC_IMAGE_UNUSABLE theme={null}
{
  "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`**: el registro confirmó el CPF (y el nombre y la fecha de nacimiento que enviaste), pero no se pudo comparar el rostro: no hay foto de referencia registrada para este CPF o no se pudo usar la selfie (no se encontró ningún rostro, tamaño de imagen incorrecto, baja calidad o más de un rostro). Los campos confirmados se mantienen en `validation`, por lo que `match_type` los refleja, pero la comprobación facial obligatoria queda sin resolver, así que la comprobación se envía a revisión. Pide una nueva selfie o recurre a la verificación de documentos para las personas sin foto registrada.

```json 200 OK — INCONCLUSIVE theme={null}
{
  "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"
      }
    }
  ]
}
```

## Datos devueltos

Los campos exactos que aparecen en `source_data` dependen de lo que devuelva el registro. El ejemplo generado para `bra_cpf_facial` documenta actualmente esta estructura normalizada:

* `date_of_birth`
* `first_name`
* `identification_number`
* `last_name`
* `name_match_score`

## Precios y SLA

Las consultas de Brasil - CPF + coincidencia facial (Datavalid) solo se facturan cuando Didit recibe un resultado concluyente de la fuente de validación.

* **Precio por llamada:** \$0.45 USD.
* **Facturación:** por consulta exitosa. No se te cobra cuando no se puede acceder al registro, cuando faltan campos obligatorios o cuando la solicitud se rechaza antes de llegar a la fuente.
* **Latencia:** p95 habitual \< 2 s.
* **Disponibilidad:** 99.9% por trimestre por parte de Didit; la disponibilidad de la fuente externa varía según el país y el conjunto de datos.

## Acerca de esta fuente

Esta es la fuente oficial del gobierno: [SERPRO](https://www.serpro.gov.br) Datavalid, operada por el servicio federal de procesamiento de datos de Brasil. El CPF se verifica con la Receita Federal, y la selfie se compara con el retrato que consta para esa persona en Senatran, el registro nacional de licencias de conducir.

Como el retrato procede del registro de la CNH (licencia de conducir), solo las personas que tienen una CNH tienen una foto registrada. Eso es lo que limita la cobertura a aproximadamente el 50% de la población adulta: los datos son oficiales, pero no están disponibles para los brasileños que nunca han tenido licencia de conducir.

**¿Necesitas una cobertura más amplia?** Usa [BRA - Unico IDCloud (CPF + selfie)](https://docs.didit.me/es/api-reference/database-validation/brazil/unico-idcloud.md) en su lugar. Llega a cerca del 96% de los adultos brasileños a través del registro biométrico privado de Unico, y cuesta \$0.20 frente a \$0.45 de esta fuente. Elige Datavalid cuando necesites específicamente que el registro del gobierno sea tu fuente de referencia; elige IDCloud cuando necesites verificar a todo el mundo.

## Continúa leyendo

* [Visión general de la validación de bases de datos de Brasil](https://docs.didit.me/api-reference/database-validation/brazil.md)
* [Visión general de la validación de bases de datos](https://docs.didit.me/es/core-technology/database-validation/overview.md)
* [Códigos de resultado](https://docs.didit.me/es/core-technology/database-validation/database-validation-outcome-codes.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.