Skip to main content
Didit Raises $2M and Joins Y Combinator (W26)
Didit
Phone Verification

Verify any phone.
On any channel they answer.

Send a one-time code over SMS, WhatsApp, Telegram, RCS, or voice — whichever channel the user actually answers. Auto-fallback between channels, with carrier-risk scoring on every call. From $0.03 plus carrier, 500 free/month.

Backed by
Y Combinator
GBTC Finance
Bondex
Crnogorski Telekom
UCSF Neuroscape
Shiply
Adelantos

Trusted by 2,000+ organizations worldwide.

Five channels

SMS. WhatsApp. Telegram.
RCS. Voice.

One module, five delivery rails. We retry across channels until the code lands, score SIM-swap and carrier risk on every call, and bill from $0.03 plus carrier — same workflow either way.

How it works

From sign-up to verified user in four steps.

  1. Step 01

    Create the workflow

    Pick the checks you want — ID, liveness, face match, sanctions, address, age, phone, email, custom questions. Drag them into a flow in the dashboard, or post the same flow to our API. Branch on conditions, run A/B tests, no code required.

  2. Step 02

    Integrate

    Embed natively with our Web, iOS, Android, React Native, or Flutter SDK. Redirect to a hosted page. Or just send your user a link — by email, SMS, WhatsApp, anywhere. Pick what fits your stack.

  3. Step 03

    User goes through the flow

    Didit hosts the camera, the lighting cues, the mobile hand-off, and accessibility. While the user is in the flow, we score 200+ fraud signals in real time and verify every field against authoritative data sources. Result in under two seconds.

  4. Step 04

    You receive the results

    Real-time signed webhooks keep your database in sync the moment a user is approved, declined, or sent to review. Poll the API on demand. Or open the console to inspect every session, every signal, and manage cases your way.

Built for developers · Built against fraud · Open by design

Six capabilities. One feature flag. PHONE.

Every capability is a toggle on the same module. No upsell tiers, no separate plans, no add-on calls. Switch them on per workflow in the console or pass them inline on the API call.
01 · Channels

Five delivery channels. One feature flag.

SMS, WhatsApp, Telegram, RCS, and voice — all on the same module and workflow. Pin a channel when policy demands (regulator-mandated SMS, WhatsApp-first markets like Brazil and India), or let us pick the cheapest deliverable hop.
One feature flag · Five channelsfeature: PHONE
  • SMSDefault
  • WhatsAppBR / IN / MX
  • TelegramEU
  • RCSAndroid
  • VoiceFallback
02 · Routing

Automatic channel fallback when one fails.

Carrier SMS blocks, premium-rate countries, and silent failures are routed past automatically. We retry on the next deliverable channel without your code touching anything, and tell you which channel actually delivered.
Auto channel routingPOST /v3/phone/send/
1SMSCarrier blocked
2WhatsAppDelivered
verification_methodwhatsapp
03 · Coverage

Global telco reach. Carrier-aware delivery.

Multi-carrier integrations per country, with routing tuned to local habits — WhatsApp leads in Brazil, India, and Mexico, Telegram and RCS lead across the EU, SMS leads in the US. Country, carrier, and number type are detected automatically.
04 · Fraud signals

More than a one-time code. Carrier risk on every call.

Every verification returns the carrier name and type (mobile, landline, voice over IP), flags for disposable and virtual numbers, and explicit warnings for high-risk, duplicated, or blocklisted numbers. Decide, review, or approve per risk category.
05 · Conversion

SMS-only leaks users. Multi-channel keeps them.

When SMS fails — carrier filter, roaming, dead zone, deliverability decline — single-channel providers leave users staring at a never-arriving code. We recover them on the next hop, and report which channel delivered so you can tune routing with real data.
Completion · 30-day rollingHigher is better
SMS only58%
+ WhatsApp79%
+ Voice fallback93%
Illustrative — directional, not a study.
06 · Pricing

Pay per message. From $0.03 plus carrier.

