mcpField
D
didit-phone-verification

didit-phone-verification

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

关于 didit-phone-verification

面向需要手机号验证和风险检查的应用,介绍 Didit API 的独立接口。涵盖验证码发送与校验,以及手机号风险信号查询。

主要功能

  1. 01通过可用渠道发送一次性验证码
  2. 02校验验证码并返回手机号报告
  3. 03无需发送验证码即可评估手机号风险
  4. 04检查运营商、线路类型和欺诈信号

适用场景

  1. 01在注册时确认用户手机号
  2. 02识别一次性号码、VoIP 或重复号码
  3. 03在账户操作前进行手机号风险检查

安装

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

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

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

附带文件scripts/verify_phone.py

详细介绍

Didit Phone Verification API

概览

三个独立端点:

  1. 发送一次性验证码到电话号码:POST /v3/phone/send/
  2. 验证用户输入的验证码并获取电话报告:POST /v3/phone/check/
  3. 风险评估(不发送验证码):通过一次调用评估号码:POST /v3/phone/risk/

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

  • 电话号码必须采用 E.164 格式(例如 +14155552671)。系统会验证并规范化号码;无效号码会返回 400。
  • 验证操作会根据你的应用和 phone_number 查找验证记录。它不接受 request_id。
  • 待处理的验证自首次发送起有效 5 分钟。重试不会延长有效期。
  • 每个待处理的验证可重试一次:在有效期内,对同一号码进行第二次发送会返回 "Retry",并使用相同的 request_id(总计发送 2 次)。之后再次发送会使用新的 request_id 开始新的验证。
  • 每次验证可尝试输入验证码 3 次。第 1 次和第 2 次输入错误验证码会返回 "Failed";第 3 次输入错误验证码会将验证结果设为 "Declined"(VERIFICATION_CODE_ATTEMPTS_EXCEEDED)。
  • code 必须为 4-8 位数字(^[0-9]{4,8}$)。其他输入会返回 400,且不消耗尝试次数。
  • 防滥用限制:每个电话号码每小时最多 4 次发送尝试(429)。
  • 没有待处理的验证(从未发送、已完成、发送时被阻止或已超过 5 分钟):验证操作会返回 HTTP 200,并包含 status: "Expired or Not Found"。
  • 在你的组织首次充值前,电话验证会一直处于禁用状态(403)。
  • 每次新验证都会存储为 API 会话:request_id 可用于 GET /v3/session/{sessionId}/decision/,会显示在 Business Console 中,并会在验证进度更新时触发 status.updated webhook。

发送渠道: options.preferred_channel 可以是 whatsapp(默认)、sms、telegram、voice、rcs、viber 或 zalo(可用性因国家/地区而异)。如果该号码无法使用首选渠道,系统会回退到 SMS,且发送仍会报告 "Success";实际使用的渠道会显示在 phone.verification_method 和 phone.lifecycle 的发送事件中(details.actual_channel)。

品牌定制: SMS 验证码会使用你的应用的 SMS 发送方名称(在 Business Console 中设置),无需额外费用。options.sms_sender_name 可使用其他名称发送单个验证码;如果未设置发送方名称,options.use_white_label_customization: true 会使用你的白标公开名称。WhatsApp 验证码使用固定消息,不支持品牌定制。

功能: 运营商名称和线路类型、VoIP/虚拟号码和一次性号码、你的会话中的重复号码(matches[])、你的电话黑名单/白名单、发送时的反欺诈拦截、可选的社交足迹(enable_social)、欺诈信号。

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

定价: Phone Verification 每条发送的消息收费 $0.04 + 运营商费用,费用按目的地国家/地区和实际发送渠道计算(价格表);除 "Blocked" 外,每次发送都会计费,包括 "Retry";验证免费(可选的社交附加功能除外);独立调用没有免费额度。POST /v3/phone/risk/ 没有公布标价(文档称其价格低于 Phone Verification);社交足迹附加功能(enable_social)也没有公布标价(在端点价格基础上按请求计费;查询无法完成时不计费)。这些标价适用至 2026 年 11 月 1 日,届时 Didit 将调整定价,每月 500 次免费验证将改为每月 $10 的免费额度。请访问 didit.me/pricing 查看当前价格。 API 参考:发送验证码 | 校验验证码 | 手机号风险 **功能指南:**https://docs.didit.me/core-technology/phone-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 skill。


