Send + verify in two API calls

WhatsApp OTP API — no subscription

Send a one-time code to a WhatsApp number and check the code your user types, with two REST calls. PayPerWA generates, sends, expires and checks each code. You pay per OTP sent; verifying is free.

Per OTP sent

Meta ₹0.115+PayPerWA ₹0.20Verify: free

₹0.115 is Meta's list rate for an Indian number, billed by Meta to your WhatsApp Business Account. PayPerWA's ₹0.20 comes from your prepaid wallet. Price per OTP by country

  • No DLT registration
  • No subscription or setup fee
  • No minimum monthly spend

Sample message

Two calls: send a code, then check it

PayPerWA generates the code, sends it with your approved Authentication template, expires it and checks it. Your server never stores a code.

1POST

/api/v1/otp/send

Sends a fresh code to the number. Body fields (any other field is refused with 400):

to
Required. 10 to 15 digits starting with the country code, never 0. A leading + or 00, spaces and dashes are fine: +91 98765-43210 and 0091 98765 43210 are the same number.
code_length
4 to 8 digits. Default 6.
expiry_minutes
1 to 30. Default 10. If your template shows an expiry footer, send the same number.
template_name
Optional. Must be an approved Authentication template. Default: your most recently updated one.
language
Optional. Defaults to the template's language.
channelId
Optional, if you have more than one WhatsApp number. The X-Channel-Id header works too.

Returns verification_id, expires_at, message_id and a cost object. Its wallet_deduction is PayPerWA's fee; Meta bills its own fee to your WhatsApp Business Account, so it is not taken from your wallet. The code itself is never in a response.

2POSTFree

/api/v1/otp/verify

Send the code your user typed, as a string of digits, with either to or verification_id (exactly one). A valid, authorised request gets HTTP 200 whatever the outcome (auth, rate-limit and 503 errors aside); read status:

approved
valid: true. The code is now used up.
incorrect
Wrong code. attempts_remaining says how many tries are left.
max_attempts
The 5th wrong try. The code is cancelled; send a new one.
expired
Past expires_at (reported once, within 2 minutes of expiry). Send a new code.
not_found
No pending code: never sent, already used or cancelled, expired more than 2 minutes ago, or (by verification_id) replaced by a newer send.

Nothing charged

When a send is refused

These answers come back before anything is charged or sent, with success: false, an error message and a code:

429OTP_COOLDOWN
A code went to this number less than 30 seconds ago.
429OTP_TOO_MANY_SENDS
5 codes went to this number in the last hour.
429OTP_TOO_MANY_FAILED_CHECKS
15 wrong codes were entered for this number in the last 24 hours.
400OTP_TEMPLATE_REQUIRED
No approved Authentication template (on that channel, if you named one).
400OTP_TEMPLATE_NOT_AUTHENTICATION
template_name is not an Authentication template.
400OWN_NUMBER
to is the WhatsApp number you send from.
402INSUFFICIENT_WALLET_BALANCE
Your wallet balance is below what the send costs. required and available come in your wallet's currency, named in currency.
503OTP_UNAVAILABLE
Verification is briefly unavailable (send or verify). Try again shortly.

The 429s also give retry_after_seconds and a Retry-After header. A body that fails validation gets 400 Validation failed with details per field. If WhatsApp rejects the send itself, you get Meta's error, PayPerWA's fee goes back to your wallet, the attempt does not count toward the resend limits and an earlier code for the number stays valid. A contact who opted out of your messages does not block an OTP: that block covers marketing and utility templates, and the person asked for this code.

# 1. Send a code (6 digits, valid for 10 minutes unless you change it)
curl -X POST https://payperwa.com/api/v1/otp/send \
  -H "Authorization: Bearer ppw_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"to": "919876543210", "code_length": 6, "expiry_minutes": 10}'

# 2. Check the code your user typed
curl -X POST https://payperwa.com/api/v1/otp/verify \
  -H "Authorization: Bearer ppw_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"to": "919876543210", "code": "482913"}'

