If you run an app, a portal, or an e-commerce store in Pakistan or India, you know that SMS OTPs are increasingly unreliable. In Pakistan, local telecom routing can drop 15% to 20% of your verification messages during peak evening hours. In India, strict DLT registration rules delay critical login codes, causing users to abandon their carts or registration screens.
Moving your one-time passwords (OTPs) to WhatsApp solves the delivery problem, but it introduces a completely different set of rules, technical requirements, and costs.
Here is the exact technical and financial breakdown of how to set up a WhatsApp OTP system, the API payloads you need, and the traps that will get your account suspended if you are not careful.
---
The Real Cost of WhatsApp OTPs
Meta does not charge for WhatsApp messages on a flat per-message basis like traditional SMS gateways. Instead, they charge per 24-hour "conversation."
When you send an OTP, it falls under Meta’s
Authentication category. Once you send an authentication message to a user, a 24-hour window opens. Any subsequent authentication messages you send to that same user within that 24-hour window are free.
The pricing depends on the country code of the recipient's phone number, not where your business is registered.
| Recipient Country | Approximate Cost Per Authentication Conversation (USD) | Approximate Cost Per Authentication Conversation (Local Currency) |
|---|
| India (+91) | $0.0014 | ~INR 0.12 |
| Pakistan (+92) | $0.0045 | ~PKR 1.25 |
| United Arab Emirates (+971) | $0.0185 | ~AED 0.068 |
Note: Meta updates these rates regularly. You should always verify the current official rates on the Meta for Developers pricing sheet for your specific currency.
If you compare this to local SMS rates in Pakistan (which hover around PKR 0.80 to PKR 2.50 depending on the route and branding), WhatsApp is highly competitive, especially because you only pay for delivered sessions. If a user requests three codes within an hour because of a slow network on their end, you only pay for the first one.
---
Meta’s Strict Rules for Authentication Templates
You cannot write whatever you want in a WhatsApp OTP message. Meta uses automated filters to review templates, and they will instantly reject any template that does not comply with their strict security structure.
An authentication template:
- Must consist of alphanumeric characters only (no media, no images, no custom emojis).
- Must have a maximum of one dynamic parameter (the OTP code itself).
- Must include a button. This button can either be a Copy Code button or a One-Tap Autofill button (which only works on Android apps).
- Cannot contain promotional text, links, or custom greetings.
If you try to write:
"Hey Ahmed! Your OTP is 55432. Thanks for shopping with us, check out our new sale at our link!"—your template will be rejected within three seconds.
Instead, your template must look exactly like this:
Your verification code is {{1}}. For security, do not share this code.
---
Step-by-Step API Integration
To send these messages, you must use the Meta Graph API (either directly or via a wrapper service). Here is the manual setup process.
1. Choose and Register Your Number
You need a clean phone number that is not currently registered on a personal or business WhatsApp mobile app. If the number is active on a phone, you must delete the account from the app first. If you are unsure which type of number to use, read our guide on
which phone number should you choose for the WhatsApp API to avoid losing access to your business line.
2. Create Your Template in Meta Business Manager
Navigate to your WhatsApp Manager inside the Meta Business Suite. Go to
Message Templates and click
Create Template.
Select
Authentication as the category, name it
auth_otp_code, and select your language.
Set up the template body with your variable placeholder:
Your verification code is {{1}}. For security, do not share this code.
Add a
Copy Code button. Label it "Copy Code". Meta will handle the clipboard functionality on the user’s phone automatically.
3. Send the API Request
Once Meta approves your template (which usually takes under two minutes), you can send the OTP using a POST request. Here is a raw curl example targeting Meta’s Cloud API:
curl -X POST \
'https://graph.facebook.com/v21.0/YOUR_PHONE_NUMBER_ID/messages' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "923001234567",
"type": "template",
"template": {
"name": "auth_otp_code",
"language": {
"code": "en_US"
},
"components": [
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "482019"
}
]
},
{
"type": "button",
"sub_type": "url",
"index": 0,
"parameters": [
{
"type": "text",
"text": "482019"
}
]
}
]
}
}'
Why is the OTP code sent twice in the payload?
The first parameter in the
body replaces the
{{1}} in your text message. The second parameter in the
button component tells the "Copy Code" button exactly what value to copy to the user's clipboard. If you mismatch these two values, your user will copy a different code than the one displayed on their screen.
---
Building the Backend Logic for Verification
Simply sending the API request is not enough. You must write the logic that generates, stores, and validates the OTP.
We have written a comprehensive guide on
how to build a WhatsApp OTP system for logins and password resets, but the core backend lifecycle should follow this pattern:
- Generation: Generate a cryptographically secure 6-digit numeric string. Avoid alphanumeric codes; they are harder for users to type on mobile keyboards if the auto-copy fails.
- Storage: Save the code in a fast in-memory database like Redis with a strict TTL (Time-To-Live) of 5 minutes (300 seconds). Store it against the user's phone number.
- Hashing: Never store the OTP in plain text if you are saving it to a persistent database. Hash it just like you would hash a password.
- Rate Limiting: Implement a cooldown. Do not let a single IP address or phone number request more than one OTP every 60 seconds.
---
Tracking Failures with Webhooks
If you send an OTP and the user claims they never received it, you cannot diagnose the issue without webhooks.
Meta will send status updates to your server when a message is sent, delivered, or read. If a delivery fails, Meta will send an error payload. For a detailed breakdown of these webhooks and what the error codes mean, see our guide on
tracking WhatsApp API message statuses, webhooks, error codes, and costs.
The most common webhook error you will encounter during OTP delivery is:
- Error 131026: "Receiver is incapable of receiving messages." This means the phone number is not registered on WhatsApp. If you see this, you must instantly trigger your fallback SMS gateway.
---
When WhatsApp OTP is the Wrong Choice
We set up these systems daily, and we will be the first to tell you that relying solely on WhatsApp for OTPs is a bad operational decision.
Here is when you should not use it, or at least, why you need an alternative.
1. You have no SMS fallback
Not everyone has WhatsApp installed, and not everyone has active mobile data at all times. In rural parts of Pakistan and India, users often turn off mobile data to save battery or credit, but their cellular network remains active for basic calls and SMS. If your app only offers WhatsApp verification, you will lock these users out entirely.
Your system should attempt to send a WhatsApp OTP first. If your webhook does not receive a
delivered status within 20 seconds, or if the API returns an error immediately, your backend must automatically failover to a standard SMS gateway.
2. Protection against API Spam Attacks
If a malicious actor scripts a bot to target your signup endpoint, they can trigger thousands of OTP requests.
If you use a prepaid SMS gateway, the worst that happens is your prepaid balance hits zero and the messages stop.
If you use the Meta Cloud API directly with a credit card attached, a bot attack can run up a bill of thousands of dollars overnight. Meta does not automatically pause your account for high traffic unless you set up manual spending limits in your Meta Business Manager.
Before you hook up your WhatsApp OTP API to your signup form, you must implement:
- A CAPTCHA (like Cloudflare Turnstile or reCAPTCHA v3) on the request button.
- Strict IP-based rate limits.
- A maximum daily OTP limit per phone number (e.g., no more than 5 OTP requests per number in 24 hours).
---
How WA Link Fits Into This
Setting up Meta Developer accounts, configuring webhooks, managing credit cards, and building failover queues can take weeks of development time.
At WA Link, we provide a simplified WhatsApp API gateway. We handle the complex Meta infrastructure, template approvals, and webhook parsing so you can focus on writing your core application logic.
However, we do not bypass Meta's rules. If you use WA Link, you still need to:
- Submit standard, clean authentication templates that comply with Meta's guidelines.
- Pay the destination network fees.
- Build your own SMS fallback system for users who do not have WhatsApp.
Our platform simply removes the developer friction of dealing with Meta’s raw Graph API directly, giving you a clean, reliable endpoint to send your transactional messages.
---
Frequently Asked Questions
Can I send OTPs using a standard WhatsApp Business App on my phone?
No. The mobile app does not have an open API for automated programmatic sending. If you try to use unofficial web-scraping tools or Android automation apps to broadcast OTPs from your phone, WhatsApp's automated spam detection systems will flag your account and permanently ban your number within hours.
Why does my template keep getting rejected by Meta?
Double-check your formatting. The most common reason for rejection is trying to include variables in the header or footer, or adding promotional words (like "Welcome to our store!") in the body. Keep it strictly limited to the verification code and the security warning.
How long does it take for a WhatsApp OTP to land on a phone?
Under normal network conditions, a WhatsApp OTP lands in less than 3 seconds. This is significantly faster than standard carrier SMS, which can take anywhere from 10 seconds to several minutes during peak times.