第 1 步:发送手机验证码

POST https://verification.didit.me/v3/phone/send/
标头
标头值必填
x-api-key你的 API 密钥是
Content-Typeapplication/json是
请求体(JSON)
参数类型必填默认值限制说明
phone_numberstring是-E.164,最多 20 位手机号码(例如 +14155552671)
options.code_sizeinteger否64-8验证码位数
options.localestring否-最多 5 个字符,BCP-47(^[a-z]{2,3}(-[A-Z]{2,3})?$)短信语言,例如 en-US、fr、es
options.preferred_channelstring否"whatsapp"whatsapp、sms、telegram、voice、rcs、viber、zalo首选渠道;不可用时回退到 SMS
options.sms_sender_namestring or null否你的应用的 SMS 发件人名称1-30 个字符:字母、数字、空格和 ' & - !;不能仅包含数字,且只能使用单个空格此名称会显示在该验证码短信中(“123456 is your verification code for Example Bank”)。无效值会返回 400,且不会发送验证码。每个应用每天(UTC)最多可开始使用两个新名称;超过后将使用应用名称。免费
options.use_white_label_customizationboolean否false-未设置 SMS 发件人名称时,使用你的白标公开名称作为 SMS 签名
signals.ipstring否-IPv4 或 IPv6用于欺诈检测的最终用户 IP
signals.device_idstring否-最多 255 个字符Android ANDROID_ID、iOS identifierForVendor
signals.device_platformstring否-android、ios、ipados、tvos、web设备平台
signals.device_modelstring否-最多 255 个字符例如 iPhone17,2
signals.os_versionstring否-最多 64 个字符例如 18.0.1
signals.app_versionstring否-最多 64 个字符例如 1.2.34
signals.user_agentstring否-最多 512 个字符浏览器或应用的 user agent
vendor_datastring否--你的用户 ID。此数据会存储在会话中(从首次发送开始),并在发送、校验和 Webhook 中返回
metadataobject否nullJSON 对象任意格式的数据,会存储在会话中并在响应中返回
示例
import requests

