mcpField
D
didit-email-verification

didit-email-verification

github.com/didit-protocol安全29200 次安装2 周前更新
代码仓库

关于 didit-email-verification

介绍 Didit API 的邮件验证码发送、校验和地址风险检查。除验证流程外,还可检查投递状况、已知泄露、临时邮箱、重复使用情况及可选的社交足迹。

主要功能

  1. 01发送一次性邮件验证码
  2. 02校验用户提交的验证码
  3. 03无需发送验证码即可评估邮件风险
  4. 04检查投递情况与已知泄露
  5. 05可选检查社交足迹

适用场景

  1. 01在创建账户时验证邮箱地址
  2. 02拒绝或标记临时邮箱及泄露地址
  3. 03在无验证码流程中评估地址风险

MCP 相关

此技能介绍 Didit Email Verification API;输入未说明 MCP 服务或 MCP 专用接口。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/didit-protocol/skills --skill didit-email-verification

安装后在 Claude Code 中输入/didit-email-verification确认已加载。

附带文件scripts/verify_email.py

详细介绍

Didit 电子邮件验证 API

概览

三个独立端点:

  1. 发送一次性验证码到电子邮件地址:POST /v3/email/send/
  2. 验证用户输入的验证码并获取电子邮件报告:POST /v3/email/check/
  3. 风险评估(不发送验证码):通过一次调用为地址评分:POST /v3/email/risk/

关键限制(发送 + 验证):

  • 验证端点通过你的应用和 email 地址查找验证记录,不接受 request_id。
  • 待处理的验证自首次发送起有效 5 分钟。重试不会延长有效期。
  • 每次验证最多可尝试输入验证码 3 次。第 1 次和第 2 次输入错误验证码会返回 "Failed";第 3 次输入错误验证码会将验证最终状态设为 "Declined"(EMAIL_CODE_ATTEMPTS_EXCEEDED)。
  • 每个待处理的验证可重新发送 一次:在有效期内对同一地址再次发送,会返回带有相同 request_id 和新验证码的 "Retry"(之前的验证码将失效)。之后再发送则会启动新的验证,并生成新的 request_id。
  • 验证码比较时不区分大小写。只有最新的验证码有效。
  • 没有待处理的验证(从未发送、已完成、发送时无法投递,或已超过 5 分钟):验证端点会返回 HTTP 200,并带有 status: "Expired or Not Found"。
  • 每次新验证都会保存为一个 API 会话:request_id 可用于 GET /v3/session/{sessionId}/decision/,并会显示在 Business Console 中;验证进度变化时还会触发 status.updated Webhook。每次风险评估调用也会创建一个 API 会话。

**功能:**已知数据泄露(breaches[])、一次性电子邮件服务提供商检测、可投递性(语法和 DNS/MX)、跨会话重复项(matches[])、你的电子邮件阻止名单/允许名单、可选的社交媒体足迹(enable_social)、欺诈信号。

**沙盒:**沙盒 API 密钥会跳过投递、计费和持久化。发送会返回静态的 "Success" 和随机 request_id;验证时使用验证码 123456(任何格式正确的验证码都会返回简化的 "Approved" 载荷)。风险评估会返回确定性的已批准数据。格式错误的输入仍会返回 400。

**定价:**电子邮件验证每次成功发送("Success")收费 $0.03;"Retry" 和 "Undeliverable" 发送以及验证均免费(可选的社交媒体足迹附加服务除外);独立调用没有免费额度。POST /v3/email/risk/ 没有公布标价(文档称其价格低于电子邮件验证),社交媒体足迹附加服务(enable_social,在端点价格基础上按请求计费;查询未能完成时不收费)也没有公布标价。以上标价有效至 2026 年 11 月 1 日,届时 Didit 将调整定价,每月 500 次免费验证将改为每月 $10 免费额度。请查看 didit.me/pricing 了解当前价格。

API 参考:发送验证码 | 验证验证码 | 电子邮件风险评估 **功能指南:**https://docs.didit.me/core-technology/email-verification/overview


身份验证

