> ## 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 vérification Unico IDCloud Brésil (CPF + selfie)

> Validation en base de données au Brésil avec Didit : CPF + selfie via Unico IDCloud. À partir de $0.20 par appel, sans contrat ni minimum.

Validation biométrique Unico IDCloud : compare le selfie de l'utilisateur au visage enregistré pour son CPF et indique s'il s'agit de la même personne, d'une personne différente ou si le résultat est non concluant. Didit expose ce service via `POST /v3/database-validation/` afin de vérifier les données soumises auprès de la source faisant autorité et de recevoir des résultats de correspondance normalisés. Format de saisie : `tax_number` accepte le CPF brésilien (exactement 11 chiffres).

## Couverture

* **Couverture :** 96%
* **Pays :** Brésil
* **ID du service :** `bra_unico_idcloud`
* **Domaine de données :** Identité
* **Catégorie :** BiometricRiskScore

Environ 96% des titulaires d'un CPF brésilien disposent d'une fiche biométrique dans le registre d'Unico, soit environ le double de la portée de la source gouvernementale de correspondance faciale, [Datavalid](https://docs.didit.me/fr/api-reference/database-validation/brazil/cpf-facial.md), qui atteint environ 50%.

## Entrées

| Champ | Obligatoire | Exemple |
| - | -: | - |
| `tax_number` | Oui | `11111111111` |
| `selfie` | Oui | `@./selfie.jpg` |
| `first_name` | Non | `John` |
| `last_name` | Non | `Doe` |
| `full_name` | Non | `John Doe` |
| `date_of_birth` | Non | `1990-01-01` |
| `vendor_data` | Non | `user-1234` |

* **Entrées obligatoires :** `tax_number`, `selfie`
* **Entrées facultatives :** `first_name`, `last_name`, `full_name`, `date_of_birth`, `vendor_data`
* **Consentement :** requis
* **Disponibilité dans un workflow :** disponible dans un workflow
* **Couverture :** 96%
* **Prix :** \$0.20 par requête réussie

## Paramètres du corps

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

Code pays ISO 3166-1 alpha-3 de ce service de base de données.

Exemple : `BRA`

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

Tableau contenant l'ID de ce service. Fixer le service permet de limiter la requête à cette base de données précise.

Exemple : `bra_unico_idcloud`

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

Consentement explicite de l'utilisateur final pour ce service.

Exemple : `true`

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

Numéro d'identification fiscale.

Exemple : `11111111111`

**selfie** `file` *required*

Fichier image du selfie à envoyer pour la validation biométrique en base de données. Formats acceptés : JPEG, PNG ou WebP.

Exemple : `@./selfie.jpg`

**first\_name** `string`

Prénom à valider.

Exemple : `John`

**last\_name** `string`

Nom de famille à valider.

Exemple : `Doe`

**full\_name** `string`

Nom légal complet à valider.

Exemple : `John Doe`

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

Date de naissance au format `YYYY-MM-DD`.

Exemple : `1990-01-01`

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

Votre référence utilisateur stable pour cette personne, par exemple votre identifiant interne. Didit l'utilise pour relier les vérifications autonomes au même utilisateur final et réduire le bruit de détection des doublons.

Exemple : `user-1234`

## Règles de saisie et notes de validation

* CPF brésilien (exactement 11 chiffres)
* `tax_number` ne doit contenir que des chiffres : retirez les espaces, tirets et signes de ponctuation avant d'envoyer la requête.
* `tax_number` doit comporter exactement 11 caractères.

## Comment l'appeler

```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));
```

