Base URL
/v1/*.
Supported countries
Numbers are routed automatically to the right carrier in each country:How codes are protected
- Secure generation: codes are generated from cryptographically secure random bytes.
- No plaintext storage: codes are hashed server-side with HMAC-SHA256 and a per-session salt. Plaintext codes are never stored in the database.
- Constant-time checks: submitted codes are compared in constant time (
crypto.timingSafeEqual) to prevent timing attacks. - Automatic refunds: wallet units are reserved before the OTP is sent. If the carrier fails to deliver it (
SMS_DELIVERY_FAILED), the reserved units are refunded automatically.
Authentication
All/verify/* endpoints accept any of these authentication methods:
See Authentication for how to get your credentials.
Verify a phone number
1
Start a verification
POST /verify/start sends an OTP to the phone number.Response (200 OK)
verification_id. You need it to check the code.2
Check the code
POST /verify/check checks the code your user entered.Resends and rate limits
Resend a code
To resend an OTP, callPOST /verify/start again with the same phone_number after the resend_after time has passed. The default cooldown is 60 seconds.
If you call it before resend_after, the API returns 429 COOLDOWN_ACTIVE, and error.retry_after_seconds tells you how many seconds remain.
Anti-abuse limits
Sandbox testing
Test the full flow for free, without spending SMS balance. SendPOST /verify/start to one of these sandbox numbers:
You can also use a test mode Verify Service (
is_test_mode: true) or a test API key.
In sandbox and test mode:
cost_unitsis0.- No real SMS is sent.
- Submitting
"code": "123456"toPOST /verify/checkalways returns"status": "approved".
Verify Services
A Verify Service controls the message template, Sender ID, code length, expiry, and limits for your OTPs. Use separate services for different flows, such as login and password reset.Create a service
POST /verify/services (or POST /verify/apps) creates a Verify Service.
Manage services, sessions, and analytics
PUT /verify/services/{id} accepts template, senderId, codeLength, expirySeconds, resendCooldownSeconds, maxAttempts, isActive, and isTestMode.
GET /verify/sessions supports these query filters:
GET /verify/analytics returns totalRequests, successfulVerifications, successRate, incorrectAttempts, expiredSessions, lockedSessions, and deliveryFailures.

