> ## 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.

# Verifikasi CPF Brasil dengan Unico IDCloud + Swafoto API

> BRA - Unico IDCloud (CPF + swafoto): pencarian database otoritatif Brasil via Didit. Bayar per panggilan mulai $0.20, tanpa kontrak, tanpa minimum.

Validasi biometrik Unico IDCloud: mencocokkan swafoto pengguna dengan wajah yang tercatat untuk CPF-nya dan mengembalikan apakah itu orang yang sama, bukan orang yang sama, atau tidak konklusif. Didit menyediakan layanan ini melalui `POST /v3/database-validation/` agar Anda dapat memverifikasi data yang dikirim terhadap sumber otoritatif dan menerima hasil pencocokan yang dinormalisasi. Format input: `tax_number` menerima CPF Brasil (tepat 11 digit).

## Cakupan

* **Cakupan:** 96%
* **Negara:** Brasil
* **ID layanan:** `bra_unico_idcloud`
* **Domain data:** Identitas
* **Kategori:** BiometricRiskScore

Sekitar 96% pemegang CPF Brasil terhubung ke catatan biometrik di registri Unico. Jangkauannya kira-kira dua kali lipat sumber pencocokan wajah pemerintah, [Datavalid](https://docs.didit.me/id/api-reference/database-validation/brazil/cpf-facial.md), yang sekitar 50%.

## Input

| Kolom | Wajib | Contoh |
| - | -: | - |
| `tax_number` | Ya | `11111111111` |
| `selfie` | Ya | `@./selfie.jpg` |
| `first_name` | Tidak | `John` |
| `last_name` | Tidak | `Doe` |
| `full_name` | Tidak | `John Doe` |
| `date_of_birth` | Tidak | `1990-01-01` |
| `vendor_data` | Tidak | `user-1234` |

* **Input wajib:** `tax_number`, `selfie`
* **Input opsional:** `first_name`, `last_name`, `full_name`, `date_of_birth`, `vendor_data`
* **Persetujuan:** Wajib
* **Ketersediaan di alur kerja:** Tersedia dalam alur kerja
* **Cakupan:** 96%
* **Harga:** \$0.20 per kueri yang berhasil

## Parameter isi

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

Kode negara ISO 3166-1 alpha-3 untuk layanan database ini.

Contoh: `BRA`

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

Array yang berisi ID layanan ini. Mengunci layanan membuat permintaan hanya berlaku untuk database yang tepat ini.

Contoh: `bra_unico_idcloud`

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

Persetujuan eksplisit dari pengguna akhir untuk layanan ini.

Contoh: `true`

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

Nomor identifikasi pajak atau fiskal.

Contoh: `11111111111`

**selfie** `file` *required*

File gambar swafoto yang diunggah untuk validasi database biometrik. Format yang diterima: JPEG, PNG, atau WebP.

Contoh: `@./selfie.jpg`

**first\_name** `string`

Nama depan yang akan divalidasi.

Contoh: `John`

**last\_name** `string`

Nama belakang yang akan divalidasi.

Contoh: `Doe`

**full\_name** `string`

Nama lengkap resmi yang akan divalidasi.

Contoh: `John Doe`

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

Tanggal lahir dalam format `YYYY-MM-DD`.

Contoh: `1990-01-01`

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

Referensi pengguna Anda yang stabil untuk orang ini, misalnya ID pengguna internal Anda. Didit menggunakannya untuk menautkan pemeriksaan terpisah ke pengguna akhir yang sama dan mengurangi gangguan dalam deteksi duplikat.

Contoh: `user-1234`

## Aturan input & catatan validasi

* CPF Brasil (tepat 11 digit)
* `tax_number` hanya boleh berisi digit; hapus spasi, tanda hubung, dan tanda baca sebelum mengirim permintaan.
* `tax_number` harus tepat 11 karakter.

## Cara memanggilnya

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

Setiap panggilan yang berhasil mengembalikan HTTP `200`. Kolom **`outcome_code`** memberi tahu Anda apa yang sebenarnya terjadi, misalnya membedakan ketidakcocokan biometrik yang sebenarnya (`BIOMETRIC_NO_MATCH`) dari swafoto yang tidak dapat dibaca (`BIOMETRIC_IMAGE_UNUSABLE`). `status` yang ditampilkan adalah status fitur default; tindakan [Partial Match / No Match](https://docs.didit.me/id/core-technology/database-validation/database-validation-warnings.md) yang Anda konfigurasi dapat menggantinya.

**`MATCH`**: Registri mengonfirmasi identitas dan setiap kolom yang diperiksa cocok.

```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`**: Skor kecocokan wajah berada di bawah ambang batas penerimaan; orang dalam swafoto bukan orang yang sama dengan orang dalam foto di registri.

```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`**: Registri tidak dapat menentukan apakah orang tersebut cocok; hasilnya benar-benar tidak pasti (mereka mungkin ada atau mungkin tidak ada di registri). Ini BUKAN ketidakcocokan dan BUKAN masalah gambar teknis; tidak ada kolom yang dapat dipastikan, sehingga match\_type bernilai null dan pemeriksaan dikirim ke peninjauan.

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

## Data yang dikembalikan

Kolom yang tepat ditampilkan di `source_data` bergantung pada apa yang dikembalikan registri. Contoh yang dihasilkan untuk `bra_unico_idcloud` saat ini mendokumentasikan bentuk ternormalisasi berikut:

* `unico_face_match`

## Harga & SLA

Kueri BRA - Unico IDCloud (CPF + swafoto) hanya ditagih ketika Didit menerima hasil konklusif dari sumber validasi.

* **Harga per panggilan:** \$0.20 USD.
* **Penagihan:** per kueri yang berhasil. Anda tidak dikenai biaya ketika registri tidak dapat dijangkau, ketika kolom wajib tidak ada, atau ketika permintaan ditolak sebelum mencapai sumber.
* **Latensi:** p95 tipikal kurang dari 2 dtk.
* **Ketersediaan:** 99.9% per kuartal di sisi Didit; ketersediaan sumber hilir bervariasi menurut negara dan dataset.

## Tentang sumber ini

[Unico](https://unico.io) adalah IDtech asal Brasil yang mengelola registri biometrik wajah swasta terbesar di negara tersebut. Platform IDCloud-nya menyimpan lebih dari satu miliar embedding wajah dan menambahkan sekitar 35 juta wajah baru setiap bulan, yang bersumber dari alur onboarding dan autentikasi ulang lebih dari 800 perusahaan Brasil, termasuk empat dari lima bank terbesar. Skala inilah yang menghasilkan angka cakupan di atas: pencarian CPF menghasilkan rekaman biometrik untuk sekitar 96% orang dewasa di Brasil.

Didit memiliki kemitraan langsung dengan Unico, sehingga Anda dapat menanyakan IDCloud melalui API Validasi Database standar: bayar per panggilan, tanpa kontrak Unico terpisah, tanpa volume minimum, dan tanpa proses onboarding.

**Perbedaannya dengan registri pemerintah.** Didit juga menawarkan [Brasil - CPF + pencocokan wajah (Datavalid)](https://docs.didit.me/id/api-reference/database-validation/brazil/cpf-facial.md), yang merupakan sumber resmi SERPRO dan pilihan tepat jika Anda secara khusus membutuhkan registri pemerintah sebagai sumber kebenaran utama. IDCloud adalah pilihan yang lebih baik untuk kebutuhan lainnya, berdasarkan dua aspek yang dapat Anda periksa sendiri. Pertama, IDCloud menjangkau sekitar 96% orang dewasa, sedangkan Datavalid sekitar 50%. Kedua, IDCloud mencocokkan wajah dengan rekaman biometrik yang dikelola registri itu sendiri, bukan dengan foto potret yang diambil dari dokumen yang diberikan pengguna, sehingga tahan terhadap pemalsuan dokumen maupun penipuan dengan CPF curian. Biayanya juga kurang dari setengah harga per kueri.

## Alur yang direkomendasikan untuk Brasil

Untuk sebagian besar kasus penggunaan di Brasil, Anda sama sekali tidak perlu menangkap dokumen. Pengguna memberikan CPF mereka, lalu swafoto yang diperiksa liveness-nya memastikan bahwa orang di depan kamera adalah pemilik CPF tersebut.

**1. Kumpulkan CPF**

Satu-satunya input teks Anda adalah CPF 11 digit. Tidak ada foto dokumen, dan tidak ada nama atau tanggal lahir yang diketik manual.

Karena tidak ada dokumen yang dibaca dalam alur ini, Didit tidak punya sumber untuk mengambil CPF kecuali Anda memberi tahu asalnya. Kirim CPF di `metadata` sesi saat Anda membuat sesi, lalu petakan sebagai input `tax_number` pada langkah Validasi Database. Di Business Console, itu adalah pemetaan input langkah tersebut. Melalui API alur kerja, itu adalah `database_validation_field_sources` pada node:

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

Kemudian buat setiap sesi dengan nilai di bawah kunci tersebut:

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

Tanpa pemetaan ini, langkah tetap berjalan, tetapi melaporkan `tax_number` sebagai hilang dan tidak pernah melakukan kueri ke registri. Tidak ada yang ditagihkan, dan entri `database_validations` pada sesi berisi alasannya.

**2. Ambil swafoto dengan pemeriksaan liveness**

Tambahkan langkah [liveness](https://docs.didit.me/id/core-technology/liveness/overview.md) ke alur kerja yang sama, lalu pilih metode yang sesuai dengan toleransi risiko Anda: **Liveness Pasif** (tanpa tindakan apa pun dari pengguna), **Flash 3D**, atau **Aksi 3D & Flash** (metode aktif yang memproyeksikan pola cahaya, dan yang terakhir menambahkan tindakan acak). Atur dengan `face_liveness_method` (`PASSIVE`, `FLASHING`, atau `ACTIVE_3D`) di Business Console atau melalui API alur kerja. Apa pun yang Anda pilih, Didit menampilkan langkah pengambilan gambar dan memastikan bahwa orang tersebut nyata serta benar-benar hadir di depan kamera. Inilah yang mencegah foto tersimpan atau pemutaran ulang layar dikirimkan.

**3. Validasi CPF dan swafoto terhadap Unico IDCloud**

Di dalam alur sesi, Didit menggunakan ulang swafoto liveness secara otomatis. Anda tidak perlu menangani gambarnya sama sekali. Didit juga membaca CPF dari pemetaan di atas. IDCloud kemudian mengonfirmasi apakah wajah tersebut milik orang yang memiliki CPF itu. Langkah ini hanya membutuhkan dua input ini. Jika Anda juga mengirim `full_name` atau `date_of_birth` di `metadata` dan memetakannya, nilainya diteruskan ke Unico sebagai pemeriksaan silang, tetapi keduanya tidak wajib.

> [!NOTE]
>
> Alur khusus CPF ini berlaku untuk integrasi **sesi dan alur kerja**, saat Didit melakukan pengambilan gambar dan meneruskan swafoto liveness ke layanan ini untuk Anda. Jika Anda memanggil `POST /v3/database-validation/` **secara langsung**, `selfie` adalah input file yang wajib, dan Anda sendiri yang menyediakan gambarnya. Lihat [ikhtisar Validasi Database](https://docs.didit.me/id/core-technology/database-validation/overview.md) untuk kedua mode tersebut.

**Biaya:** sekitar \$0.30 per pengguna terverifikasi dengan Liveness Pasif, yaitu \$0.20 untuk kueri IDCloud ditambah \$0.10 untuk pemeriksaan liveness. Atau sekitar \$0.35 dengan metode aktif, saat pemeriksaan liveness berbiaya \$0.15. Ini adalah harga daftar. Diskon paket Anda berlaku untuk masing-masing biaya tersebut. Lihat [harga](https://docs.didit.me/id/getting-started/pricing.md).

**Cadangan untuk sekitar 4% yang tidak tercakup.** Ketika IDCloud mengembalikan `INCONCLUSIVE`, registri tidak dapat mencocokkan CPF tersebut dengan catatan biometrik yang dapat digunakan, biasanya karena orang tersebut tidak ada di dalam registri. Perlakukan ini sebagai "tidak ada jawaban", bukan sebagai pemeriksaan yang gagal. Lalu alihkan ke [Verifikasi Identitas](https://docs.didit.me/id/core-technology/id-verification/overview.md) lengkap: pengambilan dokumen ditambah pencocokan wajah dengan potret dokumen. Semua pengguna tetap dapat diverifikasi, dan Anda hanya membayar verifikasi dokumen untuk sisa yang kecil.

**Menangani penolakan.** `BIOMETRIC_NO_MATCH` berarti registri secara aktif tidak setuju: wajah tersebut bukan milik CPF itu. Perlakukan ini sebagai indikasi negatif yang kuat, bukan sebagai alasan untuk mencoba lagi. Mengarahkan pengguna langsung ke pengambilan dokumen justru jalur yang diinginkan oleh penipu, karena dokumen adalah artefak yang mereka kendalikan. Meski begitu, hasil negatif palsu yang sungguhan memang terjadi, misalnya penampilan yang berubah, foto registri yang lama, atau pengambilan gambar yang buruk. Karena itu, arahkan kasus ini ke peninjauan manual. Jangan menyetujuinya secara otomatis, dan jangan menghentikan pengguna begitu saja. `BIOMETRIC_IMAGE_UNUSABLE` berbeda: swafoto tersebut tidak bisa dibaca, jadi mintalah swafoto baru. Tentukan apa yang dilakukan setiap hasil terhadap sesi dengan [tindakan Partial Match / No Match](https://docs.didit.me/id/core-technology/database-validation/database-validation-warnings.md), dan lihat [Kode Hasil](https://docs.didit.me/id/core-technology/database-validation/database-validation-outcome-codes.md) untuk daftar lengkapnya.

**Pengguna yang kembali.** Anda hanya perlu membayar pencarian registri sekali. Setelah pengguna lolos alur ini, swafoto liveness disimpan di `vendor_data` mereka, sehingga Anda dapat memverifikasi ulang mereka nanti dengan [Autentikasi Biometrik](https://docs.didit.me/id/core-technology/biometric-auth/overview.md), yaitu pemeriksaan liveness ditambah pencocokan wajah dengan wajah tersimpan tersebut, seharga \$0.10, dengan pilihan metode liveness yang sama. Perhatikan bahwa ini khusus untuk pengguna yang **kembali**. Sesi autentikasi biometrik membutuhkan wajah tersimpan (atau `portrait_image` yang Anda sediakan), dan akan gagal saat dibuat jika pengguna tidak memiliki keduanya. Karena itu, pengguna baru tetap melalui alur di atas.

## Lanjutkan membaca

* [Ikhtisar Validasi Database Brasil](https://docs.didit.me/api-reference/database-validation/brazil.md)
* [Ikhtisar Validasi Database](https://docs.didit.me/id/core-technology/database-validation/overview.md)
* [Kode Hasil](https://docs.didit.me/id/core-technology/database-validation/database-validation-outcome-codes.md)


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