$0.03 per verification, plus a country and channel carrier fee passed through with no markup. You only pay when a message is sent — abandons before delivery cost nothing. 500 verifications free/month, on every account, forever.
Per-message ratesFrom $0.03
  • United StatesSMS$0.03
  • BrazilWhatsApp$0.04
  • IndiaWhatsApp$0.05
Pay only when a message is sent. 500 free per month.
Integrate

Two endpoints. Same JSON. Same price.

Pick the hosted flow when you want us to handle the number entry, code UX, and resend. Pick the standalone API when you own the UX. Both return the same report.
POST /v3/session/Hosted UI
$ curl -X POST https://verification.didit.me/v3/session/ \
  -H "x-api-key: $DIDIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_id": "wf_phone_otp",
    "vendor_data": "user-42"
  }'
201Created{ "session_url": "verify.didit.me/..." }
We host the phone entry, OTP UX, resend, and channel routing.docs →
POST /v3/phone/send/Server to server
$ curl -X POST https://verification.didit.me/v3/phone/send/ \
  -H "x-api-key: $DIDIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number": "+14155552671"
  }'
200OK{ "status": "sent", "channel": "sms" }
Then POST /v3/phone/check/ with the OTP to retrieve the full report.docs →
Agent-ready integration

Ship Phone Verification in one prompt.

Paste the block below into Claude Code, Cursor, Codex, Devin, Aider, or Replit Agent. Fill in your stack. The agent provisions Didit, creates the Phone Verification workflow, wires the webhook, and ships.
didit-integration-prompt.md
# Didit Phone Verification — integrate in 5 minutes

You are integrating Didit's Phone Verification module into <my_stack>.
Follow these steps exactly. Every URL, header, and enum value below is
canonical — do not paraphrase or "improve" them.

## 1. Provision an account
- Sign up: https://business.didit.me (no credit card required).
- Or provision programmatically: POST https://apx.didit.me/auth/v2/programmatic/register/
  (returns an API key bound to the workspace + application).

## 2. Two integration paths — pick one

### Path A — Workflow Builder (hosted UI)
Best when you want Didit to handle phone collection, country prefix UX,
channel routing, OTP entry, resend buttons, mobile/desktop handoff, and
accessibility for you.

1. Create a workflow that contains the PHONE feature:
   POST https://verification.didit.me/v3/workflows/
   Authorization header:  x-api-key: <your-api-key>
   Body: workflow_label, features array with the single entry
         { feature: "PHONE" }   (UPPERCASE — strict enum)
   Optional config: preferred_channel ("SMS" | "WHATSAPP" | "TELEGRAM" |
   "RCS" | "VIBER" | "CALL"), code_validity_seconds, max_code_attempts
   (default 2), max_resend_requests_per_24h (default 2).

2. Create a verification session for an end user:
   POST https://verification.didit.me/v3/session/
   Body: workflow_id (from step 1), vendor_data (your own user id),
         optional contact_details.phone in E.164 format
         (e.g. "+14155552671") to pre-fill and lock the number.
   Response: session_url — redirect the user to it.

3. Listen for webhook callbacks (see "Webhooks" below).

### Path B — Standalone server-to-server API
Best when you already own the phone-entry UX (mobile SDK, native
onboarding app, reseller pipeline) and want Didit to handle OTP delivery
+ risk scoring only. Two endpoints, called in sequence:

Step 1 — Send the code:
POST https://verification.didit.me/v3/phone/send/
Content-Type: application/json
Body fields:
  - phone_number  (required, string, E.164 format e.g. "+14155552671")
  - channel       (optional — "SMS" | "WHATSAPP" | "TELEGRAM" | "RCS" |
                   "VIBER" | "CALL". Omit to let Didit pick the best
                   available channel for the destination country and
                   carrier — automatic fallback routing.)
  - vendor_data   (optional, your user id for cross-session linkage)

Step 2 — Check the code:
POST https://verification.didit.me/v3/phone/check/
Content-Type: application/json
Body fields:
  - phone_number  (required, same E.164 number)
  - code          (required, the OTP the user typed)
  - vendor_data   (optional, same user id used in Step 1)