response = requests.post(
    "https://verification.didit.me/v3/phone/send/",
    headers={"x-api-key": "YOUR_API_KEY", "Content-Type": "application/json"},
    json={
        "phone_number": "+14155552671",
        "options": {"preferred_channel": "sms", "code_size": 6, "sms_sender_name": "Example Bank"},
        "signals": {"ip": "203.0.113.42", "device_platform": "ios"},
        "vendor_data": "user-1234",
    },
    timeout=30,
)
print(response.status_code, response.json())
const response = await fetch("https://verification.didit.me/v3/phone/send/", {
  method: "POST",
  headers: { "x-api-key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({
    phone_number: "+14155552671",
    options: { preferred_channel: "whatsapp", code_size: 6, locale: "en-US" },
    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
"Blocked"反欺诈层拒绝发送。reason 会说明原因(例如 suspicious、spam)。不计费。验证会立即结束(状态为 Declined,并附带 HIGH_RISK_PHONE_NUMBER;对于允许名单中的号码,状态为 In Review),因此之后的检查会返回 "Expired or Not Found"不要对同一号码重试;请索要另一个号码或进行审核
错误响应
代码含义操作
400请求无效查看响应正文中的字段错误。格式可解析但无法接收验证码的号码会返回 {"detail": "Invalid phone number provided."} 或 {"detail": "Invalid phone line type provided."}(例如短代码)
401API 密钥已过期在 Developers > API keys 中轮换密钥或创建新密钥
403API 密钥缺失、错误或已撤销;受限密钥无权访问此端点;请求来自密钥 IP 允许名单之外;或额度不足查看 detail 或 error 中的消息:修正 x-api-key 标头或密钥访问权限,或充值
429速率限制:每个密钥每分钟最多 300 个 POST/PATCH/DELETE 请求和 600 个 GET 请求等待 Retry-After 秒后重试
502电话服务提供商暂时不可用:{"detail": "...", "code": "phone_provider_unavailable"}稍等片刻后重试。不计费,也不消耗尝试次数

电话验证的特殊情况:如果 403 的 detail 表示电话验证已禁用,直到贵组织首次充值(沙盒应用仍可免费测试);以及余额不足以支付目标号码的发送价格时,返回带有 error 的 403。对同一号码尝试次数过多(每小时 4 次)时会返回 429,且不包含 Retry-After 标头:请等待,或使用其他号码。


步骤 2:检查电话验证码

验证验证码并返回电话报告。先调用 Send,并使用相同的 phone_number。

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

标头:与步骤 1 相同。

正文(JSON)
参数类型必填默认值值描述
phone_numberstring是-E.164步骤 1 中使用的同一号码(用于将检查与发送关联起来)
codestring是-4-8 位数字用户收到的验证码
duplicated_phone_number_actionstring否"NO_ACTION""NO_ACTION" / "DECLINE"本应用中已被其他用户使用的号码(vendor_data 不同)
disposable_number_actionstring否"NO_ACTION""NO_ACTION" / "DECLINE"临时号码或一次性号码(phone.is_disposable)
voip_number_actionstring否"NO_ACTION""NO_ACTION" / "DECLINE"虚拟线路:voip、isp 或 vpn(phone.is_virtual)
enable_socialboolean否false-同时查询该号码的社交足迹(添加 phone.phone_social;按请求作为附加项计费)
phone_no_social_presence_actionstring否"NO_ACTION""NO_ACTION" / "DECLINE"如果社交足迹检查发现该号码未注册任何平台(profiles_registered: 0),则拒绝。需要 enable_social: true

策略说明: 如果发现风险,DECLINE 会将正确的验证码判定为 "Declined"。NO_ACTION 会将风险记录在 phone.warnings 中(日志类型为 information),但不会更改状态。列入黑名单的号码始终会被拒绝。此处仅接受 NO_ACTION 和 DECLINE。

示例
response = requests.post(
    "https://verification.didit.me/v3/phone/check/",
    headers={"x-api-key": "YOUR_API_KEY", "Content-Type": "application/json"},
    json={
        "phone_number": "+14155552671",
        "code": "123456",
        "disposable_number_action": "DECLINE",
        "voip_number_action": "DECLINE",
    },
    timeout=30,
)
result = response.json()
if result["status"] in ("Approved", "Declined"):
    print(result["phone"]["carrier"], result["phone"]["is_virtual"])
const response = await fetch("https://verification.didit.me/v3/phone/check/", {
  method: "POST",
  headers: { "x-api-key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({
    phone_number: "+14155552671",
    code: "123456",
    voip_number_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.",
  "phone": {
    "status": "Approved",
    "phone_number_prefix": "+1",
    "phone_number": "4155552671",
    "full_number": "+14155552671",
    "country_code": "US",
    "country_name": "United States",
    "carrier": {"name": "Example Mobile", "type": "mobile"},
    "is_disposable": false,
    "is_virtual": false,
    "verification_method": "whatsapp",
    "verification_attempts": 1,
    "verified_at": "2026-06-12T01:24:47.311323Z",
    "warnings": [],
    "lifecycle": [
      {"type": "PHONE_VERIFICATION_MESSAGE_SENT", "timestamp": "2026-06-12T01:23:39.580554+00:00", "details": {"status": "Success", "reason": null, "channel": "whatsapp", "actual_channel": "whatsapp"}, "fee": 0.0709},
      {"type": "PHONE_DELIVERY_DELIVERED", "timestamp": "2026-06-12T01:23:43.118220+00:00", "details": {"channel": "whatsapp", "status": "delivered"}, "fee": 0},
      {"type": "VALID_CODE_ENTERED", "timestamp": "2026-06-12T01:24:47.311201+00:00", "details": {"code_tried": "123456", "status": "Approved"}, "fee": 0},
      {"type": "PHONE_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"
}

如果验证码错误但仍有剩余尝试次数,则会返回 "status": "Failed"、"message": "The verification code is incorrect. Attempts remaining: 2" 和 "phone": null。

状态值与处理方式
状态含义request_id / phone操作
"Approved"代码正确,且未匹配到拒绝风险发送请求的会话 ID / 完整报告手机号已验证,继续
"Declined"终止状态:代码正确,但匹配到拒绝风险(DECLINE 操作、列入黑名单或高风险号码),或第 3 次输入错误代码发送请求的会话 ID / 完整报告读取 phone.warnings;拦截该号码或要求用户提供另一个号码
"Failed"代码错误,仍有剩余尝试次数(message 会说明剩余次数)一次性 UUID / null要求用户重新输入代码
"Expired or Not Found"最近 5 分钟内没有该号码的待处理验证一次性 UUID / 缺失发送新代码(步骤 1)
错误响应
代码含义操作
400请求无效读取响应正文中的字段错误(代码不是 4-8 位数字、号码无效、操作不是 NO_ACTION / DECLINE)。不会消耗尝试次数
401API 密钥已过期轮换密钥,或在 Developers > API keys 中创建新密钥
403API 密钥缺失、错误或已撤销;受限密钥无权访问此端点;请求来自密钥 IP 允许列表之外;或点数不足读取 detail 或 error 中的消息:修复 x-api-key 标头或密钥权限,或充值
429速率限制:每个密钥每分钟最多 300 个 POST/PATCH/DELETE 请求和 600 个 GET 请求等待 Retry-After 秒后重试
502电话服务提供商暂时不可用("code": "phone_provider_unavailable")短暂退避后重试。不会消耗尝试次数

检查免费;唯一的点数检查针对 enable_social 附加功能(余额不足以支付时返回带有 error 的 403)。


手机号风险(不发送代码)

通过一次同步调用对号码进行评分:运营商、线路类型、携号转网、一次性号码、重复项和标准化风险情报。不会发送代码,用户无需执行任何操作。会创建一个 API 会话(request_id)。

POST https://verification.didit.me/v3/phone/risk/
正文(JSON)
参数类型必填默认值说明
phone_number字符串是-要评分的号码(最多 20 位,会标准化为 E.164 格式)
country_code字符串否-ISO 3166-1 alpha-2 或 alpha-3 国家/地区提示(最多 3 个字符)
signals对象否-与步骤 1 中的 signals 字段相同
enable_social布尔值否false添加 phone.phone_social 块(按请求收取附加费用)
vendor_data字符串否-你的参考信息,会被存储并回传
metadata对象否null你的 JSON 元数据,会被存储并回传
示例
response = requests.post(
    "https://verification.didit.me/v3/phone/risk/",
    headers={"x-api-key": "YOUR_API_KEY", "Content-Type": "application/json"},
    json={"phone_number": "+14155552671", "country_code": "US", "vendor_data": "lead-123"},
    timeout=30,
)
result = response.json()
print(result["status"], result["phone"]["is_virtual"], result["phone"].get("phone_intelligence"))
const response = await fetch("https://verification.didit.me/v3/phone/risk/", {
  method: "POST",
  headers: { "x-api-key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({ phone_number: "+14155552671", country_code: "US", vendor_data: "lead-123" }),
});
const result = await response.json();
响应(200 OK)
{
  "request_id": "4fd09d2e-9bc9-4c4e-9c46-7f625ac0ab62",
  "status": "Approved",
  "phone": {
    "status": "Approved",
    "phone_number_prefix": "+1",
    "phone_number": "4155552671",
    "full_number": "+14155552671",
    "country_code": "US",
    "country_name": "United States",
    "carrier": {"name": "Example Mobile", "type": "mobile"},
    "is_disposable": false,
    "is_virtual": false,
    "verification_method": null,
    "verification_attempts": 0,
    "verified_at": null,
    "warnings": [],
    "lifecycle": [],
    "matches": [],
    "phone_intelligence": {
      "score": 3.0,
      "phone_type_risk": "Low",
      "phone_trust_index": 97,
      "network_stability_index": 95,
      "is_disposable": false,
      "is_ported": false,
      "is_recently_ported": false,
      "carrier_type": "mobile",
      "reason_codes": []
    },
    "enrichment": {
      "score": 3.0,
      "phone_type_risk": "Low",
      "phone_trust_index": 97,
      "network_stability_index": 95,
      "is_disposable": false,
      "is_ported": false,
      "is_recently_ported": false,
      "carrier_type": "mobile",
      "reason_codes": []
    }
  },
  "vendor_data": "lead-123",
  "metadata": null,
  "created_at": "2026-09-01T10:30:00.123456+00:00"
}
  • status(顶层和 phone.status):"Approved"、"In Review" 或 "Declined"。通常为 "Approved";你的应用的手机号风险规则可能会产生其他状态。每次查询完成后,HTTP 状态码均为 200。
  • phone.phone_intelligence 和 phone.enrichment 是同一对象(兼容性别名)。这两个键在未返回可用情报时都会缺失。优先依据 is_disposable 和 is_virtual 制定规则;缺少相关数据块时应视为“未知”,而非“安全”。如果未能解析出运营商,phone.carrier 可能为 null。
  • 查询开始时即会计费,即使缺少尽力获取的字段也不例外。

错误:400 字段错误、401、403(包括此次调用及 enable_social 附加功能的点数检查)、429,与步骤 2 相同。


响应字段参考

phone 对象(检查和风险)
字段类型描述
status字符串检查:最终检查结果为 "Approved" 或 "Declined"(枚举还包括 "In Review"、"Not Finished"、"Expired")。风险:"Approved"、"In Review"、"Declined"
phone_number_prefix字符串带 + 的国家/地区拨号代码(例如 +1)
phone_number字符串不含拨号代码的本地号码
full_number字符串完整的 E.164 号码
country_code / country_name字符串该号码所属国家/地区的 ISO 3166-1 alpha-2 代码及其名称
carrier.name字符串运营商名称(未知时为空字符串)
carrier.type字符串mobile、fixed_line、voip、isp、vpn、toll_free、premium_rate、pager、payphone、satellite、service、shared_cost、short_codes_commercial、calling_cards、local_rate、universal_access、voice_mail、other、unknown
is_disposable布尔值临时号码或一次性号码服务
is_virtual布尔值线路类型为 voip、isp 或 vpn
verification_method字符串确认送达后,实际发送验证码的渠道;否则为请求的渠道。风险查询时为 null
verification_attempts整数此次验证发送验证码的次数(1 次;重试后为 2 次)。风险查询时为 0
verified_at字符串或 null输入正确验证码的时间
warnings数组{feature, risk, additional_data, log_type, short_description, long_description}。log_type:error 表示拒绝,warning 表示标记以供审核,information 仅记录
lifecycle数组{type, timestamp, details, fee}。类型:PHONE_VERIFICATION_MESSAGE_SENT、PHONE_VERIFICATION_RETRY_MESSAGE_SENT、PHONE_VERIFICATION_BLOCKED、PHONE_DELIVERY_DELIVERED、PHONE_DELIVERY_UNDELIVERABLE、VALID_CODE_ENTERED、INVALID_CODE_ENTERED、PHONE_VERIFICATION_APPROVED、PHONE_VERIFICATION_DECLINED、PHONE_VERIFICATION_IN_REVIEW、PHONE_VERIFICATION_EXPIRED。发送事件包含 {status, reason, channel, actual_channel};fee(美元)仅在发送事件中非零
matches数组最多 5 个其他应用会话,其中不同用户(vendor_data)使用了此号码:{session_id, session_number, vendor_data, verification_date, phone_number, status, is_blocklisted, api_service, source}。source 为 session,或在黑名单条目中为 list_entry
phone_intelligence / enrichment对象仅风险端点提供,尽力返回:score(0-100,数值越高风险越高)、phone_type_risk(Low/Medium/High)、phone_trust_index(与评分成反比)、network_stability_index、is_disposable、is_ported、is_recently_ported、carrier_type、reason_codes(开放列表;不要拒绝未知代码)
phone_social对象仅在设置 enable_social: true 且查询完成后提供:profiles_registered / profiles_checked(已注册数量为 0 是真实且可计费的查询结果)、各类数量、0-10 指数、whatsapp_profile_completeness(Basic、Partial、Complete、Not Present)、registered_platforms、not_registered_platforms、categories、profiles。数量可能为 null

警告标签

标签严重性描述
VERIFICATION_CODE_ATTEMPTS_EXCEEDEDerror(始终拒绝)独立验证中第 3 次输入错误的验证码
PHONE_NUMBER_IN_BLOCKLISTerror(始终拒绝)号码位于你的电话黑名单(Lists API)中,或与列入黑名单的会话匹配。additional_data:blocklisted_session_id、blocklisted_session_number、api_service
HIGH_RISK_PHONE_NUMBER默认为 error发送时由反欺诈层拦截("Blocked")后触发;请求会被拒绝。位于你的电话允许名单中的号码则会进入 In Review(log_type: "warning",additional_data.phone_number_in_allowlist: true)。additional_data.blocked_reason 保存发送的 reason
DISPOSABLE_NUMBER_DETECTED由 disposable_number_action 决定临时号码或一次性号码
VOIP_NUMBER_DETECTED由 voip_number_action 决定线路类型为 voip、isp 或 vpn
DUPLICATED_PHONE_NUMBER由 duplicated_phone_number_action 决定其他用户在另一个会话中使用了该号码(任意状态)。additional_data:duplicated_session_id、duplicated_session_number、api_service
PHONE_NUMBER_IN_ALLOWLISTinformation该号码与其他会话匹配,但位于你的电话允许名单中,因此跳过了重复号码操作。additional_data:phone_number

在此 API 中,DECLINE 操作会生成 error 类型的日志,NO_ACTION 会生成 information 类型的日志。


常见工作流

基本电话验证
1. POST /v3/phone/send/   -> {"phone_number": "+14155552671"}
   If "Blocked"           -> ask for another number (nothing billed)
2. Wait for the user to type the code (valid 5 minutes from the first send)
3. POST /v3/phone/check/  -> {"phone_number": "+14155552671", "code": "123456"}
4. If "Approved"             -> phone verified
   If "Failed"               -> ask the user to retry (3 attempts in total)
   If "Declined"             -> read phone.warnings
   If "Expired or Not Found" -> send again (step 1)
严格安全验证
1. POST /v3/phone/send/   -> include signals.ip, signals.device_platform, vendor_data,
                             options.preferred_channel: "sms"
2. POST /v3/phone/check/  -> disposable_number_action, voip_number_action,
                             duplicated_phone_number_action = "DECLINE"
3. If "Declined" -> phone.warnings[].risk says why; block or ask for another number
无需验证码的预筛查
1. POST /v3/phone/risk/   -> {"phone_number": "+14155552671", "vendor_data": "lead-123"}
2. If phone.is_virtual or phone.is_disposable -> reject before sending any OTP
3. Otherwise continue with the send/check flow above

实用脚本

verify_phone.py:从命令行发送验证码、验证验证码并评估电话风险。

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

python scripts/verify_phone.py send +14155552671 --channel sms --sms-sender-name "Example Bank"
python scripts/verify_phone.py check +14155552671 123456 --decline-voip --decline-disposable
python scripts/verify_phone.py risk +14155552671 --country-code US

也可以作为库导入:

from scripts.verify_phone import send_code, check_code, score_phone_risk

send_result = send_code("+14155552671", channel="sms")
check_result = check_code("+14155552671", "123456", decline_voip=True)
risk_result = score_phone_risk("+14155552671")

评论

支持 Markdown