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

# Laporan Verifikasi Email: JSON Breach & OTP

> Pelajari respons Verifikasi Email Didit: siklus OTP, kebocoran data, flag disposable, kecocokan lintas sesi, dan peringatan risiko.

Laporan Verifikasi Email mencatat hasil lengkap dari tantangan OTP email: kepada siapa pesan dikirim, apakah alamat tersebut sekali pakai atau tidak dapat menerima email, apakah alamat tersebut muncul dalam kebocoran data yang diketahui, berapa banyak percobaan yang dilakukan pengguna, dan setiap kecocokan lintas-sesi terhadap daftar blokir Anda atau pengguna lain yang telah disetujui.

Halaman ini mendokumentasikan format JSON yang dikembalikan oleh endpoint keputusan sehingga Anda dapat mem-parsing hasil OTP, paparan kebocoran data, dan tanda risiko untuk setiap alamat yang diverifikasi.

![Laporan verifikasi email Didit yang menampilkan hasil OTP, data kebocoran, dan tanda risiko](https://mintcdn.com/didit-0f962782/z6T2GHM4Zh-iSj-K/images/email-verification-report.png?fit=max\&auto=format\&n=z6T2GHM4Zh-iSj-K\&q=85\&s=4d153b7d3d9d4c88bc3932466af7ed29)

## Ringkasan

Laporan email dibuat setiap kali node alur kerja menjalankan fitur Verifikasi Email. Setiap laporan merepresentasikan satu tantangan OTP terhadap satu alamat dan berisi:

* Alamat `email` yang diverifikasi.
* Tanda risiko boolean (`is_breached`, `is_disposable`, `is_undeliverable`) serta array pendukung `breaches[]` yang bersumber dari database intelijen kebocoran.
* Jumlah percobaan pengiriman OTP (`verification_attempts`) dan stempel waktu persetujuan.
* Log kronologis `lifecycle[]` dari setiap pengiriman, percobaan ulang, dan pemeriksaan kode.
* Array `matches[]` yang memunculkan alamat yang sama pada verifikasi email lain yang disetujui atau daftar blokir Anda.
* Array `warnings[]` — event risiko yang dikeluarkan selama verifikasi (lihat [Peringatan Verifikasi Email](https://docs.didit.me/id/core-technology/email-verification/warnings-email-verification.md)).
* Sebuah `node_id` yang mengidentifikasi node graf alur kerja mana yang menghasilkan laporan tersebut (khusus sesi V3).

Dalam sesi alur kerja yang di-hosting, tantangan OTP berjalan di dalam UI verifikasi Didit — Anda hanya membaca hasilnya dari payload keputusan. Untuk OTP server-ke-server tanpa alur yang di-hosting, gunakan Email API mandiri: [`POST /v3/email/send/`](https://docs.didit.me/id/standalone-apis/email-send) mengirimkan kode dan [`POST /v3/email/check/`](https://docs.didit.me/id/standalone-apis/email-check) memvalidasi entri pengguna; verifikasi mandiri yang telah selesai ditampilkan melalui format laporan yang sama.

Sesi yang di-hosting membatasi pengguna hingga **2 kali entri kode yang salah** (`email_max_check_attempts`) dan **2 kali pengiriman OTP — pengiriman awal ditambah satu kali kirim ulang** (`email_max_retries`) secara default, yang dapat disesuaikan per node alur kerja. Melebihi salah satu batas tersebut akan menetapkan langkah sebagai `Declined` dengan `EMAIL_CODE_ATTEMPTS_EXCEEDED`.

## Tempat kemunculannya dalam respons API

Endpoint keputusan (`GET /v3/session/{sessionId}/decision/`) mengembalikan laporan email dalam array dengan kunci jamak **`email_verifications`**. Array ini berisi satu entri per node Verifikasi Email dalam graf alur kerja — biasanya satu, tetapi alur peningkatan dapat menghasilkan beberapa entri.

```json theme={null}
{
  "session_id": "11111111-1111-1111-1111-111111111111",
  "status": "Approved",
  "email_verifications": [
    { "node_id": "feature_email_1", "status": "Approved", "...": "..." }
  ]
}
```

Nilai `null` berarti belum ada langkah Verifikasi Email yang berjalan. Lakukan iterasi pada array (daripada hanya membaca `email_verifications[0]`) ketika alur kerja Anda dapat mengumpulkan lebih dari satu alamat email.

## Skema

Skema kanonik per kolom terdapat di halaman [Model data](https://docs.didit.me/id/reference/data-models.md#verifikasi-email).

```typescript theme={null}
interface EmailVerification {
  node_id: string | null;
  status: "Not Finished" | "Approved" | "Declined" | "In Review" | "Expired";
  email: string;
  is_breached: boolean;
  breaches: Breach[];                // Up to the 5 most recent known breaches
  is_disposable: boolean;            // Disposable / throwaway provider
  is_undeliverable: boolean;         // Failed syntax / DNS (MX) validation or OTP delivery
  verification_attempts: number;     // OTP send attempts
  verified_at: string | null;        // ISO 8601, null until a valid code is entered
  lifecycle: EmailLifecycleEvent[];  // OTP send/retry/check timeline
  warnings: Warning[];               // Risk events (see Data models → Warning object)
  matches: EmailMatch[];             // Cross-session / blocklist matches
}

interface Breach {
  name: string;                      // Breached service name
  domain: string;                    // Affected domain
  breach_date: string;               // YYYY-MM-DD
  breach_emails_count: number;       // Total affected accounts
  description: string;               // HTML description of the breach
  logo_path: string;                 // Breached-service logo URL
  data_classes: string[];            // Exposed data categories (snake_case)
  is_verified: boolean;              // true when the breach is a verified incident
}
```

Alamat yang tidak dapat dijangkau — sintaks tidak valid, domain yang tidak ada, catatan MX yang hilang, atau pengiriman OTP yang gagal — menyelesaikan langkah sebagai **`Declined`** dengan peringatan penolakan otomatis `UNDELIVERABLE_EMAIL_DETECTED`. Satu-satunya pengecualian: ketika pengguna mengetik sendiri alamat tersebut (tidak diisi sebelumnya saat pembuatan sesi), pengiriman yang gagal disampaikan mengembalikan error inline sehingga mereka dapat mencoba lagi dengan alamat yang berbeda alih-alih langsung ditolak.

### Nilai status

| Status | Arti |
| - | - |
| `Not Finished` | Pengiriman OTP telah dimulai tetapi verifikasi belum diselesaikan. |
| `Approved` | Pengguna memasukkan OTP yang valid dan tidak ada risiko penolakan yang cocok. |
| `Declined` | Peringatan penolakan otomatis terpicu (daftar blokir, alamat tidak dapat dijangkau, batas percobaan terlampaui) atau tindakan risiko yang dikonfigurasi ke `DECLINE` cocok. |
| `In Review` | Tindakan risiko yang dikonfigurasi ke `REVIEW` mengarahkan langkah ke peninjauan manual. |
| `Expired` | Jendela waktu OTP selama 5 menit telah berlalu tanpa kode yang valid — berlaku untuk verifikasi yang dibuat melalui API email mandiri. |

### Jenis event siklus hidup

`lifecycle[]` diurutkan secara kronologis. Setiap event memiliki `type`, `timestamp`, `details`, dan `fee` yang dapat ditagih (jika berlaku):

| Jenis event | Dipancarkan saat |
| - | - |
| `EMAIL_VERIFICATION_MESSAGE_SENT` | Upaya pengiriman OTP pertama — termasuk pengiriman yang gagal disampaikan. |
| `EMAIL_VERIFICATION_RETRY_MESSAGE_SENT` | Pengiriman OTP berikutnya setelah pengguna meminta pengiriman ulang. |
| `VALID_CODE_ENTERED` | Pengguna mengirimkan kode OTP yang benar. |
| `INVALID_CODE_ENTERED` | Pengguna mengirimkan kode OTP yang salah atau kedaluwarsa (dihitung dalam batas maksimal). |
| `EMAIL_VERIFICATION_APPROVED` | Status tingkat fitur diatur ke `Approved`. |
| `EMAIL_VERIFICATION_DECLINED` | Status tingkat fitur diatur ke `Declined`. |
| `EMAIL_VERIFICATION_IN_REVIEW` | Status tingkat fitur diatur ke `In Review`. |
| `EMAIL_VERIFICATION_EXPIRED` | Jendela waktu OTP telah berlalu tanpa kode yang valid (API email mandiri). |

Payload `details` bergantung pada kelompok event:

* **Event pengiriman** (`EMAIL_VERIFICATION_MESSAGE_SENT`, `EMAIL_VERIFICATION_RETRY_MESSAGE_SENT`) — `{ status, reason }`. `status` berupa `Success`, `Retry`, atau `Undeliverable`; `reason` bernilai `null` kecuali pengiriman gagal (`email_can_not_be_delivered`, atau `unknown` untuk nilai lama yang tidak dikenali).
* **Event pemeriksaan** (`VALID_CODE_ENTERED`, `INVALID_CODE_ENTERED`) — `{ code_tried, status }` dengan `status` `Approved`, `Failed`, `Expired or Not Found`, atau `Declined`.
* **Event status akhir** — `null`, kecuali `EMAIL_VERIFICATION_DECLINED` / `EMAIL_VERIFICATION_IN_REVIEW`, yang memuat `{ "reason": "<risk code>" }` (misalnya `UNDELIVERABLE_EMAIL_DETECTED`).

Pengiriman dengan `status` `Success` atau `Undeliverable` mencatat biaya Verifikasi Email sebesar \$0.02; pengiriman `Retry`, event pemeriksaan, dan event status selalu memuat `fee: 0`.

### Kecocokan lintas sesi

`matches[]` mencatat alamat yang sama pada verifikasi email yang **sebelumnya disetujui** dalam aplikasi yang sama — di seluruh sesi KYC, KYB, dan API mandiri — ditambah temuan daftar blokir yang dikonfigurasi dalam [daftar management-api](https://docs.didit.me/id/management-api/lists/overview.md). Verifikasi yang berbagi `vendor_data` sesi saat ini dikecualikan (pengguna akhir yang sama tidak mencocokkan diri mereka sendiri), array dibatasi hingga maksimal **5** entri, diurutkan dari yang paling lama. Ketika alamat berada di daftar blokir Anda tetapi tidak ada sesi yang cocok yang masuk daftar blokir, entri sintetis dengan `source: "list_entry"` (semua kolom sesi bernilai `null`) ditambahkan di awal array.

```typescript theme={null}
interface EmailMatch {
  session_id: string | null;         // null when source = "list_entry"
  session_number: number | null;
  vendor_data: string | null;
  verification_date: string | null;  // ISO 8601, creation date of the matched session
  email: string;
  status: string | null;             // Status of the matched session
  is_blocklisted: boolean;
  api_service: string | null;        // Set when the matched session came from a standalone API
  source: "session" | "list_entry";  // "list_entry" = manual blocklist hit
}
```

## Contoh

### Disetujui — OTP bersih dengan satu pelanggaran informasional

```json theme={null}
{
  "node_id": "feature_email_1",
  "status": "Approved",
  "email": "alex.sample@example.com",
  "is_breached": true,
  "breaches": [
    {
      "name": "ExampleAir",
      "domain": "example-air.com",
      "breach_date": "2022-08-25",
      "breach_emails_count": 6083479,
      "description": "In August 2022, the airline ExampleAir suffered a data breach that exposed customers' personal information.",
      "logo_path": "https://<media-host>/logos/ExampleAir.png",
      "data_classes": [
        "dates_of_birth", "email_addresses", "genders", "names",
        "nationalities", "phone_numbers", "physical_addresses",
        "salutations", "spoken_languages"
      ],
      "is_verified": true
    }
  ],
  "is_disposable": false,
  "is_undeliverable": false,
  "verification_attempts": 1,
  "verified_at": "2025-09-15T17:36:19.963451Z",
  "lifecycle": [
    {
      "type": "EMAIL_VERIFICATION_MESSAGE_SENT",
      "timestamp": "2025-09-15T17:35:50.000000+00:00",
      "details": { "status": "Success", "reason": null },
      "fee": 0.02
    },
    {
      "type": "VALID_CODE_ENTERED",
      "timestamp": "2025-09-15T17:36:19.000000+00:00",
      "details": { "code_tried": "123456", "status": "Approved" },
      "fee": 0
    },
    {
      "type": "EMAIL_VERIFICATION_APPROVED",
      "timestamp": "2025-09-15T17:36:19.963451+00:00",
      "details": null,
      "fee": 0
    }
  ],
  "warnings": [
    {
      "feature": "EMAIL",
      "risk": "BREACHED_EMAIL_DETECTED",
      "additional_data": null,
      "log_type": "information",
      "short_description": "Breached email detected",
      "long_description": "This email address was found in one or more known data breaches.",
      "node_id": "feature_email_1"
    }
  ],
  "matches": []
}
```

### Ditolak — alamat yang tidak dapat dijangkau

Alamat yang diisi sebelumnya yang gagal dalam validasi sintaks atau DNS (MX) — atau yang email OTP-nya tidak dapat dikirimkan — segera diselesaikan sebagai `Declined`. Tidak ada event pemeriksaan kode yang muncul karena tidak ada kode yang pernah sampai ke pengguna.

```json theme={null}
{
  "node_id": "feature_email_1",
  "status": "Declined",
  "email": "user@nonexistent-domain.example",
  "is_breached": false,
  "breaches": [],
  "is_disposable": false,
  "is_undeliverable": true,
  "verification_attempts": 1,
  "verified_at": null,
  "lifecycle": [
    {
      "type": "EMAIL_VERIFICATION_MESSAGE_SENT",
      "timestamp": "2025-09-15T18:00:00.000000+00:00",
      "details": { "status": "Undeliverable", "reason": "email_can_not_be_delivered" },
      "fee": 0.02
    },
    {
      "type": "EMAIL_VERIFICATION_DECLINED",
      "timestamp": "2025-09-15T18:00:01.500000+00:00",
      "details": { "reason": "UNDELIVERABLE_EMAIL_DETECTED" },
      "fee": 0
    }
  ],
  "warnings": [
    {
      "feature": "EMAIL",
      "risk": "UNDELIVERABLE_EMAIL_DETECTED",
      "additional_data": null,
      "log_type": "error",
      "short_description": "Undeliverable email detected",
      "long_description": "The system detected that the email is undeliverable, which is not allowed.",
      "node_id": "feature_email_1"
    }
  ],
  "matches": []
}
```

### Ditolak — kotak surat sekali pakai yang masuk daftar blokir

Pengguna menyelesaikan OTP, tetapi alamat tersebut cocok dengan daftar blokir email Anda (penolakan otomatis). Tanda alamat sekali pakai juga dimunculkan — di sini pada tingkat `information` karena `disposable_email_action` dibiarkan pada nilai defaultnya `NO_ACTION`.

```json theme={null}
{
  "node_id": "feature_email_1",
  "status": "Declined",
  "email": "user@mailinator.com",
  "is_breached": false,
  "breaches": [],
  "is_disposable": true,
  "is_undeliverable": false,
  "verification_attempts": 1,
  "verified_at": "2025-09-15T18:05:42.201734Z",
  "lifecycle": [
    {
      "type": "EMAIL_VERIFICATION_MESSAGE_SENT",
      "timestamp": "2025-09-15T18:05:01.000000+00:00",
      "details": { "status": "Success", "reason": null },
      "fee": 0.02
    },
    {
      "type": "VALID_CODE_ENTERED",
      "timestamp": "2025-09-15T18:05:42.000000+00:00",
      "details": { "code_tried": "654321", "status": "Approved" },
      "fee": 0
    },
    {
      "type": "EMAIL_VERIFICATION_DECLINED",
      "timestamp": "2025-09-15T18:05:42.201734+00:00",
      "details": { "reason": "EMAIL_IN_BLOCKLIST" },
      "fee": 0
    }
  ],
  "warnings": [
    {
      "feature": "EMAIL",
      "risk": "EMAIL_IN_BLOCKLIST",
      "additional_data": {
        "blocklisted_session_id": null,
        "blocklisted_session_number": null,
        "api_service": null
      },
      "log_type": "error",
      "short_description": "Email in blocklist",
      "long_description": "The system detected that the email is in the blocklist, which is not allowed.",
      "node_id": "feature_email_1"
    },
    {
      "feature": "EMAIL",
      "risk": "DISPOSABLE_EMAIL_DETECTED",
      "additional_data": null,
      "log_type": "information",
      "short_description": "Disposable email detected",
      "long_description": "The system detected that the email is disposable, which is not allowed.",
      "node_id": "feature_email_1"
    }
  ],
  "matches": [
    {
      "session_id": null,
      "session_number": null,
      "vendor_data": null,
      "verification_date": null,
      "email": "user@mailinator.com",
      "status": null,
      "is_blocklisted": true,
      "api_service": null,
      "source": "list_entry"
    }
  ]
}
```

## Terkait

* [Gambaran umum Verifikasi Email](https://docs.didit.me/id/core-technology/email-verification/overview.md) — perilaku fitur dan harga.
* [Peringatan Verifikasi Email](https://docs.didit.me/id/core-technology/email-verification/warnings-email-verification.md) — setiap kode risiko, pemicu penolakan, dan tindakan yang dapat dikonfigurasi.
* [Model data — verifikasi email](https://docs.didit.me/id/reference/data-models.md#verifikasi-email) — skema kanonik per kolom.
* [Email API — Send OTP](https://docs.didit.me/id/standalone-apis/email-send.md) dan [Check OTP](https://docs.didit.me/id/standalone-apis/email-check.md) — endpoint server-ke-server mandiri.
* [Management API — Lists](https://docs.didit.me/id/management-api/lists/overview.md) — kelola daftar blokir email yang mengisi `matches[]` dengan `source: list_entry`.


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