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

# 邮箱验证报告：泄露检测与 OTP JSON 解析

> Didit 邮箱验证响应解析指南：涵盖一次性验证码生命周期、数据泄露曝光、一次性及不可投递邮箱标识、跨会话匹配与风险警告。

邮箱验证报告记录了邮箱 OTP 验证的完整结果：消息发送对象、该地址是否为一次性邮箱或无法送达、是否出现在已知数据泄露事件中、用户尝试了多少次，以及与您的黑名单或其他已通过验证的用户的跨会话匹配项。

本页面介绍了决策 endpoint 返回的 JSON 结构，以便您解析每个已验证地址的 OTP 结果、数据泄露情况和风险标记。

![Didit 邮箱验证报告，展示 OTP 结果、泄露数据和风险标记](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)

## 概述

工作流节点每次运行邮箱验证功能时，都会生成一份邮箱报告。每份报告代表针对一个地址的一次 OTP 验证，包含以下内容：

* 已验证的 `email` 地址。
* 布尔值风险标记（`is_breached`、`is_disposable`、`is_undeliverable`）以及来自泄露情报数据库的辅助 `breaches[]` 数组。
* OTP 发送尝试次数（`verification_attempts`）和通过时间戳。
* 记录每次发送、重试和验证码核验尝试的按时间排序的 `lifecycle[]` 日志。
* 呈现同一地址在其他已通过邮箱验证或您的黑名单中出现的 `matches[]` 数组。
* `warnings[]` 数组：验证期间产生的风险事件（请参阅[邮箱验证警告](https://docs.didit.me/zh/core-technology/email-verification/warnings-email-verification.md)）。
* 标识生成该报告的工作流图谱节点的 `node_id`（仅限 V3 会话）。

在托管工作流会话中，OTP 验证在 Didit 验证界面内运行，您只需从决策 payload 中读取结果。对于无需托管流程的服务器到服务器 OTP，请使用独立的 Email API：[`POST /v3/email/send/`](https://docs.didit.me/zh/standalone-apis/email-send) 投递验证码，[`POST /v3/email/check/`](https://docs.didit.me/zh/standalone-apis/email-check) 校验用户输入；最终完成的独立验证会以相同的报告结构呈现。

托管会话默认对用户限制为**最多输入 2 次错误验证码**（`email_max_check_attempts`）以及**最多发送 2 次 OTP（初始发送加一次重新发送）**（`email_max_retries`），可在每个工作流节点中进行调整。超过任一上限都会将该步骤最终判定为 `Declined`，并带有 `EMAIL_CODE_ATTEMPTS_EXCEEDED`。

## 在 API 响应中的位置

决策 endpoint（`GET /v3/session/{sessionId}/decision/`）在复数数组键 **`email_verifications`** 下返回邮箱报告。该数组在工作流图谱中每个邮箱验证节点包含一个条目，通常为一个，但升级流程可能会生成多个。

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

`null` 值表示尚未运行邮箱验证步骤。当您的工作流可以收集多个邮箱地址时，请遍历该数组（而不是直接读取 `email_verifications[0]`）。

## 数据结构

权威且逐字段详细说明的数据结构请参见[数据模型](https://docs.didit.me/zh/reference/data-models.md#邮箱验证)页面。

```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
}
```

无法投递的地址 — 无论是语法无效、域名不存在、缺少 MX 记录，还是 OTP 投递失败 — 都会将该步骤最终判定为 **`Declined`**，并触发自动拒绝警告 `UNDELIVERABLE_EMAIL_DETECTED`。唯一的例外情况是：当用户自行输入邮箱地址（而非在创建会话时预填充）时，投递失败会返回内联错误，以便用户可以使用其他地址重试，而不会被立即拒绝。

### 状态值

| 状态 | 含义 |
| - | - |
| `Not Finished` | OTP 发送已发起，但验证尚未最终完成。 |
| `Approved` | 用户输入了有效的 OTP，且未命中任何会导致拒绝的风险项。 |
| `Declined` | 触发了自动拒绝警告（黑名单、无法投递的地址、尝试次数超限），或命中了配置为 `DECLINE` 的风险操作。 |
| `In Review` | 配置为 `REVIEW` 的风险操作将该步骤路由至人工审核。 |
| `Expired` | 5 分钟的 OTP 有效窗口期已过且未输入有效验证码 — 适用于通过独立邮箱 API 创建的验证。 |

### 生命周期事件类型

`lifecycle[]` 按时间先后顺序排序。每个事件都包含 `type`、`timestamp`、`details` 以及计费 `fee`（如适用）：

| 事件类型 | 触发时机 |
| - | - |
| `EMAIL_VERIFICATION_MESSAGE_SENT` | 首次尝试发送 OTP — 包括返回无法投递的发送尝试。 |
| `EMAIL_VERIFICATION_RETRY_MESSAGE_SENT` | 用户请求重新发送后的后续 OTP 发送。 |
| `VALID_CODE_ENTERED` | 用户提交了正确的 OTP 验证码。 |
| `INVALID_CODE_ENTERED` | 用户提交了错误或已过期的 OTP 验证码（计入上限次数）。 |
| `EMAIL_VERIFICATION_APPROVED` | 功能层面的状态被设置为 `Approved`。 |
| `EMAIL_VERIFICATION_DECLINED` | 功能层面的状态被设置为 `Declined`。 |
| `EMAIL_VERIFICATION_IN_REVIEW` | 功能层面的状态被设置为 `In Review`。 |
| `EMAIL_VERIFICATION_EXPIRED` | OTP 有效窗口期已过且未输入有效验证码（独立邮箱 API）。 |

`details` payload 取决于事件类别：

* **发送事件**（`EMAIL_VERIFICATION_MESSAGE_SENT`、`EMAIL_VERIFICATION_RETRY_MESSAGE_SENT`）— `{ status, reason }`。`status` 为 `Success`、`Retry` 或 `Undeliverable`；`reason` 为 `null`，除非发送失败（`email_can_not_be_delivered`，或未识别的历史遗留值为 `unknown`）。
* **核验事件**（`VALID_CODE_ENTERED`、`INVALID_CODE_ENTERED`）— `{ code_tried, status }`，其中 `status` 为 `Approved`、`Failed`、`Expired or Not Found` 或 `Declined`。
* **最终状态事件** — 为 `null`，但 `EMAIL_VERIFICATION_DECLINED` / `EMAIL_VERIFICATION_IN_REVIEW` 除外，它们会携带 `{ "reason": "<risk code>" }`（例如 `UNDELIVERABLE_EMAIL_DETECTED`）。

`status` 为 `Success` 或 `Undeliverable` 的发送会记录 \$0.02 邮箱验证费用；`Retry` 发送、核验事件和状态事件始终带有 `fee: 0`。

### 跨会话匹配

`matches[]` 记录同一应用内**先前已通过**的邮箱验证中的相同地址 — 跨越 KYC、KYB 和独立 API 会话 — 以及在[管理 API 列表](https://docs.didit.me/zh/management-api/lists/overview.md)中配置的命中黑名单项。与当前会话共享相同 `vendor_data` 的验证将被排除（同一终端用户不会与自身匹配），该数组最多包含 **5** 条记录，按时间从早到晚排序。当该地址存在于您的黑名单中但匹配的会话均未被列入黑名单时，数组最前面会预先添加一条 `source: "list_entry"` 的合成记录（所有会话字段均为 `null`）。

```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
}
```

## 示例

### 已通过 - 正常的 OTP 且包含一条信息级别的违规

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

### 已拒绝 - 无法投递的地址

预填充的地址如果未能通过语法或 DNS（MX）验证 — 或者其 OTP 邮件无法投递 — 将立即最终判定为 `Declined`。由于验证码从未送达用户，因此不会出现验证码核验事件。

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

### 已拒绝 - 黑名单中的一次性邮箱

用户完成了 OTP，但该地址命中了您的邮箱黑名单（自动拒绝）。同时也触发了一次性邮箱标记 — 此处为 `information` 级别，因为 `disposable_email_action` 保持为默认的 `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"
    }
  ]
}
```

## 相关内容

* [邮箱验证概述](https://docs.didit.me/zh/core-technology/email-verification/overview.md) — 功能行为与定价。
* [邮箱验证警告](https://docs.didit.me/zh/core-technology/email-verification/warnings-email-verification.md) — 所有风险代码、拒绝触发条件和可配置操作。
* [数据模型 — 邮箱验证](https://docs.didit.me/zh/reference/data-models.md#邮箱验证) — 权威且逐字段说明的数据结构。
* [邮箱 API — 发送 OTP](https://docs.didit.me/zh/standalone-apis/email-send.md)和[核验 OTP](https://docs.didit.me/zh/standalone-apis/email-check.md) — 独立的服务端到服务端的 endpoint。
* [Management API — 列表](https://docs.didit.me/zh/management-api/lists/overview.md) — 管理为 `matches[]` 提供 `source: list_entry` 数据的邮箱黑名单。


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