> ## 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 de verificación BRA - Unico IDCloud (CPF + selfie)

> BRA - Unico IDCloud (CPF + selfie): consulta en base de datos oficial de Brasil con Didit. Pago por uso desde $0.20, sin contratos ni mínimos.

Validación biométrica de Unico IDCloud: compara la selfie del usuario con el rostro asociado a su CPF y devuelve si se trata de la misma persona, de una persona distinta o si el resultado no es concluyente. 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:** 96%
* **País:** Brasil
* **ID del servicio:** `bra_unico_idcloud`
* **Dominio de datos:** Identidad
* **Categoría:** BiometricRiskScore

Alrededor del 96% de los titulares de CPF brasileños se resuelven en un registro biométrico en el registro de Unico, aproximadamente el doble del alcance de la fuente gubernamental de coincidencia facial, [Datavalid](https://docs.didit.me/es/api-reference/database-validation/brazil/cpf-facial.md), que ronda el 50%.

## Datos de entrada

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

* **Datos obligatorios:** `tax_number`, `selfie`
* **Datos opcionales:** `first_name`, `last_name`, `full_name`, `date_of_birth`, `vendor_data`
* **Consentimiento:** Obligatorio
* **Disponibilidad en flujos de verificación (workflow):** Disponible en flujos
* **Cobertura:** 96%
* **Precio:** \$0.20 por consulta exitosa

## Parámetros del cuerpo

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

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

Ejemplo: `BRA`

**services** `string` *required* (default: bra\_unico\_idcloud)

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

Ejemplo: `bra_unico_idcloud`

**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 biométrica en la base de datos. 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`

**full\_name** `string`

Nombre legal completo que se va a validar.

Ejemplo: `John 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 con el 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` debe contener solo 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_unico_idcloud" \
  -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_unico_idcloud"],
    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_unico_idcloud"],
  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_unico_idcloud"}),
	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_unico_idcloud"))
        .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_unico_idcloud'],
    '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_unico_idcloud"],
  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_unico_idcloud" },
    Consent = true,
    TaxNumber = "11111111111",
    VendorData = "user-1234",
    Selfie = FileUpload.FromPath("selfie.jpg"),
});
Console.WriteLine(JsonSerializer.Serialize(result));
```

Toda solicitud exitosa devuelve HTTP `200`. El campo **`outcome_code`** te indica qué ocurrió realmente; distingue, por ejemplo, una falta de coincidencia 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) configuradas pueden sobrescribirlo.

**`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_unico_idcloud",
      "service_name": "BRA - Unico IDCloud (CPF + selfie)",
      "source_data": {
        "unico_face_match": "yes"
      },
      "validation": {
        "identification_number": "full_match"
      }
    }
  ]
}
```