每个请求都需要 x-api-key 标头。使用你在 Didit Business Console 的 Developers > API keys 下获取的应用 API 密钥,或通过编程方式创建账户和密钥(参见入门指南)。具有自定义访问权限的命名密钥需要 Sessions 写入权限才能运行独立验证;仅限于部分工作流或已批准会话的密钥无法运行这些验证。

快速开始(还没有账户?)

如果你还没有 Didit API 密钥,只需调用 2 次 API 即可创建:

  1. 注册: 使用 {"email": "[email protected]", "password": "MyStr0ng!Pass"} 调用 POST https://apx.didit.me/auth/v2/programmatic/register/
  2. 检查电子邮件,获取 6 个字符的验证码
  3. 验证: 使用 {"email": "[email protected]", "code": "A3K9F2"} 调用 POST https://apx.didit.me/auth/v2/programmatic/verify-email/。密钥位于响应的 application.api_key 中。

添加额度: 使用 GET /v3/billing/balance/ 查看余额;使用 POST /v3/billing/top-up/ 并传入 {"amount_in_dollars": 50} 获取 Stripe 结账链接。

如需全面的平台管理(工作流、会话、用户、账单),请参阅 didit-verification-management 技能。


步骤 1:发送电子邮件验证码

POST https://verification.didit.me/v3/email/send/
请求头
请求头值必填
x-api-key你的 API 密钥是
Content-Typeapplication/json是
请求体(JSON)
参数类型必填默认值限制描述
email字符串是-有效电子邮件地址,最多 254 个字符验证码的发送地址
options.code_size整数否64-8验证码长度
options.alphanumeric_code布尔值否false-true = 使用大写字母 A-Z 和数字 0-9,而不是仅使用数字
options.locale字符串否en54 种代码之一模板语言,例如 en、es、fr、pt-BR、zh-CN、zh-TW。不支持的值会返回 400,并列出支持的值
options.use_white_label_customization布尔值否false-使用应用的白标品牌样式,而不是 Didit 模板
signals.ip字符串否-IPv4 或 IPv6用于欺诈检测的最终用户 IP
signals.device_id字符串否-最多 255 个字符Android ANDROID_ID、iOS identifierForVendor
signals.device_platform字符串否-android、ios、ipados、tvos、web设备平台
signals.device_model字符串否-最多 255 个字符例如 iPhone17,2
signals.os_version字符串否-最多 64 个字符例如 18.0.1
signals.app_version字符串否-最多 64 个字符例如 1.2.34
signals.user_agent字符串否-最多 512 个字符浏览器或应用的 user agent
vendor_data字符串否--你的用户 ID。存储在会话中(从首次发送起),并在发送、检查和 Webhook 中原样返回
metadata对象否nullJSON 对象任意格式的数据,存储在会话中并在响应中原样返回
示例
import requests

response = requests.post(
    "https://verification.didit.me/v3/email/send/",
    headers={"x-api-key": "YOUR_API_KEY", "Content-Type": "application/json"},
    json={
        "email": "[email protected]",
        "options": {"code_size": 6, "locale": "en"},
        "signals": {"ip": "203.0.113.42"},
        "vendor_data": "user-1234",
    },
    timeout=30,
)
print(response.status_code, response.json())
const response = await fetch("https://verification.didit.me/v3/email/send/", {
  method: "POST",
  headers: { "x-api-key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({
    email: "[email protected]",
    options: { code_size: 6, locale: "en" },
    signals: { ip: "203.0.113.42" },
    vendor_data: "user-1234",
  }),
});
const data = await response.json(); // { request_id, status, reason, vendor_data, metadata }
响应(200 OK)
{
  "request_id": "e39cb057-92fc-4b59-b84e-02fec29a0f24",
  "status": "Success",
  "reason": null,
  "vendor_data": "user-1234",
  "metadata": null
}
状态值与处理方式
状态含义操作
"Success"已为新的验证发送电子邮件验证码(计费)等待用户提供验证码,然后调用 Check
"Retry"在 5 分钟窗口内第二次发送:为同一验证发送新验证码,request_id 不变,之前的验证码失效(免费)等待用户提供新验证码,然后调用 Check
"Undeliverable"地址未通过语法或 DNS/MX 验证,或电子邮件无法发送。reason 为 "email_can_not_be_delivered"。未发送电子邮件,不产生费用;验证已最终判定为 Declined(调用检查会返回 "Expired or Not Found")请用户提供其他地址
错误响应
代码含义操作
400请求无效查看响应正文中的字段错误(格式错误的 email、超出 4-8 范围的 options.code_size、不受支持的 options.locale)
401API 密钥已过期轮换密钥,或在 Developers > API keys 中创建新密钥
403缺少、错误或已撤销的 API 密钥;无权访问此端点的范围限定密钥;来自密钥 IP 允许列表之外的请求;或余额不足查看 detail 或 error 中的消息:修正 x-api-key 标头或密钥权限,或充值
429速率限制:每个密钥每分钟允许 300 个 POST/PATCH/DELETE 请求和 600 个 GET 请求等待 Retry-After 指定的秒数,然后重试