Chaque appel réussi renvoie HTTP `200`. Le champ **`outcome_code`** indique ce qui s'est réellement passé, en distinguant par exemple une véritable absence de correspondance biométrique (`BIOMETRIC_NO_MATCH`) d'un selfie impossible à lire (`BIOMETRIC_IMAGE_UNUSABLE`). Le `status` affiché est le statut par défaut de la fonctionnalité ; vos [actions Partial Match / No Match](https://docs.didit.me/fr/core-technology/database-validation/database-validation-warnings.md) configurées peuvent le remplacer.

**`MATCH`** : le registre a confirmé l'identité et tous les champs vérifiés correspondaient.

```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`** : le score de correspondance faciale était inférieur au seuil d'acceptation. Le selfie ne correspond pas à la photo du registre.

```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`** : le registre n'a pas pu déterminer si la personne correspond. Le résultat est réellement incertain : la personne figure peut-être ou non dans le registre. Ce n'est ni une absence de correspondance, ni un problème technique lié à l'image. Aucun champ n'est validé, donc match\_type est null et la vérification est envoyée en examen manuel.

```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": {}
    }
  ]
}
```

## Données renvoyées

Les champs exacts présents dans `source_data` dépendent de ce que renvoie le registre. L'exemple généré pour `bra_unico_idcloud` documente actuellement cette structure normalisée :

* `unico_face_match`

## Tarifs et SLA

Les requêtes BRA - Unico IDCloud (CPF + selfie) ne sont facturées que lorsque Didit reçoit un résultat concluant de la source de validation.

* **Prix par appel :** \$0.20 USD.
* **Facturation :** par requête réussie. Vous n'êtes pas facturé lorsque le registre est injoignable, lorsque des champs obligatoires manquent ou lorsque la requête est rejetée avant d'atteindre la source.
* **Latence :** p95 typique \< 2 s.
* **Disponibilité :** 99.9% par trimestre côté Didit ; la disponibilité de la source en aval varie selon le pays et le jeu de données.

## À propos de cette source

[Unico](https://unico.io) est une société d'identité brésilienne (IDtech) qui exploite le plus grand registre privé de données biométriques faciales du pays. Sa plateforme IDCloud contient plus d'un milliard d'embeddings faciaux et ajoute environ 35 millions de nouveaux visages chaque mois, alimentée par les flux d'onboarding et de réauthentification de plus de 800 entreprises brésiliennes, dont quatre des cinq plus grandes banques. Cette échelle explique le taux de couverture indiqué plus haut : une recherche par CPF correspond à un enregistrement biométrique pour environ 96 % des adultes brésiliens.

Didit dispose d'un partenariat direct avec Unico. Vous pouvez donc interroger IDCloud via l'API standard de Validation en base de données, avec une facturation à l'appel, sans contrat distinct avec Unico, sans volume minimum et sans processus d'onboarding.

**En quoi cela diffère du registre gouvernemental.** Didit propose également [Brésil - CPF + correspondance faciale (Datavalid)](https://docs.didit.me/fr/api-reference/database-validation/brazil/cpf-facial.md), qui s'appuie sur la source officielle du SERPRO et constitue le bon choix lorsque vous avez expressément besoin du registre gouvernemental comme source de référence. IDCloud est en revanche le choix le plus pertinent dans tous les autres cas, selon deux critères que vous pouvez vérifier : il couvre environ 96 % des adultes, contre environ 50 % pour Datavalid, et il effectue la correspondance avec un enregistrement biométrique tenu à jour par le registre lui-même, et non avec un portrait tiré d'un document que l'utilisateur vous fournit. Il résiste ainsi à la falsification de documents comme à la fraude au CPF volé. Enfin, son coût par requête est inférieur de plus de moitié.

## Parcours recommandé pour le Brésil

Pour la plupart des cas d'usage au Brésil, vous n'avez pas du tout besoin de capture de document. L'utilisateur vous fournit un CPF, et un selfie soumis à une détection du vivant confirme qu'il s'agit bien de la personne liée à ce CPF.

**1. Collecter le CPF**

Votre seule saisie textuelle est le CPF à 11 chiffres : aucune photo de document, ni nom ni date de naissance saisis manuellement.

Comme aucun document n'est lu dans ce parcours, Didit n'a aucune source pour le CPF tant que vous n'indiquez pas d'où il provient. Transmettez-le dans `metadata` de la session lors de sa création, puis associez-le à l'entrée `tax_number` de l'étape Validation en base de données. Dans la Business Console, cela se fait dans le mappage des entrées de l'étape ; via l'API des workflows, il s'agit de `database_validation_field_sources` du nœud :

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

Créez ensuite chaque session avec la valeur sous cette clé :

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

Sans ce mappage, l'étape s'exécute quand même, mais elle signale `tax_number` comme manquant et n'interroge jamais le registre : rien n'est facturé, et l'entrée `database_validations` de la session indique la raison.

**2. Capturer le selfie avec une détection du vivant**

Ajoutez une étape de [détection du vivant](https://docs.didit.me/fr/core-technology/liveness/overview.md) au même workflow et choisissez la méthode adaptée à votre niveau de risque : **Détection du vivant passive** (aucune action de l'utilisateur), **Flash 3D** ou **Action 3D et Flash** (méthodes actives qui projettent des motifs lumineux, la dernière ajoutant une action aléatoire). Définissez-la avec `face_liveness_method` (`PASSIVE`, `FLASHING` ou `ACTIVE_3D`) dans la Business Console ou via l'API des workflows. Quelle que soit la méthode, Didit affiche l'étape de capture et confirme la présence d'une personne réelle : c'est ce qui empêche la soumission d'une photo enregistrée ou d'une relecture d'écran.

**3. Valider le CPF et le selfie auprès d'Unico IDCloud**

Dans un parcours de session, Didit réutilise automatiquement le selfie de détection du vivant (vous ne manipulez jamais l'image) et lit le CPF grâce au mappage ci-dessus. IDCloud vérifie alors si ce visage appartient à la personne à laquelle le CPF est rattaché. L'étape n'a besoin que de ces deux entrées ; si vous envoyez aussi `full_name` ou `date_of_birth` dans `metadata` et que vous les mappez, ils sont transmis à Unico comme contrôles croisés, mais ils ne sont pas obligatoires.

> [!NOTE]
>
> Ce parcours ne nécessitant que le CPF s'applique aux intégrations **session et workflow**, où Didit effectue la capture et transmet le selfie de détection du vivant à ce service à votre place. Si vous appelez **directement** `POST /v3/database-validation/`, `selfie` est un fichier obligatoire que vous fournissez vous-même ; consultez la [vue d'ensemble de la Validation en base de données](https://docs.didit.me/fr/core-technology/database-validation/overview.md) pour les deux modes.

**Coût :** environ \$0.30 par utilisateur vérifié avec la **Détection du vivant passive** (\$0.20 pour la requête IDCloud et \$0.10 pour la détection du vivant), ou environ \$0.35 avec une méthode active, où la détection du vivant coûte \$0.15. Ce sont des tarifs publics : la remise de votre forfait s'applique à chacun d'eux ; voir [tarifs](https://docs.didit.me/fr/getting-started/pricing.md).

**Solution de repli pour les quelque 4 % sans couverture.** Lorsque IDCloud renvoie `INCONCLUSIVE`, le registre n'a pas pu rattacher ce CPF à un enregistrement biométrique exploitable, généralement parce que la personne n'y figure pas. Traitez ce cas comme une « absence de réponse » et non comme une vérification échouée, puis basculez vers la [Vérification d'identité](https://docs.didit.me/fr/core-technology/id-verification/overview.md) complète : capture du document et correspondance faciale avec le portrait du document. Tous les utilisateurs restent vérifiables, et vous ne payez la vérification de document que pour la petite partie restante.

**Gestion des refus.** `BIOMETRIC_NO_MATCH` signifie que le registre a explicitement indiqué une absence de correspondance : le visage n'appartient pas à ce CPF. Ne le traitez pas comme un signal à réessayer, mais comme un fort indice négatif : envoyer l'utilisateur directement vers la capture de document est exactement le chemin qu'un usurpateur recherche, puisque le document est l'élément qu'il contrôle. Les faux négatifs véritables existent toutefois : apparence modifiée, ancienne photo dans le registre ou capture de mauvaise qualité. Orientez donc ces cas vers un examen manuel, plutôt que de les approuver automatiquement ou de bloquer l'utilisateur. `BIOMETRIC_IMAGE_UNUSABLE` est différent : le selfie n'a tout simplement pas pu être lu ; demandez-en un nouveau. Définissez l'effet de chaque résultat sur la session avec les [actions Partial Match / No Match](https://docs.didit.me/fr/core-technology/database-validation/database-validation-warnings.md), et consultez les [codes de résultat](https://docs.didit.me/fr/core-technology/database-validation/database-validation-outcome-codes.md) pour la liste complète.

**Utilisateurs qui reviennent.** Vous ne payez une consultation du registre qu'une seule fois. Une fois qu'un utilisateur a réussi ce parcours, le selfie de détection du vivant est enregistré dans son `vendor_data`, ce qui vous permet de le revérifier plus tard avec l'[authentification biométrique](https://docs.didit.me/fr/core-technology/biometric-auth/overview.md) (détection du vivant plus correspondance faciale avec ce visage enregistré) pour \$0.10, avec le même choix de méthodes de détection du vivant. Notez que cela concerne spécifiquement les utilisateurs **récurrents** : une session d'authentification biométrique nécessite un visage enregistré (ou un `portrait_image` que vous fournissez) et échoue à la création si l'utilisateur n'en a aucun, donc les nouveaux utilisateurs passent d'abord par le parcours ci-dessus.

## Pour aller plus loin

* [Vue d'ensemble de la Validation en base de données pour le Brésil](https://docs.didit.me/api-reference/database-validation/brazil.md)
* [Vue d'ensemble de la Validation en base de données](https://docs.didit.me/fr/core-technology/database-validation/overview.md)
* [Codes de résultat](https://docs.didit.me/fr/core-technology/database-validation/database-validation-outcome-codes.md)


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