**`BIOMETRIC_NO_MATCH`**: la puntuación de coincidencia facial quedó por debajo del umbral de aceptación; la selfie no corresponde a la misma persona que 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_unico_idcloud",
      "service_name": "BRA - Unico IDCloud (CPF + selfie)",
      "source_data": {
        "identification_number": "NO_MATCH"
      },
      "validation": {
        "identification_number": "no_match"
      }
    }
  ]
}
```

**`INCONCLUSIVE`**: el registro no pudo determinar si la persona coincide; el resultado es realmente incierto (puede que la persona esté o no en el registro). NO es una falta de coincidencia ni un problema técnico de la imagen; no se afirma ningún campo, por lo que match\_type es null y la comprobación se envía a revisión.

```json 200 OK — INCONCLUSIVE theme={null}
{
  "request_id": "req_01H…",
  "status": "In Review",
  "issuing_state": "BRA",
  "match_type": null,
  "validations": [
    {
      "outcome_code": "INCONCLUSIVE",
      "service_id": "bra_unico_idcloud",
      "service_name": "BRA - Unico IDCloud (CPF + selfie)",
      "source_data": {},
      "validation": {}
    }
  ]
}
```

## Datos devueltos

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

* `unico_face_match`

## Precios y SLA

Las consultas a BRA - Unico IDCloud (CPF + selfie) se facturan solo cuando Didit recibe un resultado concluyente de la fuente de validación.

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

## Acerca de esta fuente

[Unico](https://unico.io) es una empresa brasileña de IDtech que opera el mayor registro privado de biometría facial del país. Su plataforma IDCloud almacena más de mil millones de embeddings faciales y suma unos 35 millones de rostros nuevos cada mes, alimentada por los flujos de onboarding y reautenticación de más de 800 empresas brasileñas, entre ellas cuatro de los cinco mayores bancos. Esa escala es la que explica la cifra de cobertura indicada arriba: una consulta por CPF devuelve un registro biométrico para aproximadamente el 96% de los adultos brasileños.

Didit tiene una alianza directa con Unico, así que puedes consultar IDCloud a través de la API estándar de Validación de base de datos: pagas por llamada, sin contrato aparte con Unico, sin volumen mínimo y sin proceso de onboarding.

**En qué se diferencia del registro gubernamental.** Didit también ofrece [Brasil - CPF + coincidencia facial (Datavalid)](https://docs.didit.me/es/api-reference/database-validation/brazil/cpf-facial.md), que es la fuente oficial de SERPRO y la opción adecuada cuando necesitas específicamente que el registro gubernamental sea tu fuente de verdad. IDCloud es la mejor opción para todo lo demás, en dos aspectos que puedes comprobar: llega a aproximadamente el 96% de los adultos frente a aproximadamente el 50% de Datavalid, y compara contra un registro biométrico que mantiene IDCloud, en lugar de contra un retrato tomado de un documento que te entrega el usuario, por lo que resiste tanto la falsificación de documentos como el fraude con CPF robados. Además, cuesta menos de la mitad por consulta.

## Flujo recomendado para Brasil

En la mayoría de los casos de uso en Brasil no necesitas captura de documentos. El usuario te proporciona un CPF y una selfie con prueba de vida confirma que es la persona a la que corresponde.

**1. Recopila el CPF**

Tu única entrada de texto es el CPF de 11 dígitos: sin foto del documento y sin nombre ni fecha de nacimiento introducidos manualmente.

Como en este flujo no se lee ningún documento, Didit no tiene de dónde obtener el CPF a menos que le indiques su origen. Envíalo en el `metadata` de la sesión al crearla y asígnalo como la entrada `tax_number` del paso de Validación de base de datos. En la Business Console, esto se hace en la asignación de entradas del paso; a través de la API de flujos, es el `database_validation_field_sources` del nodo:

```json theme={null}
{
  "database_validation_countries": {"BRA": {"services": ["bra_unico_idcloud"]}},
  "database_validation_field_sources": {
    "tax_number": {"source": "expected_data", "key": "metadata.cpf"}
  }
}
```

Después, crea cada sesión con el valor bajo esa clave:

```json theme={null}
{"workflow_id": "<workflow_id>", "metadata": {"cpf": "12345678909"}}
```

Sin la asignación, el paso se ejecuta igualmente, pero informa que falta `tax_number` y nunca consulta el registro: no se factura nada, y la entrada `database_validations` de la sesión incluye el motivo.

**2. Captura la selfie con prueba de vida**

Añade un paso de [prueba de vida](https://docs.didit.me/es/core-technology/liveness/overview.md) al mismo flujo y elige el método que se ajuste a tu tolerancia al riesgo: **Prueba de vida pasiva** (sin ninguna acción del usuario), **Flash 3D** o **Acción 3D y Flash** (métodos activos que proyectan patrones de luz; el último añade una acción aleatoria). Configúralo con `face_liveness_method` (`PASSIVE`, `FLASHING` o `ACTIVE_3D`) en la Business Console o a través de la API de flujos. Elijas el que elijas, Didit muestra el paso de captura y confirma que se trata de una persona real y presente: esto es lo que impide que se envíe una foto almacenada o la reproducción de una pantalla.

**3. Valida el CPF y la selfie con Unico IDCloud**

Dentro de un flujo de sesión, Didit reutiliza automáticamente la selfie de la prueba de vida (nunca manejas la imagen) y lee el CPF a partir de la asignación anterior. Después, IDCloud confirma si ese rostro pertenece a la persona titular del CPF. El paso solo necesita estas dos entradas; si además envías `full_name` o `date_of_birth` en `metadata` y los asignas, se pasan a Unico como verificaciones cruzadas, pero no son obligatorios.

> [!NOTE]
>
> Este flujo basado solo en el CPF se aplica a las integraciones de **sesión y flujo**, en las que Didit realiza la captura y pasa la selfie de la prueba de vida a este servicio en tu nombre. Si llamas a `POST /v3/database-validation/` **directamente**, `selfie` es una entrada de archivo obligatoria y debes proporcionar la imagen tú mismo; consulta la [descripción general de Validación de base de datos](https://docs.didit.me/es/core-technology/database-validation/overview.md) para ver ambos modos.

**Coste:** unos \$0.30 por usuario verificado con Prueba de vida pasiva (\$0.20 por la consulta a IDCloud más \$0.10 por la prueba de vida), o unos \$0.35 con un método activo, en el que la prueba de vida cuesta \$0.15. Son precios de lista: el descuento de tu plan se aplica a cada uno de ellos; consulta los [precios](https://docs.didit.me/es/getting-started/pricing.md).

**Alternativa para el 4% aproximado sin cobertura.** Cuando IDCloud devuelve `INCONCLUSIVE`, el registro no pudo asociar ese CPF a un registro biométrico utilizable, normalmente porque la persona no figura en él. Trátalo como una "respuesta no concluyente" y no como una verificación fallida, y recurre a la [Verificación de identidad](https://docs.didit.me/es/core-technology/id-verification/overview.md) completa: captura del documento más coincidencia facial con el retrato del documento. Todos siguen pudiendo verificarse, y solo pagas la verificación de documentos para el pequeño resto.

**Gestión de rechazos.** `BIOMETRIC_NO_MATCH` significa que el registro determinó activamente que no hay coincidencia: el rostro no pertenece a ese CPF. Trátalo como un resultado negativo sólido y no como una invitación a reintentar: enviar al usuario directamente a la captura de documentos es justo el camino que quiere un impostor, ya que el documento es el elemento que controla. Aun así, los falsos negativos genuinos ocurren (un cambio de apariencia, una foto antigua en el registro o una captura deficiente), así que deriva estos casos a revisión manual en lugar de aprobarlos automáticamente o dejar al usuario sin salida. `BIOMETRIC_IMAGE_UNUSABLE` es distinto: simplemente no se pudo leer la selfie, así que pide una nueva. Decide qué efecto tiene cada resultado en la sesión con las [acciones de Partial Match / No Match](https://docs.didit.me/es/core-technology/database-validation/database-validation-warnings.md), y consulta los [códigos de resultado](https://docs.didit.me/es/core-technology/database-validation/database-validation-outcome-codes.md) para ver la lista completa.

**Usuarios recurrentes.** Solo necesitas pagar una consulta al registro una vez. Cuando un usuario supera este flujo, la selfie de la prueba de vida se almacena asociada a su `vendor_data`, de modo que más adelante puedes volver a verificarlo con [Autenticación biométrica](https://docs.didit.me/es/core-technology/biometric-auth/overview.md) (una prueba de vida más una coincidencia facial con ese rostro almacenado) por \$0.10, con la misma elección de métodos de prueba de vida. Ten en cuenta que esto es específicamente para usuarios **recurrentes**: una sesión de autenticación biométrica necesita un rostro almacenado (o un `portrait_image` que tú proporciones) y falla al crearse si el usuario no tiene ninguno de los dos, por lo que los usuarios nuevos siguen pasando por el flujo anterior.

## Continúa leyendo

* [Descripción general de Validación de base de datos en Brasil](https://docs.didit.me/api-reference/database-validation/brazil.md)
* [Descripción general de Validación de base 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.