didit-phone-verificationVerify phone numbers via OTP with Didit using SMS, WhatsApp, Telegram, or voice; supports fraud detection, disposable/VoIP checks, and auto-decline policies.
Install via ClawdBot CLI:
clawdbot install rosasalberto/didit-phone-verificationTwo-step phone verification via one-time code:
Key constraints:
+14155552671)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
All requests require an API key via the x-api-key header.
How to obtain: Didit Business Console β API & Webhooks β Copy API key.
x-api-key: your_api_key_here
POST https://verification.didit.me/v3/phone/send/
| Header | Value | Required |
|---|---|---|
| x-api-key | Your API key | Yes |
| Content-Type | application/json | Yes |
| Parameter | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
| phone_number | string | Yes | β | E.164 format | Phone number (e.g. +14155552671) |
| options.code_size | 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 |
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},
"vendor_data": "session-abc-123",
},
)
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: "sms", code_size: 6 },
}),
});
| Status | Meaning | Action |
|---|---|---|
| "Success" | Code sent | Wait for user to provide code, then call Check |
| "Retry" | 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 |
| Code | Meaning | Action |
|---|---|---|
| 400 | Invalid request body | Check phone format (E.164) and parameters |
| 401 | 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 |
Must be called after a successful Send. Optionally auto-declines risky numbers.
POST https://verification.didit.me/v3/phone/check/
| Parameter | Type | Required | Default | Values | Description |
|---|---|---|---|---|---|
| phone_number | string | Yes | β | E.164 | Same phone used in Step 1 |
| code | 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 |
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",
},
)
{
"request_id": "e39cb057-...",
"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": "ATT", "type": "mobile"},
"is_disposable": false,
"is_virtual": false,
"verification_method": "sms",
"verification_attempts": 1,
"verified_at": "2025-08-24T09:12:39.662232Z",
"warnings": [],
"lifecycle": [...]
}
}
| Status | Meaning | Action |
|---|---|---|
| "Approved" | Code correct, no policy violations | Phone verified β proceed |
| "Failed" | 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 |
phone Object| Field | Type | Description |
|---|---|---|
| status | string | "Approved", "Failed", "Declined" |
| phone_number_prefix | 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} |
| Tag | Description | Auto-Decline |
|---|---|---|
| VERIFICATION_CODE_ATTEMPTS_EXCEEDED | Max code attempts exceeded | Yes |
| PHONE_NUMBER_IN_BLOCKLIST | 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 |
1. POST /v3/phone/send/ β {"phone_number": "+14155552671"}
2. Wait for user to provide the code
3. POST /v3/phone/check/ β {"phone_number": "+14155552671", "code": "123456"}
4. If "Approved" β phone is verified
If "Failed" β retry (up to 3 attempts)
If "Expired or Not Found"β resend (step 1)
1. POST /v3/phone/send/ β include signals.ip, signals.device_platform, channel: "sms"
2. POST /v3/phone/check/ β set disposable_number_action + voip_number_action to "DECLINE"
3. If "Declined" β check phone.warnings, block or warn user
export DIDIT_API_KEY="your_api_key"
python scripts/verify_phone.py send +14155552671 --channel sms
python scripts/verify_phone.py check +14155552671 123456 --decline-voip
AI Usage Analysis
Analysis is being generated⦠refresh in a few seconds.
Drift detection + baseline integrity guard for agent workspace files with automatic alerting support
Guardian Angel gives AI agents a moral conscience rooted in Thomistic virtue ethics. Rather than relying solely on rule lists, it cultivates stable virtuous...
Core identity and personality for Molt, the transformative AI assistant
Build secure authentication with sessions, JWT, OAuth, passwordless, MFA, and SSO for web and mobile apps.
Gentle reminders to stay human while using AI. Reflection, not restriction.
Post to X (Twitter) using the official OAuth 1.0a API. Free tier compatible.