Responses

POST /otp/send · 200 (INR wallet, Meta-direct billing)

{
  "success": true,
  "data": {
    "verification_id": "0b6f8f1e-6c1d-4f43-9a51-2f3c8f1d7a20",
    "to": "919876543210",
    "status": "pending",
    "expires_at": "2026-11-09T10:50:00.000Z",
    "code_length": 6,
    "template_name": "login_code",
    "message_id": "wamid.HBgLMTIzNDU2Nzg5MA==",
    "cost": {
      "meta_fee": 0,
      "platform_fee": 0.2,
      "wallet_deduction": 0.2,
      "total_outlay": 0.2,
      "billing_mode": "meta_direct",
      "breakdown": "Meta bills customer directly + PayPerWA ₹0.20 fee",
      "country": "IN",
      "pricing_source": "meta_direct"
    }
  }
}

POST /otp/verify · 200

{
  "success": true,
  "data": {
    "valid": true,
    "status": "approved",
    "verification_id": "0b6f8f1e-6c1d-4f43-9a51-2f3c8f1d7a20"
  }
}

{
  "success": true,
  "data": {
    "valid": false,
    "status": "incorrect",
    "verification_id": "0b6f8f1e-6c1d-4f43-9a51-2f3c8f1d7a20",
    "attempts_remaining": 3
  }
}
Base URL https://payperwa.com/api/v1 · header Authorization: Bearer ppw_live_sk_… · key permission messages:send · 100 requests a minute per key. Call the API from your server, never from browser JavaScript. Full reference in the API docs.

Why send OTPs on WhatsApp

Fewer moving parts than SMS, and fewer digits to retype.

No DLT registration

SMS OTPs in India need DLT entity, header and template registration. On WhatsApp you need one approved Authentication template, which you create in the dashboard and Meta reviews.

A copy-code button

Every code arrives with a Copy code button, so your user copies it in one tap instead of retyping it.

Code suggestions on iPhone

On iOS 26 and later, iPhones can suggest numeric codes of 3 to 8 digits straight from the WhatsApp notification.

No SMS-pumping fees

SMS pumping bills you for floods of texts that earn attackers a share of carrier revenue. A WhatsApp OTP sends no SMS, so that fraud has nothing to pump.

Two things to know before you switch

  • Your user needs WhatsApp on that number. PayPerWA has no SMS fallback, so keep another way to sign in (email, or your current SMS provider) for people without it.
  • Meta requires opt-in. People must agree to receive messages from you on WhatsApp, so ask for that clearly in your sign-in flow.
Built in

Protections you would otherwise build yourself

Expiry, attempt limits and resend limits are part of the API, not homework.

Cryptographic codes

Every code comes from a cryptographically secure random number generator.

Stored only as a keyed hash

PayPerWA keeps a keyed hash, never the code itself, and never returns the code in an API response.

Codes expire

Each code lasts 1 to 30 minutes, 10 by default. After that it cannot be used.

Single use

A code is deleted the moment it is approved. A new code replaces the previous one as soon as Meta accepts it; if the send is refused with an error, the previous code still works.

Limits on wrong guesses

5 wrong tries cancel a code. After 15 wrong codes for one number in 24 hours, no new code is sent to it until fewer than 15 remain in that window.

Resend limits, before any charge

30 seconds between sends to the same number and at most 5 an hour. A blocked request returns 429 with retry_after_seconds and a Retry-After header, and costs nothing.

WhatsApp does not stop bots

A bot can still submit your sign-up form and make you send codes you pay for. The limits above stop repeated sends to one number, not sends to many different numbers, so add a CAPTCHA and your own rate limits to the form that requests a code. What you do avoid is SMS pumping (carrier revenue-share fraud), because no SMS is sent.

Two numbers. That's the price.

Per OTP sent you pay Meta's authentication fee and PayPerWA's fee, shown separately. Checking a code costs nothing.