发送前会检查余额:余额不足时返回 403,并附带 {"error": "You don't have enough credits to perform this request."}。


第 2 步:验证邮箱验证码

验证验证码并返回邮箱报告。请先调用 Send,并使用相同的 email。

POST https://verification.didit.me/v3/email/check/

标头:与第 1 步相同。

请求正文(JSON)
参数类型必填默认值值描述
emailstring是-有效邮箱第 1 步中使用的同一地址(用于将验证与发送关联起来)
codestring是-最多 10 个字符用户收到的验证码(4-8 个字符,不区分大小写)
duplicated_email_actionstring否"NO_ACTION""NO_ACTION" / "DECLINE"该地址已被应用中的其他用户批准(vendor_data 不同)
breached_email_actionstring否"NO_ACTION""NO_ACTION" / "DECLINE"该地址出现在已知数据泄露事件中
disposable_email_actionstring否"NO_ACTION""NO_ACTION" / "DECLINE"域名属于一次性或临时邮箱服务提供商
enable_socialboolean否false-同时查询该地址的社交网络足迹(添加 email.email_social;作为附加项按请求计费)
email_no_social_presence_actionstring否"NO_ACTION""NO_ACTION" / "DECLINE"如果社交足迹检查发现该地址未在任何平台注册(profiles_registered: 0),则拒绝。需要启用 enable_social: true

策略说明: 如果检测到风险,DECLINE 会将正确的验证码判定为 "Declined"。NO_ACTION 会将风险记录在 email.warnings 中(日志类型为 information),但不会更改状态。已列入阻止名单或无法投递的地址始终会被拒绝。此处仅接受 NO_ACTION 和 DECLINE。

示例
response = requests.post(
    "https://verification.didit.me/v3/email/check/",
    headers={"x-api-key": "YOUR_API_KEY", "Content-Type": "application/json"},
    json={
        "email": "[email protected]",
        "code": "123456",
        "breached_email_action": "DECLINE",
        "disposable_email_action": "DECLINE",
    },
    timeout=30,
)
result = response.json()
if result["status"] in ("Approved", "Declined"):
    print(result["email"]["is_breached"], result["email"]["is_disposable"])
const response = await fetch("https://verification.didit.me/v3/email/check/", {
  method: "POST",
  headers: { "x-api-key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({
    email: "[email protected]",
    code: "123456",
    breached_email_action: "DECLINE",
    disposable_email_action: "DECLINE",
  }),
});
const result = await response.json(); // inspect result.status, not the HTTP code
响应(200 OK)
{
  "request_id": "e39cb057-92fc-4b59-b84e-02fec29a0f24",
  "status": "Approved",
  "message": "The verification code is correct.",
  "email": {
    "status": "Approved",
    "email": "[email protected]",
    "is_breached": false,
    "breaches": [],
    "is_disposable": false,
    "is_undeliverable": false,
    "verification_attempts": 1,
    "verified_at": "2026-06-12T01:24:47.311323Z",
    "warnings": [],
    "lifecycle": [
      {"type": "EMAIL_VERIFICATION_MESSAGE_SENT", "timestamp": "2026-06-12T01:23:39.580554+00:00", "details": {"status": "Success", "reason": null}, "fee": 0.03},
      {"type": "VALID_CODE_ENTERED", "timestamp": "2026-06-12T01:24:47.311201+00:00", "details": {"code_tried": "123456", "status": "Approved"}, "fee": 0},
      {"type": "EMAIL_VERIFICATION_APPROVED", "timestamp": "2026-06-12T01:24:47.384292+00:00", "details": null, "fee": 0}
    ],
    "matches": []
  },
  "vendor_data": "user-1234",
  "metadata": null,
  "created_at": "2026-06-12T01:24:47.401719+00:00"
}

