Skip to content

OTP Authentication

Send verification codes via WhatsApp Authentication templates

View .md

WhatsApp Authentication templates provide a secure, high-delivery-rate channel for sending one-time passwords (OTP) and verification codes. This guide covers creating, submitting, and sending OTP messages.

Overview

Authentication templates are purpose-built for verification codes:

  • High delivery rates - WhatsApp messages have 98%+ open rates
  • Instant delivery - Codes arrive in seconds
  • User-friendly - Copy button or auto-fill on Android
  • Cost-effective - Lowest messaging rates of all template categories
  • Secure - End-to-end encrypted delivery

Prerequisites

Before creating OTP templates, ensure you have:

Step 1: Create OTP Template

Via Dashboard

  1. Navigate to Senders in your dashboard
  2. Select the sender with WhatsApp connected
  3. Go to the Templates tab
  4. Click Create Template
  5. Configure the template:
    • Name: Use a descriptive name like otp_verification
    • Channel: Select WhatsApp only
    • Category: Select AUTHENTICATION
    • Language: Choose your language (e.g., en)
  6. Configure the OTP button:
    • Button Type: Choose Copy Code or One-Tap (Android only)
  7. Optional settings:
    • Enable Security Recommendation to add "Do not share this code"
    • Set Code Expiration (1-90 minutes)
  8. Click Create

Via API

import Zavudev from '@zavudev/sdk'; const zavu = new Zavudev({ apiKey: process.env["ZAVUDEV_API_KEY"], }); const template = await zavu.templates.create({ name: 'otp_verification', language: 'en', body: '{{1}} is your verification code.', category: 'AUTHENTICATION', buttons: [{ type: 'otp', text: 'Copy code', otpType: 'COPY_CODE' }], addSecurityRecommendation: true, codeExpirationMinutes: 10 }); console.log('Template ID:', template.id); console.log('Status:', template.status); // "draft"

Step 2: Submit for Meta Approval

Authentication templates typically receive fast approval (within hours).

Via Dashboard

  1. Go to Senders > Select sender > Templates tab
  2. Find your template with "Draft" status
  3. Click the ... menu and select Submit for Approval

Via API

await zavu.templates.submit({ templateId: template.id, senderId: 'sender_abc123' }); // Check status const updated = await zavu.templates.retrieve({ templateId: template.id }); console.log('Status:', updated.status); // "pending" -> "approved"

Expected Approval Time

Template TypeTypical Approval Time
AUTHENTICATION1-4 hours
UTILITY24-48 hours
MARKETING24-72 hours

Step 3: Send OTP Messages

Once approved, send verification codes to users:

import Zavudev from '@zavudev/sdk'; const zavu = new Zavudev({ apiKey: process.env["ZAVUDEV_API_KEY"], }); // Generate your OTP code const otpCode = '123456'; const message = await zavu.messages.send({ to: '+14155551234', messageType: 'template', content: { templateId: 'tmpl_abc123', templateVariables: { '1': otpCode // The OTP code } } }); console.log('Message ID:', message.id); console.log('Status:', message.status);

What the User Sees

The user receives a message like:

Code
123456 is your verification code. For your security, do not share this code. This code expires in 10 minutes. [Copy code]

OTP Button Types

The Copy Code button allows users to tap and copy the code to their clipboard.

TypeScript
buttons: [{ type: 'otp', text: 'Copy code', otpType: 'COPY_CODE' }]

Benefits:

  • Works on all platforms (iOS, Android, Web)
  • Simple user experience
  • No additional configuration required

ONE_TAP (Android Only)

The One-Tap button enables automatic code filling in your Android app.

TypeScript
buttons: [{ type: 'otp', text: 'Copy code', otpType: 'ONE_TAP', packageName: 'com.yourcompany.app', signatureHash: 'K8a+W1234...' }]

Requirements:

  • Android app only
  • Must provide packageName (Android package name)
  • Must provide signatureHash (Android app signature hash)

How to get your signature hash:

  1. In your Android app, use the SMS Retriever API helper:
JAVA
AppSignatureHelper helper = new AppSignatureHelper(context); ArrayList<String> signatures = helper.getAppSignatures(); // Use the first signature String signatureHash = signatures.get(0);
  1. The hash is an 11-character string like K8a+W1234ab

Template Options

Security Recommendation

Add a security disclaimer to your OTP message:

TypeScript
addSecurityRecommendation: true

This adds: "For your security, do not share this code."

Code Expiration

Display when the code expires:

TypeScript
codeExpirationMinutes: 10 // 1-90 minutes

This adds: "This code expires in 10 minutes."

Best Practices

Use Short Expiration

Set expiration to 5-10 minutes for security. Shorter is better.

Enable Security Warning

Always enable addSecurityRecommendation to protect users from phishing.

Generate Secure Codes

Use cryptographically secure random number generators for OTP codes.

Rate Limit Requests

Limit OTP requests per user to prevent abuse (e.g., 5 per hour).

OTP Code Guidelines

  • Use 6-digit numeric codes for balance of security and usability
  • Generate codes using secure random functions
  • Store codes with expiration timestamps
  • Invalidate codes after successful verification
  • Limit verification attempts (e.g., 3 tries per code)
TypeScript
// Example: Generate secure OTP import crypto from 'crypto'; function generateOTP(): string { return crypto.randomInt(100000, 999999).toString(); }

Common Issues

IssueSolution
Template rejectedEnsure category is AUTHENTICATION and content is purely verification-related
Code not displayingCheck that variable {{1}} is provided in templateVariables
One-Tap not workingVerify packageName and signatureHash are correct for your Android app
Slow deliveryCheck recipient's WhatsApp status and your sender's quality rating
Button not showingEnsure the template has buttons configured with OTP type

Webhook Events

Track OTP delivery status via webhooks:

JSON
{ "id": "evt_1702000000000_abc123", "type": "message.delivered", "timestamp": 1702000000000, "data": { "messageId": "msg_xyz789", "to": "+14155551234", "channel": "whatsapp", "status": "delivered" } }

Configure webhooks to receive:

  • message.sent - OTP accepted by WhatsApp
  • message.delivered - OTP delivered to device
  • message.failed - Delivery failed

See Webhooks Guide for setup instructions.

Next Steps