curl -X POST https://verification.didit.me/v3/phone/check/ \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"phone_number": "+14155552671",
"code": "123456",
"voip_number_action": "DECLINE"
}'from didit import Didit
# Reads DIDIT_API_KEY.
client = Didit()
result = client.phone.check_code(
phone_number="+14155552671",
code="123456",
)
print(result)import Didit from "@didit-protocol/sdk-node";
// Reads DIDIT_API_KEY.
const didit = new Didit();
const result = await didit.phone.checkCode({
phone_number: "+14155552671",
code: "123456",
});
console.log(result);ctx := context.Background()
// Reads DIDIT_API_KEY.
client := didit.NewClient()
result, err := client.Phone.CheckCode(ctx, didit.PhoneCheckCodeParams{
PhoneNumber: "+14155552671",
Code: "123456",
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("%+v\n", result)import me.didit.Didit;
import me.didit.types.PhoneCheckCodeParams;
// Reads DIDIT_API_KEY.
Didit client = new Didit();
var result = client.phone().checkCode(PhoneCheckCodeParams.builder()
.phoneNumber("+14155552671")
.code("123456")
.build());
System.out.println(result);<?php
require 'vendor/autoload.php';
use Didit\DiditClient;
// Reads DIDIT_API_KEY.
$didit = new DiditClient();
$result = $didit->phone->checkCode([
'phone_number' => '+14155552671',
'code' => '123456',
]);
print_r($result->toArray());require "didit"
# Reads DIDIT_API_KEY.
didit = Didit::Client.new
result = didit.phone.check_code(
phone_number: "+14155552671",
code: "123456"
)
puts result.to_husing System;
using System.Text.Json;
using Didit;
// Reads DIDIT_API_KEY.
using var client = new DiditClient();
var result = await client.Phone.CheckCodeAsync(new PhoneCheckCodeParams
{
PhoneNumber = "+14155552671",
Code = "123456",
});
Console.WriteLine(JsonSerializer.Serialize(result));{
"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": "AT&T",
"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.0509
},
{
"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"
}手机验证码核验 API:短信 OTP 验证
通过 POST /v3/phone/check/ 核验手机 OTP,同时检测运营商类型、虚拟号码和一次性号码。Didit 提供按量付费,无月度最低消费。
curl -X POST https://verification.didit.me/v3/phone/check/ \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"phone_number": "+14155552671",
"code": "123456",
"voip_number_action": "DECLINE"
}'from didit import Didit
# Reads DIDIT_API_KEY.
client = Didit()
result = client.phone.check_code(
phone_number="+14155552671",
code="123456",
)
print(result)import Didit from "@didit-protocol/sdk-node";
// Reads DIDIT_API_KEY.
const didit = new Didit();
const result = await didit.phone.checkCode({
phone_number: "+14155552671",
code: "123456",
});
console.log(result);ctx := context.Background()
// Reads DIDIT_API_KEY.
client := didit.NewClient()
result, err := client.Phone.CheckCode(ctx, didit.PhoneCheckCodeParams{
PhoneNumber: "+14155552671",
Code: "123456",
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("%+v\n", result)import me.didit.Didit;
import me.didit.types.PhoneCheckCodeParams;
// Reads DIDIT_API_KEY.
Didit client = new Didit();
var result = client.phone().checkCode(PhoneCheckCodeParams.builder()
.phoneNumber("+14155552671")
.code("123456")
.build());
System.out.println(result);<?php
require 'vendor/autoload.php';
use Didit\DiditClient;
// Reads DIDIT_API_KEY.
$didit = new DiditClient();
$result = $didit->phone->checkCode([
'phone_number' => '+14155552671',
'code' => '123456',
]);
print_r($result->toArray());require "didit"
# Reads DIDIT_API_KEY.
didit = Didit::Client.new
result = didit.phone.check_code(
phone_number: "+14155552671",
code: "123456"
)
puts result.to_husing System;
using System.Text.Json;
using Didit;
// Reads DIDIT_API_KEY.
using var client = new DiditClient();
var result = await client.Phone.CheckCodeAsync(new PhoneCheckCodeParams
{
PhoneNumber = "+14155552671",
Code = "123456",
});
Console.WriteLine(JsonSerializer.Serialize(result));{
"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": "AT&T",
"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.0509
},
{
"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"
}处理服务商故障
如果电话服务商暂时不可用,此端点会返回502 以及一个稳定的机器可读代码:
{
"detail": "The phone verification provider is temporarily unavailable.",
"code": "phone_provider_unavailable"
}
情报附加功能
将enable_enrichment 设为 true,即可同时对该号码运行电话情报分析,包括风险评分、线路类型、号码是否近期携号转网,以及信任指数。
该附加功能按标准价格每次请求收取 $0.05,另外还需支付电话验证本身的费用。
当你的余额不足以支付该费用时,请求会返回 403。
四个字段决定信号的处理方式。
每个字段的取值为 NO_ACTION(默认值)或 DECLINE,且仅当 enable_enrichment 为 true 时才生效。
| 字段 | 拒绝条件 |
|---|---|
phone_intelligence_score_action | 风险评分高于阈值。 |
phone_type_risk_action | 号码属于高风险线路类型。 |
recent_port_action | 号码近期已转入其他运营商。 |
low_phone_trust_action | 信任指数等于或低于阈值。 |
NO_ACTION 时,信号仍会在 phone.phone_intelligence 中返回,以便你应用自己的规则。授权
您的应用 API 密钥,可在 Business Console 的“开发者 -> API 密钥”中获取。主密钥拥有完整访问权限。指定名称的密钥可设置作用域:针对每个资源设为无权限、只读或读写,限定于特定工作流或已通过的会话、限定于 IP 地址列表,以及设置到期日期。401 表示密钥错误、已撤销或已过期;403 表示未发送密钥、密钥无权访问该资源或操作,或请求来自其 IP 列表之外的地址;在会话路由上返回 404 表示该会话不在该密钥允许的工作流或状态范围内。没有媒体访问权限的密钥获取到的图片、视频和 PDF URL 将为 null;没有会话写入权限的密钥获取到的会话链接和 token 将为 null。请参阅 https://docs.didit.me/console/api-keys。
请求体
与匹配的 POST /v3/phone/send/ 调用中使用的相同电话号码,采用 E.164 格式。这是将核验与发送关联起来的依据。
20"+14155552671"
终端用户收到的 OTP。必须为 4–8 位数字,其他任何格式都会返回 400 且不消耗尝试次数。格式正确但内容错误的验证码会返回 200 并附带 status: "Failed",同时消耗 3 次尝试机会中的一次。
4 - 8^[0-9]{4,8}$"123456"
当您应用的另一位用户(不同的 vendor_data)已经使用过相同号码时采取的操作。DECLINE 会将最终的 status 变为 Declined;NO_ACTION 会在 phone.warnings 中记录该风险并填充 phone.matches。
NO_ACTION, DECLINE 当运营商查询将该号码标记为临时/一次性线路(phone.is_disposable)时的处理操作。DECLINE 会将最终 status 变为 Declined;NO_ACTION 会在 phone.warnings 中记录该风险。
NO_ACTION, DECLINE 当运营商查询报告虚拟线路类型(voip、isp 或 vpn,phone.is_virtual)时的处理操作。DECLINE 会将最终 status 变为 Declined;NO_ACTION 会在 phone.warnings 中记录该风险。
NO_ACTION, DECLINE 为 true 时,还会对该号码运行电话情报分析:风险评分、线路类型、近期是否携号转网以及信任指数。除此 endpoint 本身的价格外,每次请求按单次 phone_intelligence_api 计费(标价为 $0.05)。当您的余额不足以支付时,请求将返回 403。
false
电话情报风险评分高于阈值时的操作。DECLINE 会将最终 status 翻转为 Declined;NO_ACTION 会记录该信号而不拒绝。仅在 enable_enrichment 为 true 时生效。
NO_ACTION, DECLINE 号码属于高风险线路类型时的操作。DECLINE 会将最终 status 翻转为 Declined;NO_ACTION 会记录该信号而不拒绝。仅在 enable_enrichment 为 true 时生效。
NO_ACTION, DECLINE 号码最近携号转网至另一运营商时的操作。DECLINE 会将最终 status 翻转为 Declined;NO_ACTION 会记录该信号而不拒绝。仅在 enable_enrichment 为 true 时生效。
NO_ACTION, DECLINE 电话情报信任指数处于或低于阈值时的操作。DECLINE 会将最终 status 翻转为 Declined;NO_ACTION 会记录该信号而不拒绝。仅在 enable_enrichment 为 true 时生效。
NO_ACTION, DECLINE 为 true 时,还会查找该号码的社交足迹,即其注册所在的消息、社交、电子商务和职业平台。除此 endpoint 本身的价格外,每次请求按一个 phone_social 计费。
true
社交足迹核查发现该号码在其覆盖的所有平台上均未注册时的操作。此 endpoint 仅接受 NO_ACTION 和 DECLINE;同名工作流配置键上提供 REVIEW。
NO_ACTION, DECLINE 响应
核验已完成:错误的验证码和缺失的验证也会返回 200;请检查 status,而非 HTTP 状态码。phone 仅在最终结果(Approved/Declined)中填充,在 Failed 时为 null,在 Expired or Not Found 时不存在。
状态为 Approved/Declined 时:匹配验证的会话 ID,与 POST /v3/phone/send/ 返回的 request_id 相同。状态为 Failed 和 Expired or Not Found 时:一个随机的一次性 UUID,后续无法查询。
Approved — 验证码正确,无拒绝风险。Declined — 最终状态:匹配到拒绝风险或尝试次数上限(3)已用尽。Failed — 验证码错误,仍有剩余尝试次数。Expired or Not Found — 过去 5 分钟内该号码没有待处理的验证。
Approved, Declined, Failed, Expired or Not Found 结果的便于人类阅读的说明,包括输入错误验证码后的剩余尝试次数。
完整的电话报告。仅在已完成的结果(Approved/Declined)中出现(非 null);状态为 Failed 时为 null,状态为 Expired or Not Found 时不存在。
Show child attributes
Show child attributes
匹配验证会话的 vendor_data。若为 Expired or Not Found 则为 null。
匹配验证会话的 metadata。在 Expired or Not Found 时为 null。
此检查响应的时间戳。