验证码错误但仍有尝试次数:

{
  "request_id": "11111111-2222-3333-4444-555555555555",
  "status": "Failed",
  "message": "The verification code is incorrect. Attempts remaining: 2",
  "email": null,
  "vendor_data": "user-1234",
  "metadata": null,
  "created_at": "2026-06-12T01:24:21.512340+00:00"
}
状态值与处理方式
状态含义request_id / email操作
"Approved"验证码正确,且未检测到会导致拒绝的风险发送操作的会话 ID / 完整报告邮箱已验证,继续操作
"Declined"终止状态:验证码正确但匹配到会导致拒绝的风险(使用了 DECLINE 操作、地址已列入阻止名单或无法投递),或第 3 次验证码错误发送操作的会话 ID / 完整报告查看 email.warnings;阻止操作或要求提供其他地址
"Failed"验证码错误,仍有尝试次数(message 会说明剩余次数)一次性 UUID / null要求用户重新输入验证码
"Expired or Not Found"过去 5 分钟内没有此地址的待处理验证一次性 UUID / 不存在发送新验证码(第 1 步)
错误响应
代码含义操作
400请求无效查看响应正文中的字段错误(格式错误的 email、缺少 code、操作不是 NO_ACTION/DECLINE)
401API 密钥已过期轮换密钥,或在 Developers > API keys 中创建新密钥
403缺少、错误或已撤销的 API 密钥;无权访问此端点的受限密钥;来自密钥 IP 允许列表之外的请求;或额度不足查看 detail 或 error 中的消息:修正 x-api-key 标头或密钥的访问权限,或充值
429速率限制:每个密钥每分钟可发送 300 个 POST/PATCH/DELETE 请求和 600 个 GET 请求等待 Retry-After 秒后重试

检查是免费的;唯一会检查额度的是 enable_social 附加项(余额不足时返回带有 error 的 403)。


邮箱风险(不发送验证码)

通过一次同步调用为地址评分:可送达性、一次性邮箱域名、泄露记录、重复项和标准化风险情报。不会发送邮件,用户也无需执行任何操作。创建一个 API 会话(request_id)。