Response: JSON report — status, verification_method (the channel that
actually delivered), carrier object, is_disposable, is_virtual, warnings
array.

## 3. Channel routing — how the automatic fallback works
When channel is omitted on /v3/phone/send/, Didit picks the cheapest
+ most-deliverable channel for the destination:
  - SMS where deliverable and lowest cost (most countries)
  - WhatsApp in BR / IN / MX and other WhatsApp-dense markets
  - Telegram / RCS / Viber where carrier-side SMS is blocked or premium
  - CALL (voice OTP) as last-resort fallback when text channels fail
Each retry attempt may switch channels — the final delivery channel is
returned as verification_method in the report.

## 4. Webhooks (Path A only — Path B returns synchronously)
- Register a webhook destination once via
  POST https://verification.didit.me/v3/webhook/destinations/
  Body: url, subscribed_events: ["session.verified", "session.review_started",
                                  "session.declined"]
- Response includes secret_shared_key — store it.
- Every webhook delivery carries an X-Signature-V2 header you MUST verify
  before trusting the payload.  HMAC-SHA256 verification MUST run against the raw body bytes (the raw payload as Didit sent it) BEFORE any JSON parsing — re-serialising the parsed body changes whitespace and key order, which invalidates the signature.Algorithm:
    1. sortKeys(payload) recursively
    2. shortenFloats (truncate trailing zeros after the decimal point)
    3. JSON.stringify the result
    4. HMAC-SHA256 with the secret_shared_key
    5. Hex-encode, compare to the X-Signature-V2 header.

## 5. Reading the report (both paths return the same phone object)
- status: "Approved" | "Declined" | "In Review" | "Not Finished"
- phone_number_prefix: country prefix in international format ("+34")
- phone_number: subscriber number without the prefix
- full_number: full E.164 string ("+34600600600")
- country_code: ISO 3166-1 alpha-2 ("ES")
- country_name: full country name
- carrier: { name, type: "mobile" | "landline" | "voip" | "unknown" }
- is_disposable: boolean — temporary or throwaway number
- is_virtual: boolean — VoIP or virtual provider
- verification_method: the channel that actually delivered the code
  ("sms" | "whatsapp" | "viber" | "telegram" | "call")
- verification_attempts: number of code-entry tries
- verified_at: ISO 8601 timestamp
- warnings: Array<{ risk, log_type, short_description, long_description }>

Auto-decline risks (always enforced by Didit, not configurable):
- VERIFICATION_CODE_ATTEMPTS_EXCEEDED
- HIGH_RISK_PHONE_NUMBER
- PHONE_NUMBER_IN_BLOCKLIST

Configurable risks (action per workflow — Decline, Review, or Approve):
- DISPOSABLE_NUMBER_DETECTED
- VOIP_NUMBER_DETECTED
- DUPLICATED_PHONE_NUMBER

## 6. Attempt limits (defaults — overridable per workflow)
- Max code-entry attempts: 2 per session
- Max resend requests: 2 per phone number per 24 hours
- Code validity: 5 minutes from send
Hitting either limit fires VERIFICATION_CODE_ATTEMPTS_EXCEEDED and
auto-declines the session.

