+
R

By Ryan

Published on Oct 15, 2026

WhatsApp Authentication Templates: How to Send OTPs on WhatsApp

Authentication templates are WhatsApp’s dedicated category for OTPs: fixed content, instant approval, and an OTP button built for Android autofill. This guide covers button types, requirements, creating and sending via dashboard or API, expiry vs TTL, and pricing.

TL;DR: Authentication templates are the WhatsApp Business Platform's dedicated category for OTPs and verification codes. The message text is fixed by WhatsApp, you supply only the code, and you pick an OTP button (copy code, one-tap autofill, or zero-tap). They are typically approved almost instantly, rarely get paused, and billed only when delivered. This guide covers how they differ from other templates, when to use them, how to create and send one (dashboard and API), how code expiry differs from message TTL, and the best practices that prevent most production issues.

Introduction

If your app sends OTPs over SMS, you already know the pain: rising costs, delayed or filtered messages, and users who never see the code. WhatsApp authentication templates give you another route. Codes arrive in an app people already check constantly, and on Android you can offer a one-tap autofill that drops the code straight into your app.

This guide covers what authentication templates are, how they differ from Marketing and Utility templates, when you can (and can't) use them, and how to create and send one, both from the Chakra dashboard and through the API.

What Are Authentication Templates?

Authentication templates are one of the three template categories on the WhatsApp Business Platform, alongside Marketing and Utility. They exist for one job: delivering one-time passwords and verification codes that confirm a user's identity.

What makes them different:

  • The content is standardized. You cannot write custom body text. WhatsApp generates it in the template's language ("{{1}} is your verification code") and you only supply the code.
  • They require an OTP button. Copy code or one-tap autofill is mandatory, or zero-tap, which shows no visible button. These button types exist only in this category.
  • Expiry text is optional. You can add a footer such as "This code expires in 5 minutes."
  • Approval is typically instant, since the content is preset and non-promotional. Meta also notes that authentication templates with OTP buttons carry a much lower risk of being paused than other categories.

Anatomy of an Authentication Template

ComponentRequired?Details
HeaderNot supportedAuthentication templates cannot include a header or any media.
BodyRequired (auto-generated)"{{1}} is your verification code." You can optionally add "For your security, do not share this code." You cannot edit the text.
FooterOptionalShows "This code expires in X minutes" when you set a code expiration.
ButtonRequiredA single OTP button: copy code, one-tap autofill, or zero-tap.

What the user sees:

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

This code expires in 5 minutes.

[ Copy code ]

Button Types: Copy Code vs. One-Tap Autofill vs. Zero-Tap

Copy CodeOne-Tap AutofillZero-Tap
How it worksUser taps, code is copied, user pastes it into your appUser taps, code is passed directly into your Android appNo tap: the code is delivered to your Android app when the message arrives
PlatformAll devicesAndroid onlyAndroid only
RequirementsNoneYour app's package name and signature hashSame as one-tap, plus accepting Meta's zero-tap terms
Best forUniversal baselineAndroid apps that want the smoothest standard flowApps with deep Android integration

Fallback behavior matters. A one-tap or zero-tap template still requires you to supply the copy code button label. If Meta can't validate the autofill handshake (for example, the app isn't installed), the message shows a copy code button instead. So you don't build "autofill plus copy code" as two buttons: a template carries a single OTP button, and the copy code fallback comes built in.

A note on iPhone. One-tap and zero-tap are Android features. Separately, Meta's documentation states that from June 15, 2026, on iOS 26 and later, keyboard suggestions provide native OTP autofill from the push notification, with no integration required on your side.

About the signature hash. For one-tap and zero-tap, you provide your Android app's package name and an 11-character signature hash derived from your app's signing certificate. A mismatch is the most common reason autofill silently falls back to copy code, so test on a real device before you ship. Meta's OTP Android SDK simplifies the handshake and is worth using.

When to Use Authentication Templates

Use them only for verification codes:

  • Login and registration (verifying a phone number)
  • Two-factor authentication
  • Account recovery and password resets
  • Confirming identity before sensitive account changes
  • Re-verification on a new device or after a period of inactivity

When Not to Use Them

Authentication templates are strictly for codes. Using them for anything else gets templates rejected or recategorized:

  • Order updates and delivery notifications belong in Utility.
  • Promotions, offers, and re-engagement belong in Marketing.
  • Any content that isn't a verification code does not belong here.

