Secure User Verification with OTP
Send the one-time codes your app generates to Indian mobile numbers by SMS, for sign-up verification, two-factor authentication, password resets and transaction confirmations. Prefer WhatsApp? Send codes with WhatsApp authentication templates instead.
✦ No credit card required · Free credits to start · Setup in 5 minutes
OTP Flow in 4 Steps
User enters phone number
Your app collects the user's phone number during sign-up, login, or transaction.
Your app calls our API
Generate a random code, store a hash of it with an expiry, then POST /otp/send with the phone number and the code in variables.otp. We deliver it by SMS.
User enters the code
The user receives the OTP on their phone and enters it in your app's verification screen.
Your app verifies the code
Compare the entered code with the stored hash, check the expiry and attempt count, then mark the code as used. Verification happens in your own backend.
OTP by SMS, or by WhatsApp: Your Choice
The SMS OTP API delivers your codes by SMS. To send codes on WhatsApp instead, use a WhatsApp authentication template with a copy-code button, sent through the WhatsApp Messages API (POST /api/v1/messages), which is a separate product. The two never fall back to each other automatically: if you offer both, your app decides which channel to use and when to resend.
- Track SMS delivery with GET /messages/{id}
- DLT-registered or DLT-free SMS routes in India
- WhatsApp OTP via authentication templates with a copy-code button
WhatsApp OTP Verification vs. Traditional SMS OTP vs. Email Authentication
Compare how each channel delivers and protects one-time codes.
| Comparison Vector | WhatsApp OTP | Traditional SMS OTP | Email Verification |
|---|---|---|---|
| How You Send It | Authentication template via POST /api/v1/messages | SMS OTP API: POST /otp/send (India) | ✗ (Not offered by StartMessaging) |
| Code Generation & Check | Your app | Your app | Your app |
| Code Entry | ✓ (Copy-code button in the chat) | ✓ (Android & iOS native) | ✗ (Manual inbox copy) |
| Interception Risk | Lower (delivered to the WhatsApp app over an encrypted connection) | Higher (SIM-swap and network attacks) | Depends on the mail provider |
Send an OTP by SMS and track delivery
# 1. Send the OTP (you generate and store the code)
curl -X POST https://api.startmessaging.com/otp/send \
-H "Content-Type: application/json" \
-H "X-API-Key: sm_live_your_api_key_here" \
-d '{
"phoneNumber": "+919876543210",
"templateId": "YOUR_TEMPLATE_ID",
"variables": {
"otp": "482913",
"appName": "YourApp"
}
}'
# 2. Check delivery with the messageId from the response
curl https://api.startmessaging.com/messages/MESSAGE_ID \
-H "X-API-Key: sm_live_your_api_key_here" const otp = String(Math.floor(100000 + Math.random() * 900000));
// store a hash of otp against the login attempt, with an expiry
const res = await fetch('https://api.startmessaging.com/otp/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': process.env.SM_API_KEY,
},
body: JSON.stringify({
phoneNumber: '+919876543210',
templateId: 'YOUR_TEMPLATE_ID',
variables: { otp, appName: 'YourApp' },
}),
});
const { data } = await res.json();
console.log(data.messageId, data.status); // queued import os, secrets, requests
otp = f"{secrets.randbelow(900000) + 100000}"
# store a hash of otp against the login attempt, with an expiry
res = requests.post(
'https://api.startmessaging.com/otp/send',
headers={'X-API-Key': os.environ['SM_API_KEY']},
json={
'phoneNumber': '+919876543210',
'templateId': 'YOUR_TEMPLATE_ID',
'variables': {'otp': otp, 'appName': 'YourApp'},
},
)
print(res.json()['data']['messageId']) OTP Authentication — FAQ
What's the best practice for OTP expiry time?
Because your app generates and stores the code, you choose the expiry. We recommend 5 minutes for standard sign-up and login codes and 2-3 minutes for high-security actions (payments, password resets). Shorter expiry is more secure but can frustrate users on slow connections.
Are there local rules for sending OTP verification codes?
Yes. In India, SMS OTPs must use a DLT-registered template and sender ID, or our DLT-free route. Everywhere, local data-protection laws govern how you store phone numbers and verification logs. WhatsApp OTPs must use a Meta-approved authentication template.
Is there automatic fallback between WhatsApp and SMS OTP?
No. WhatsApp OTP (authentication templates sent through the WhatsApp Messages API) and SMS OTP (POST /otp/send) are separate products with separate accounts and API keys, and neither falls back to the other. If you want a backup channel, build it in your app: offer a 'Send by SMS instead' option, or listen for the WhatsApp message.failed webhook and then call the SMS API yourself.
Is there a limit on how many OTPs a user can request?
Yes. To prevent spam and SMS-pumping fraud, the SMS OTP API allows at most 3 OTPs per phone number every 5 minutes and answers 429 Too Many Requests beyond that. Add your own resend delay (30-60 seconds) in your app as well.
Add OTP to Your App Today
Create an API key in your dashboard and send your first SMS OTP.