## 7. Hard rules — do not change
- Base URL for /v3/* endpoints is verification.didit.me (NOT apx.didit.me).
- Feature enum is UPPERCASE: PHONE, ID_VERIFICATION, LIVENESS, FACE_MATCH,
  AML, IP_ANALYSIS.
- Channel enum is UPPERCASE on input ("SMS", "WHATSAPP", "TELEGRAM",
  "RCS", "VIBER", "CALL") and lowercase on output ("sms", "whatsapp",
  "telegram", "rcs", "viber", "call").
- All phone numbers go in and come out as E.164 strings — including
  the leading "+" and country prefix.
- Auth header is x-api-key (lowercase, hyphenated).
- Webhook signature header is X-Signature-V2 (NOT X-Signature).
- Always verify webhook signatures before trusting payload data.
- Status casing matches exactly: "Approved", "Declined", "In Review",
  "Not Finished" (title-cased, space-separated).

## 8. Pricing reference (public)
- Didit fee: $0.03 per verification (the cheapest channel; some
  channels and countries cost more — see didit.me/pricing for the
  per-country, per-channel table).
- Carrier fee: variable by country and channel, billed as a
  pass-through with no Didit markup.
- 500 free checks every month, forever, on every account.
- You only pay when a message is SENT. If the user abandons before
  delivery, you are not charged.

## 9. Verify your integration
- Sandbox starts on signup at https://business.didit.me — no separate flag.
- Sandbox numbers: deterministic E.164 numbers return Approved by default;
  trigger Declined with the canonical "high-risk" sandbox number.
- Switch to live: flip the application's environment toggle in console.

When in doubt: https://docs.didit.me/core-technology/phone-verification/overview
Need more context? See the full module docs.docs.didit.me →
Compliant by design

Open a new country in one click. We do the hard work.

We open the local subsidiaries, secure the licenses, run the penetration tests, earn the certifications, and align with every new regulation. To ship verifications in a new country, flip a toggle. 220+ countries live, audited and pen-tested every quarter — the only identity provider an EU member-state government has formally called safer than in-person verification.
Read the security & compliance dossier
EU financial sandbox
Tesoro · SEPBLAC · BdE
ISO/IEC 27001
Information security · 2026
SOC 2 · Type I
AICPA · 2026
iBeta Level 1 PAD
NIST / NIAP · 2026
GDPR
EU 2016/679
DORA
EU 2022/2554
MiCA
EU 2023/1114
AMLD6 · eIDAS 2.0
EU-aligned by design

Proof numbers

Proof numbers
  • 0
    Delivery channels — SMS, WhatsApp, Telegram, RCS, voice.
  • Auto
    Channel routing — we pick the cheapest deliverable hop.
  • 0
    Free Phone Verifications every month, every account.
  • From $0.03
    Per verification, plus pass-through carrier — no markup.
Three tiers, one price list

Start free. Pay per usage. Scale to Enterprise.

500 free verifications every month, forever. Pay-as-you-go for production. Custom contracts, data residency, and SLAs (Service Level Agreements) on Enterprise.
Free

Free

$0 / month. No credit card required.

  • Free KYC bundle (ID Verification + Passive Liveness + Face Match + Device & IP Analysis) — 500 / month, every month
  • Blocklisted Users
  • Duplicate Detection
  • 200+ fraud signals on every session
  • Reusable KYC across the Didit network
  • Case Management Platform
  • Workflow Builder
  • Public docs, sandbox, SDKs, MCP (Model Context Protocol) server
  • Community support
Most popular
Pay per usage

Usage Based

Pay only for what you use. 25+ modules. Public per-module pricing, no monthly minimum fee.

  • Full KYC at $0.33 (ID + Biometric + IP / Device)
  • 10,000+ AML datasets — sanctions, PEPs, adverse media
  • 1,000+ government data sources for Database Validation
  • Transaction Monitoring at $0.02 per transaction
  • Live KYB at $2.00 per business
  • Wallet Screening at $0.15 per check
  • Whitelabel verification flow — your brand, our infrastructure
Enterprise

Enterprise

Custom MSA & SLA. For large volumes and regulated programs.

  • Annual contracts
  • Custom MSA, DPA, and SLA
  • Dedicated Slack and WhatsApp channel
  • Manual reviewers on demand
  • Reseller and white-label terms
  • Exclusive features and partner integrations
  • Named CSM, security review, compliance support

Start free → pay only when a check runs → unlock Enterprise for a custom contract, SLA, or data residency.

FAQ

Common questions

Infrastructure for identity and fraud.

One API for KYC, KYB, Transaction Monitoring, and Wallet Screening. Integrate in 5 minutes.

Ask an AI to summarise this page