The reverse mistake is just as common: don't put an OTP inside a Utility template to avoid the fixed format. Meta detects OTP content and will recategorize or reject it. If your message carries a code, it belongs in an Authentication template, and that also determines how it's billed.

Requirements and Limits

For the business

  • An active WhatsApp Business Account on the WhatsApp Business Platform, available through providers like Chakra.
  • Copy code and one-tap need no special approval. Zero-tap requires accepting Meta's zero-tap terms when you create the template.

For the template

  • Body text is fixed. No custom copy and no extra variables beyond the code.
  • Exactly one OTP button.
  • Button label text: 25 characters maximum.
  • Signature hash (one-tap and zero-tap): exactly 11 characters.
  • Code expiration (optional): 1 to 90 minutes.
  • Keep codes to the usual 4 to 8 digits, which is what autofill flows are designed around.

For the recipient

  • The number must have an active WhatsApp account. If it doesn't, delivery fails (you'll see error 131026), so an SMS fallback is a sensible safety net for critical flows.
  • Per Meta's documentation, authentication messages are delivered only to the user's primary WhatsApp device.
  • One-tap autofill additionally needs your app installed on an Android device.

How to Create an Authentication Template

Option 1: From the Chakra Dashboard

Chakra's template management lets you create templates in every category, including Authentication, with submission to Meta and approval status syncing handled for you.

  1. Open template management and create a new template.
  2. Choose the Authentication category.
  3. Name the template (lowercase letters, numbers, and underscores) and select its language.
  4. Choose the button type: copy code, or one-tap autofill.
  5. For one-tap, enter your Android package name and signature hash.
  6. Toggle the security recommendation ("For your security, do not share this code") on or off.
  7. Set a code expiration (5 to 10 minutes is typical for login flows).
  8. Submit. Approval is typically instant.
Screenshot 2026-10-14 at 3.14.40 PM.png

Option 2: Via the API

Create a copy code template:

json

POST https://graph.facebook.com/v{version}/{WABA_ID}/message_templates

{
"name": "login_otp_copy_code",
"language": "en_US",
"category": "AUTHENTICATION",
"message_send_ttl_seconds": 300,
"components": [
{ "type": "BODY", "add_security_recommendation": true },
{ "type": "FOOTER", "code_expiration_minutes": 5 },
{
"type": "BUTTONS",
"buttons": [
{ "type": "OTP", "otp_type": "COPY_CODE", "text": "Copy Code" }
]
}
]
}

Create a one-tap autofill template (the copy code label is the built-in fallback):

json

{
"name": "login_otp_autofill",
"language": "en_US",
"category": "AUTHENTICATION",
"message_send_ttl_seconds": 300,
"components": [
{ "type": "BODY", "add_security_recommendation": true },
{ "type": "FOOTER", "code_expiration_minutes": 5 },
{
"type": "BUTTONS",
"buttons": [
{
"type": "OTP",
"otp_type": "ONE_TAP",
"text": "Copy Code",
"autofill_text": "Autofill",
"package_name": "com.yourcompany.app",
"signature_hash": "K8a/AINcGX7"
}
]
}
]
}

Field reference

FieldRequiredNotes
nameYesLowercase letters, numbers, underscores.
languageYesLocale code such as en_US. Body text localizes automatically.
categoryYesMust be AUTHENTICATION.
message_send_ttl_secondsNoHow long Meta keeps trying to deliver. Default is 10 minutes.
BODY.add_security_recommendationNoAdds the "do not share this code" line.
FOOTER.code_expiration_minutesNoAdds the expiry line. 1 to 90 minutes.
BUTTONSYesA single OTP button. otp_type is COPY_CODE, ONE_TAP, or ZERO_TAP.
textYesCopy code label, 25 characters max. Required even for one-tap, as the fallback.
autofill_textOne-tap onlyAutofill label, 25 characters max.
package_name, signature_hashOne-tap and zero-tapYour Android app's package name and 11-character signature hash.

Multiple languages. The same template name can exist in several languages. Meta's upsert endpoint lets you create an authentication template across a list of languages in one call, instead of repeating the request per language.

Sending the Code

With Chakra's SDK

Chakra's TypeScript SDK has an OTP parameter, so you don't assemble components by hand:

javascript

await client.whatsapp.templateMessages.send({
pluginId: "YOUR_PLUGIN_ID",
toPhoneNumber: "919999999999",
whatsappPhoneNumberId: "YOUR_PHONE_NUMBER_ID",
templateName: "login_otp",
otpCode: "496093",
});