Meta's authentication fee

₹0.115

Meta's list rate per OTP to an Indian number. Billed by Meta to the payment method on your WhatsApp Business Account. Rates by country →

PayPerWA fee

₹0.20

Per OTP sent, from your prepaid PayPerWA wallet, whatever the recipient's country.

  • FreeVerifying a code
  • NoneSubscription
  • NoneSetup fee
  • NoneMinimum monthly spend

Example: 1,000 codes to Indian numbers cost Meta ₹115 (billed by Meta) + PayPerWA ₹200 (from your wallet). Minimum wallet recharge ₹750.

Price per OTP by country

Meta's authentication fee depends on the recipient's country. PayPerWA's fee depends only on your wallet's currency. Verifying is free everywhere.

  • Indian accounts (INR wallet): an OTP to an Indian number costs Meta ₹0.115 + PayPerWA ₹0.20 = ₹0.315. To other countries PayPerWA's fee stays ₹0.20 and Meta charges that country's rate.
  • Accounts outside India (USD wallet): Meta's fee from the table + PayPerWA $0.004 per OTP sent.
Price of one WhatsApp OTP by recipient country on a USD wallet: Meta's authentication fee plus PayPerWA's fee
Recipient's countryMeta's authentication fee+ PayPerWA (USD wallet)= Per OTP sent
India$0.0014$0.004$0.0054
Nigeria$0.0067$0.004$0.0107
Indonesia$0.025$0.004$0.029
Saudi Arabia$0.0107$0.004$0.0147
United Arab Emirates$0.0157$0.004$0.0197
Brazil$0.0068$0.004$0.0108
Mexico$0.0085$0.004$0.0125
United States$0.0034$0.004$0.0074
Egypt$0.0036$0.004$0.0076
United Kingdom$0.022$0.004$0.026
South Africa$0.0095$0.004$0.0135
Kenya$0.004$0.004$0.008

Meta's list rates from its USD rate card effective 1 October 2026, billed by Meta to your WhatsApp Business Account (in the currency that account is billed in). Meta charges per delivered message, and PayPerWA refunds its own fee if Meta rejects a send or reports it as failed. Meta can change rates only on 1 January, 1 April, 1 July or 1 October. Very high-volume senders messaging users in certain other countries can become eligible for Meta's higher authentication-international rates; see the WhatsApp OTP API guide. Every other country is on the rates page.

Set it up in four steps

One template, one API key, two calls.

  1. 1

    Create your account

    Sign up free, connect your WhatsApp Business number with Meta's embedded signup and top up your wallet (minimum ₹750).

  2. 2

    Create an Authentication template

    Dashboard → Templates → New → Authentication. Meta reviews it before you can send. Your Meta business must be verified first: PayPerWA stops the submission and links you to Meta's business verification if Meta reports it as not verified or still pending.

  3. 3

    Get an API key

    Dashboard → Settings → API. Use a key with the messages:send permission and keep it on your server.

  4. 4

    Call send, then verify

    /otp/send when the user asks for a code, /otp/verify when they type it in.

The message Meta allows

Authentication templates use wording fixed by Meta, so there is no message copy for you to write.

  • Body: <code> is your verification code.
  • Optional: "For your security, do not share this code."
  • Optional footer with the expiry time
  • A Copy code button
  • No links, media or emoji

The PayPerWA dashboard creates copy-code templates only. Meta's one-tap and zero-tap autofill are Android-only, and PayPerWA does not offer them.

731905 is your verification code. For your security, do not share this code.

This code expires in 5 minutes.

Copy code

Sample of the fixed format

WhatsApp OTP API questions

Something else? Talk to us.