POST https://verification.didit.me/v3/email/risk/
请求正文(JSON)
参数类型必填默认值描述
emailstring是-评分的邮箱地址
country_codestring否-用于情报覆盖范围的 ISO 3166-1 alpha-2 或 alpha-3 国家/地区提示(最多 3 个字符)
signalsobject否-与步骤 1 中 signals 的字段相同(ip、device_id、device_platform、device_model、os_version、app_version、user_agent)
enable_socialboolean否false添加 email.email_social 区块(作为附加项按请求计费)
vendor_datastring否-你的参考信息,会被存储并在响应中返回
metadataobject否null你的 JSON 元数据,会被存储并在响应中返回
示例
response = requests.post(
    "https://verification.didit.me/v3/email/risk/",
    headers={"x-api-key": "YOUR_API_KEY", "Content-Type": "application/json"},
    json={"email": "[email protected]", "country_code": "US", "vendor_data": "lead-123"},
    timeout=30,
)
result = response.json()
print(result["status"], result["email"]["is_breached"], result["email"]["is_disposable"])
const response = await fetch("https://verification.didit.me/v3/email/risk/", {
  method: "POST",
  headers: { "x-api-key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({ email: "[email protected]", country_code: "US", vendor_data: "lead-123" }),
});
const result = await response.json();
响应(200 OK)
{
  "request_id": "82397be9-5921-4970-a979-2d5b43e08b33",
  "status": "Approved",
  "email": {
    "status": "Approved",
    "email": "[email protected]",
    "is_breached": false,
    "breaches": [],
    "is_disposable": false,
    "is_undeliverable": false,
    "verification_attempts": 0,
    "verified_at": null,
    "warnings": [],
    "lifecycle": [],
    "matches": [],
    "email_intelligence": {
      "score": 4.0,
      "deliverable": "high",
      "breach_risk_level": "Low",
      "breach_risk_index": 4,
      "is_recent_breach": false,
      "is_frequent_breached": false,
      "is_disposable": false,
      "is_free_domain": false,
      "is_breached": false,
      "no_of_breaches": 0,
      "reason_codes": []
    },
    "enrichment": {
      "score": 4.0,
      "deliverable": "high",
      "breach_risk_level": "Low",
      "breach_risk_index": 4,
      "is_recent_breach": false,
      "is_frequent_breached": false,
      "is_disposable": false,
      "is_free_domain": false,
      "is_breached": false,
      "no_of_breaches": 0,
      "reason_codes": []
    }
  },
  "vendor_data": "lead-123",
  "metadata": null,
  "created_at": "2026-09-01T10:30:00.123456+00:00"
}
  • status(顶层和 email.status):"Approved"、"In Review" 或 "Declined"。通常为 "Approved";你的应用的邮箱风险规则可能会产生其他结果。每次已完成的查询,HTTP 状态码均为 200。
  • email.email_intelligence 和 email.enrichment 是同一对象(兼容性别名)。它们是尽力返回的:如果没有可用的情报数据,两个键都会缺失。请优先根据 is_breached、is_disposable 和 is_undeliverable 制定规则,并将缺失的区块视为“未知”,而非“安全”。
  • 查询一旦开始即会计费,即使尽力返回的字段缺失也是如此。

错误:与步骤 2 的表格相同(400 字段错误、401、403(包括此调用及 enable_social 附加项的额度检查)、429)。


响应字段参考

email 对象(检查与风险)
字段类型描述
statusstring检查:最终检查时为 "Approved" 或 "Declined"。风险:"Approved"、"In Review"、"Declined"
emailstring地址
is_breachedboolean是否在已知数据泄露事件中被发现
breachesarray最近最多 5 起数据泄露事件:{name, domain, breach_date, breach_emails_count, description, logo_path, data_classes, is_verified}。description 可能包含 HTML
is_disposableboolean域名是否属于一次性或临时邮箱服务提供商
is_undeliverableboolean是否无法接收邮件(语法、DNS/MX 或退信原因)
verification_attemptsinteger此次验证发送验证码的次数(1 次;重试后为 2 次)。风险查询时为 0
verified_atstring or null正确输入验证码的时间
warningsarray{feature, risk, additional_data, log_type, short_description, long_description}。log_type:error 表示拒绝,warning 表示标记以供审核,information 仅记录
lifecyclearray{type, timestamp, details, fee}。类型:EMAIL_VERIFICATION_MESSAGE_SENT、EMAIL_VERIFICATION_RETRY_MESSAGE_SENT、VALID_CODE_ENTERED、INVALID_CODE_ENTERED、EMAIL_VERIFICATION_APPROVED、EMAIL_VERIFICATION_DECLINED、EMAIL_VERIFICATION_IN_REVIEW、EMAIL_VERIFICATION_EXPIRED。仅首次成功发送时,fee(USD)才非零
matchesarray最多 5 个来自你应用的其他会话,其中不同用户(vendor_data)使用了此地址:{session_id, session_number, vendor_data, verification_date, email, status, is_blocklisted, api_service, source}。source 为 session;若为屏蔽列表条目,则为 list_entry(session_id/session_number 为 null)
email_intelligence / enrichmentobject仅风险端点提供,尽力返回:score(0-100,分数越高风险越大)、deliverable、breach_risk_level(Low/Medium/High)、breach_risk_index、is_recent_breach、is_frequent_breached、is_disposable、is_free_domain、is_breached、no_of_breaches、reason_codes(开放列表;不要拒绝未知代码)
email_socialobject仅在设置 enable_social: true 且查询已完成时提供。见下文
email_social 对象
字段描述
profiles_registered / profiles_checked已注册该地址的平台数量 / 已检查的平台数量。注册数为 0 是真实且计费的结果(常见的合成身份信号)
names_found、photos_found、communication_breadth、digital_footprint_diversity计数
digital_sophistication_index、engagement_depth_index、subscription_affordability_index0-10 的综合指标
free_platforms、full_paid_platforms、partial_paid_platforms按平台定价模式划分的注册情况
registered_platforms、not_registered_platforms平台列表,包含 category 和 scope(global 或 local)
categories、profiles按类别统计的注册数量和比例;以及在提供时按平台列出的档案详情

如果查询未返回某项数据,任何计数都可能为 null。


警告标签

标签严重级别描述
EMAIL_CODE_ATTEMPTS_EXCEEDEDerror(始终拒绝)独立验证中第 3 次输入错误的验证码
EMAIL_IN_BLOCKLISTerror(始终拒绝)地址位于你的邮箱黑名单(Lists API)中,或匹配了被列入黑名单的验证记录。additional_data:blocklisted_session_id、blocklisted_session_number、api_service(仅命中名单时均为 null)
UNDELIVERABLE_EMAIL_DETECTED取决于 breached_email_action地址无法接收邮件
BREACHED_EMAIL_DETECTED取决于 breached_email_action在已知泄露事件中发现(参见 breaches[])
DISPOSABLE_EMAIL_DETECTED取决于 disposable_email_action一次性或临时邮箱域名
DUPLICATED_EMAIL取决于 duplicated_email_action已批准给其他用户。additional_data:duplicated_session_id、duplicated_session_number、api_service
EMAIL_IN_ALLOWLISTinformation地址位于你的邮箱允许名单中,因此跳过了重复项操作

每次尝试最多触发 EMAIL_IN_BLOCKLIST、DUPLICATED_EMAIL 和 EMAIL_IN_ALLOWLIST 中的一个(依次检查黑名单、重复项和允许名单)。在此 API 中,DECLINE 操作会生成 error 类型的日志,NO_ACTION 则会生成 information 类型的日志。


常见工作流

基本邮箱验证
1. POST /v3/email/send/   -> {"email": "[email protected]"}
   If "Undeliverable"     -> ask for another address (nothing billed)
2. Wait for the user to type the code (valid 5 minutes from the first send)
3. POST /v3/email/check/  -> {"email": "[email protected]", "code": "123456"}
4. If "Approved"             -> email verified
   If "Failed"               -> ask the user to retry (3 attempts in total)
   If "Declined"             -> read email.warnings
   If "Expired or Not Found" -> go back to step 1
严格安全验证
1. POST /v3/email/send/   -> include signals.ip, signals.device_id, signals.user_agent and vendor_data
2. Wait for the user's code
3. POST /v3/email/check/  -> duplicated_email_action, breached_email_action, disposable_email_action = "DECLINE"
4. If "Approved"  -> safe to proceed
   If "Declined"  -> email.warnings[].risk says why; block or ask for another address
无需验证码的预筛选
1. POST /v3/email/risk/   -> {"email": "[email protected]", "vendor_data": "lead-123"}
2. If email.is_undeliverable or email.is_disposable -> reject before sending any OTP
3. Otherwise continue with the send/check flow above

实用脚本

verify_email.py:从命令行发送验证码、验证验证码并评估邮箱风险。

# Requires: pip install requests
export DIDIT_API_KEY="your_api_key"

python scripts/verify_email.py send [email protected] --locale es
python scripts/verify_email.py check [email protected] 123456 --decline-breached --decline-disposable
python scripts/verify_email.py risk [email protected] --country-code US

也可以作为库导入:

from scripts.verify_email import send_code, check_code, score_email_risk

send_result = send_code("[email protected]")
check_result = check_code("[email protected]", "123456", decline_breached=True)
risk_result = score_email_risk("[email protected]")

评论

支持 Markdown