Phone numbers should include the country code with no + or formatting characters.

With the Meta-format endpoint

If you prefer the raw Meta payload through Chakra's pass-through endpoint, note one detail that trips people up: the code must appear twice, once in the body and once in the button component.

bash

curl --request POST \
'https://api.chakrahq.com/v1/ext/plugin/whatsapp/{pluginId}/api/v19.0/{whatsappPhoneNumberId}/messages' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "919999999999",
"type": "template",
"template": {
"name": "login_otp",
"language": { "code": "en_US" },
"components": [
{
"type": "body",
"parameters": [ { "type": "text", "text": "482913" } ]
},
{
"type": "button",
"sub_type": "url",
"index": "0",
"parameters": [ { "type": "text", "text": "482913" } ]
}
]
}
}'

Leaving out the button parameter is a common cause of failed OTP sends. Use a current Graph API version in the URL, and see Chakra's API reference for authentication and request details.

Code Expiry and Message TTL Are Different Settings

These two are easy to confuse:

  • code_expiration_minutes controls the text shown to the user ("This code expires in X minutes"). It communicates how long the code is valid.
  • message_send_ttl_seconds controls how long Meta keeps trying to deliver the message. For authentication templates the default is 10 minutes, and you can shorten it. If delivery doesn't happen within that window, Meta drops the message, and undelivered messages aren't charged.

Set both deliberately, and keep them aligned with your server-side validity window. If the TTL passes and you've received no delivery webhook, treat the message as dropped, which is the natural trigger for an SMS fallback.

The End-to-End OTP Flow

  1. The user enters their phone number in your app or site.
  2. Your backend generates a code and calls the send API.
  3. WhatsApp delivers the authentication template.
  4. The user taps autofill (Android) or copies the code and pastes it.
  5. Your backend verifies the code and signs the user in.
  6. Your webhook receives delivery status, so you can trigger a fallback if the message never lands.

Pricing

  • Authentication messages are billed per delivered message, at the authentication rate for the recipient's country (Check pricing by country). Some markets also have a separate authentication-international rate for eligible businesses.
  • Undelivered messages, including ones dropped after the TTL, aren't charged.
  • Rates vary by country and change over time, so check Meta's current rate card before forecasting.
  • Chakra applies zero markup on template messages: you pay Meta's prevailing rate for successfully delivered messages.

Best Practices

  • Start with copy code. It works for every user. Add one-tap only if you have an Android app and can maintain the signature hash.
  • Keep expiry short, typically 5 to 10 minutes, and match your TTL to it.
  • Add an SMS fallback for recipients who can't receive WhatsApp (131026) and for messages with no delivery confirmation inside the TTL.
  • Rate-limit OTP requests on your server, with cooldowns between resends, to prevent abuse and accidental spam. Also account for API rate limits at traffic peaks (Chakra enforces 200 calls per minute).
  • Create each language you serve, under the same template name where possible.
  • Monitor status webhooks (sent, delivered, read, failed) to catch deliverability issues early.
  • Never use authentication templates for non-OTP content. It's the fastest route to recategorization.
  • Test autofill on a real Android device before launch. Signature hash problems only show up there.

FAQ

Can I customize the body text of an authentication template? No. The body is standardized. Your only text controls are the security disclaimer, the expiry line, and the button labels.

Do authentication templates need approval? They go through the normal submission, but because the content is preset they are typically approved almost immediately.

What happens if I send an OTP in a Utility template? Meta detects OTP content and will recategorize it as authentication or reject it. Use the correct category from the start.

Does one-tap autofill work on iPhone? No. One-tap and zero-tap are Android features. iPhone users get the copy code flow, and on iOS 26 and later, Meta says keyboard suggestions can autofill the code natively from the notification.

Can I send the same template in multiple languages? Yes. A template name can have a separate approved version per language, and you pick the language code when sending.

How long can the code be? Stick to 4 to 8 digits, the standard that autofill flows are built around.

Wrapping Up

Authentication templates are one of the simplest categories to get right: fixed content, instant approval, and an OTP button that fits your platform. If you're building login, signup, or two-factor flows, they're worth adding alongside SMS, or as your primary OTP channel where WhatsApp is how your users already communicate. For the full template and sending reference, see Meta's authentication template documentation and Chakra's API docs.