How much does a WhatsApp OTP cost with PayPerWA?
Two separate fees per OTP sent: Meta's authentication fee for the recipient's country, which Meta bills to the payment method on your WhatsApp Business Account (Meta's list rate for an Indian number is ₹0.115), and PayPerWA's fee of ₹0.20 ($0.004 on a USD wallet), taken from your prepaid wallet. So an OTP to an Indian number from an INR wallet costs Meta ₹0.115 + PayPerWA ₹0.20 = ₹0.315. Verifying a code is free. There is no subscription, no setup fee and no minimum monthly spend.
Do I need DLT registration to send OTPs on WhatsApp in India?
No. DLT entity, header and template registration is a requirement for SMS. A WhatsApp OTP needs an approved WhatsApp Authentication template instead. You create it in Dashboard → Templates → New → Authentication, and Meta reviews it before you can send.
What if my user does not have WhatsApp?
Then the code cannot reach them. The recipient must use WhatsApp on the number you send to, and PayPerWA has no SMS fallback, so keep another way to sign in (for example email, or your existing SMS provider) for people without WhatsApp. Meta also requires that people opt in to receive messages from you on WhatsApp.
Does PayPerWA support one-tap or zero-tap autofill?
No. The PayPerWA dashboard creates copy-code Authentication templates only: your user taps Copy code and pastes it. One-tap and zero-tap are Android-only Meta features that PayPerWA does not offer. On iPhones with iOS 26 or later, the system can suggest numeric codes of 3 to 8 digits from the WhatsApp notification.
How long is a code valid, and how many attempts does a user get?
You choose per send: codes are 4 to 8 digits (6 by default) and expire after 1 to 30 minutes (10 by default). Each code works once, and five wrong attempts cancel it. A new code replaces the previous one as soon as Meta accepts it; if the send is refused with an error, the previous code stays valid. You can send again to the same number after 30 seconds, up to 5 times an hour. Once 15 wrong codes have been entered for a number in 24 hours, no new code is sent to it until fewer than 15 remain in that window.
Does WhatsApp OTP stop bots and fake sign-ups?
No. A bot can still submit your sign-up form and make you send codes you pay for. PayPerWA's limits stop repeated sends to one number and are checked before any charge, but they do not stop sends to many different numbers. Add a CAPTCHA and your own rate limits to the form that requests a code. What you do avoid is SMS pumping, the fraud that earns attackers a share of carrier revenue from SMS, because no SMS is sent.
Do I need to generate or store the codes myself?
No. PayPerWA generates each code with a cryptographic random number generator, sends it, keeps only a keyed hash of it and checks it when you call verify. The code is never returned to you in an API response; your server only passes on what the user typed.
Can I send OTPs to numbers outside India?
Yes, to people who use WhatsApp. Send the number with its country code (a leading + or 00 is fine). Meta's authentication fee depends on the recipient's country: on Meta's USD rate card effective 1 October 2026 it is $0.0067 for Nigeria, $0.0034 for the United States, $0.022 for the United Kingdom and $0.0157 for the UAE. The price table on this page lists more countries and our rates page lists every country. PayPerWA's fee stays ₹0.20 per OTP sent on an INR wallet or $0.004 on a USD wallet, whatever the recipient's country, so an OTP to Nigeria from a USD wallet costs Meta $0.0067 + PayPerWA $0.004.
How does PayPerWA compare with Twilio Verify?
They charge in different ways. Twilio's Verify pricing page (checked 9 November 2026) lists $0.05 per successful verification plus channel delivery fees, which for WhatsApp means a fee per authentication message. PayPerWA charges per OTP sent instead: Meta's authentication fee for the recipient's country, billed by Meta, plus PayPerWA's $0.004 on a USD wallet (₹0.20 on an INR wallet), and checking a code is free. PayPerWA's fee applies to every OTP sent, including codes your user never enters, while Twilio's verification fee applies only when a code is approved. Twilio also offers SMS, voice and email codes; PayPerWA sends codes on WhatsApp only, with no SMS fallback. Compare with your own volumes and conversion rate.

Add WhatsApp OTP to your sign-in

Meta's authentication fee + PayPerWA ₹0.20 per OTP sent. Verifying is free. No subscription, no setup fee.

Chat with us