Didit Phone Verification API
Overview
Two-step phone verification via one-time code:
- 1. Send a verification code to a phone number
- Check the code the user provides
Key constraints:
- - Code expires after 5 minutes
- Maximum 3 verification attempts per code (then must resend)
- Maximum 2 resend requests within 24 hours
- Rate limit: 4 sends per hour per phone number
- Phone must be in E.164 format (e.g.
+14155552671) - You must call Send before Check
Delivery channels: SMS (default fallback), WhatsApp, Telegram, voice call. Falls back to SMS if preferred channel unavailable.
Capabilities: Detects disposable/temporary numbers, VoIP numbers, carrier info, and duplicate numbers. Supports fraud signals for risk scoring.
API Reference: Send Code | Check Code
Feature Guide: https://docs.didit.me/core-technology/phone-verification/overview
Authentication
All requests require an API key via the x-api-key header.
How to obtain: Didit Business Console → API & Webhooks → Copy API key, or via programmatic registration (see below).
CODEBLOCK0
Getting Started (No Account Yet?)
If you don't have a Didit API key, create one in 2 API calls:
- 1. Register:
POST https://apx.didit.me/auth/v2/programmatic/register/ with INLINECODE3 - Check email for a 6-character OTP code
- Verify:
POST https://apx.didit.me/auth/v2/programmatic/verify-email/ with {"email": "you@gmail.com", "code": "A3K9F2"} → response includes INLINECODE6
To add credits: GET /v3/billing/balance/ to check, POST /v3/billing/top-up/ with {"amount_in_dollars": 50} for a Stripe checkout link.
See the didit-verification-management skill for full platform management (workflows, sessions, users, billing).
Step 1: Send Phone Code
Request
CODEBLOCK1
Headers
| Header | Value | Required |
|---|
| INLINECODE10 | Your API key | Yes |
| INLINECODE11 |
application/json |
Yes |
Body (JSON)
| Parameter | Type | Required | Default | Constraints | Description |
|---|
| INLINECODE13 | string | Yes | — | E.164 format | Phone number (e.g. +14155552671) |
| INLINECODE15 |
integer | No |
6 | Min: 4, Max: 8 | Code length |
|
options.locale | string | No | — | Max 5 chars | Locale for message. e.g.
en-US |
|
options.preferred_channel | string | No |
"whatsapp" | See channels |
"sms",
"whatsapp",
"telegram",
"voice" |
|
signals.ip | string | No | — | IPv4/IPv6 | User's IP for fraud detection |
|
signals.device_id | string | No | — | Max 255 chars | Unique device identifier |
|
signals.device_platform | string | No | — | Enum |
"android",
"ios",
"ipados",
"tvos",
"web" |
|
signals.device_model | string | No | — | Max 255 chars | e.g.
iPhone17,2 |
|
signals.os_version | string | No | — | Max 64 chars | e.g.
18.0.1 |
|
signals.app_version | string | No | — | Max 64 chars | e.g.
1.2.34 |
|
signals.user_agent | string | No | — | Max 512 chars | Browser user agent |
|
vendor_data | string | No | — | — | Your identifier for session tracking |
Example
CODEBLOCK2
CODEBLOCK3
Status Values & Handling
| Status | Meaning | Action |
|---|
| INLINECODE41 | Code sent | Wait for user to provide code, then call Check |
| INLINECODE42 |
Temporary issue | Wait a few seconds and retry (max 2 retries) |
|
"Undeliverable" | Number cannot receive messages | Inform user. Try a different number |
|
"Blocked" | Number blocked (spam) | Use a different number |
Error Responses
| Code | Meaning | Action |
|---|
| INLINECODE45 | Invalid request body | Check phone format (E.164) and parameters |
| INLINECODE46 |
Invalid or missing API key | Verify
x-api-key header |
|
403 | Insufficient credits/permissions | Check credits in Business Console |
|
429 | Rate limited (4/hour/number) | Wait for cooldown period |
Step 2: Check Phone Code
Must be called after a successful Send. Optionally auto-declines risky numbers.
Request
CODEBLOCK4
Body (JSON)
| Parameter | Type | Required | Default | Values | Description |
|---|
| INLINECODE50 | string | Yes | — | E.164 | Same phone used in Step 1 |
| INLINECODE51 |
string |
Yes | — | 4-8 chars | The code the user received |
|
duplicated_phone_number_action | string | No |
"NO_ACTION" |
"NO_ACTION" /
"DECLINE" | Decline if already verified by another user |
|
disposable_number_action | string | No |
"NO_ACTION" |
"NO_ACTION" /
"DECLINE" | Decline disposable/temporary numbers |
|
voip_number_action | string | No |
"NO_ACTION" |
"NO_ACTION" /
"DECLINE" | Decline VoIP numbers |
Example
CODEBLOCK5
Response (200 OK)
CODEBLOCK6
Status Values & Handling
| Status | Meaning | Action |
|---|
| INLINECODE64 | Code correct, no policy violations | Phone verified — proceed |
| INLINECODE65 |
Code incorrect | Ask user to retry (up to 3 attempts) |
|
"Declined" | Code correct but policy violation | Check
phone.warnings for reason |
|
"Expired or Not Found" | No pending code | Resend via Step 1 |
Response Field Reference
phone Object
| Field | Type | Description |
|---|
| INLINECODE70 | string | INLINECODE71 , "Failed", INLINECODE73 |
| INLINECODE74 |
string | Country prefix (e.g.
+1) |
|
full_number | string | Full E.164 number |
|
country_code | string | ISO 3166-1 alpha-2 |
|
carrier.name | string | Carrier name |
|
carrier.type | string |
"mobile",
"landline",
"voip",
"unknown" |
|
is_disposable | boolean | Disposable/temporary number |
|
is_virtual | boolean | VoIP number |
|
verification_method | string |
"sms",
"whatsapp",
"telegram",
"voice" |
|
verification_attempts | integer | Check attempts made (max 3) |
|
warnings | array |
{risk, log_type, short_description, long_description} |
Warning Tags
| Tag | Description | Auto-Decline |
|---|
| INLINECODE94 | Max code attempts exceeded | Yes |
| INLINECODE95 |
Phone is in blocklist | Yes |
|
HIGH_RISK_PHONE_NUMBER | Identified as high risk | Yes |
|
DISPOSABLE_NUMBER_DETECTED | Temporary/disposable number | Configurable |
|
VOIP_NUMBER_DETECTED | VoIP number detected | Configurable |
|
DUPLICATED_PHONE_NUMBER | Already verified by another user | Configurable |
Common Workflows
Basic Phone Verification
CODEBLOCK7
Strict Security Verification
CODEBLOCK8
Utility Scripts
CODEBLOCK9
Didit 手机验证 API
概述
通过一次性验证码进行两步手机验证:
- 1. 发送 验证码到手机号码
- 检查 用户提供的验证码
关键限制:
- - 验证码在 5分钟 后过期
- 每个验证码最多 3次验证尝试(之后必须重新发送)
- 24小时内最多 2次重新发送请求
- 速率限制:每个手机号码 每小时最多发送4次
- 手机号码必须为 E.164格式(例如 +14155552671)
- 必须先调用发送接口,再调用检查接口
投递渠道: 短信(默认备用)、WhatsApp、Telegram、语音通话。如果首选渠道不可用,则回退到短信。
功能: 检测一次性/临时号码、VoIP号码、运营商信息以及重复号码。支持用于风险评分的欺诈信号。
API 参考: 发送验证码 | 检查验证码
功能指南: https://docs.didit.me/core-technology/phone-verification/overview
身份验证
所有请求都需要通过 x-api-key 请求头提供 API 密钥。
获取方式: Didit 业务控制台 → API 与 Webhooks → 复制 API 密钥,或通过编程方式注册(见下文)。
x-api-key: yourapikey_here
快速开始(还没有账户?)
如果您还没有 Didit API 密钥,可以通过 2 次 API 调用创建一个:
- 1. 注册: POST https://apx.didit.me/auth/v2/programmatic/register/,请求体为 {email: you@gmail.com, password: MyStr0ng!Pass}
- 检查邮箱 获取 6 位 OTP 验证码
- 验证: POST https://apx.didit.me/auth/v2/programmatic/verify-email/,请求体为 {email: you@gmail.com, code: A3K9F2} → 响应中包含 api_key
添加积分: 使用 GET /v3/billing/balance/ 检查余额,使用 POST /v3/billing/top-up/ 并传入 {amountindollars: 50} 获取 Stripe 结账链接。
有关完整的平台管理(工作流、会话、用户、计费),请参阅 didit-verification-management 技能。
步骤 1:发送手机验证码
请求
POST https://verification.didit.me/v3/phone/send/
请求头
| 请求头 | 值 | 必填 |
|---|
| x-api-key | 您的 API 密钥 | 是 |
| Content-Type |
application/json |
是 |
请求体(JSON)
| 参数 | 类型 | 必填 | 默认值 | 约束 | 描述 |
|---|
| phonenumber | 字符串 | 是 | — | E.164 格式 | 手机号码(例如 +14155552671) |
| options.codesize |
整数 | 否 | 6 | 最小值:4,最大值:8 | 验证码长度 |
| options.locale | 字符串 | 否 | — | 最多 5 个字符 | 消息的语言区域。例如 en-US |
| options.preferred_channel | 字符串 | 否 | whatsapp | 见渠道说明 | sms、whatsapp、telegram、voice |
| signals.ip | 字符串 | 否 | — | IPv4/IPv6 | 用于欺诈检测的用户 IP |
| signals.device_id | 字符串 | 否 | — | 最多 255 个字符 | 唯一设备标识符 |
| 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 个字符 | 浏览器用户代理 |
| vendor_data | 字符串 | 否 | — | — | 用于会话跟踪的您的标识符 |
示例
python
import requests
response = requests.post(
https://verification.didit.me/v3/phone/send/,
headers={x-api-key: YOURAPIKEY, Content-Type: application/json},
json={
phone_number: +14155552671,
options: {preferredchannel: sms, codesize: 6},
vendor_data: session-abc-123,
},
)
typescript
const response = await fetch(https://verification.didit.me/v3/phone/send/, {
method: POST,
headers: { x-api-key: YOURAPIKEY, Content-Type: application/json },
body: JSON.stringify({
phone_number: +14155552671,
options: { preferredchannel: sms, codesize: 6 },
}),
});
状态值及处理
| 状态 | 含义 | 操作 |
|---|
| Success | 验证码已发送 | 等待用户提供验证码,然后调用检查接口 |
| Retry |
临时问题 | 等待几秒后重试(最多重试 2 次) |
| Undeliverable | 号码无法接收消息 | 通知用户。尝试其他号码 |
| Blocked | 号码已被屏蔽(垃圾信息) | 使用其他号码 |
错误响应
| 状态码 | 含义 | 操作 |
|---|
| 400 | 请求体无效 | 检查手机号码格式(E.164)和参数 |
| 401 |
API 密钥无效或缺失 | 验证 x-api-key 请求头 |
| 403 | 积分或权限不足 | 在业务控制台中检查积分 |
| 429 | 请求频率受限(每小时/每个号码 4 次) | 等待冷却时间 |
步骤 2:检查手机验证码
必须在成功发送验证码后调用。 可选择自动拒绝高风险号码。
请求
POST https://verification.didit.me/v3/phone/check/
请求体(JSON)
| 参数 | 类型 | 必填 | 默认值 | 值 | 描述 |
|---|
| phone_number | 字符串 | 是 | — | E.164 | 步骤 1 中使用的相同手机号码 |
| code |
字符串 |
是 | — | 4-8 个字符 | 用户收到的验证码 |
| duplicated
phonenumber
action | 字符串 | 否 | NOACTION | NO_ACTION / DECLINE | 如果已被其他用户验证,则拒绝 |
| disposable
numberaction | 字符串 | 否 | NO
ACTION | NOACTION / DECLINE | 拒绝一次性/临时号码 |
| voip
numberaction | 字符串 | 否 | NO
ACTION | NOACTION / DECLINE | 拒绝 VoIP 号码 |
示例
python
response = requests.post(
https://verification.didit.me/v3/phone/check/,
headers={x-api-key: YOURAPIKEY, Content-Type: application/json},
json={
phone_number: +14155552671,
code: 123456,
disposablenumberaction: DECLINE,
voipnumberaction: DECLINE,
},
)
响应(200 OK)
json
{
request_id: e39cb057-...,
status: Approved,
message: 验证码正确。,
phone: {
status: Approved,