WhatsApp supports a dedicated Authentication template category specifically designed for One-Time Passwords (OTPs) and verification codes.
To improve conversion rates and user experience, you can include a Copy Code button, which allows users to copy the code to their device clipboard with a single tap.
Meta guidelines for OTP templates
Meta enforces strict formatting and security policies on authentication templates:
- No media allowed: You cannot add images, video files, or document attachments.
- No external links: The template cannot contain URL buttons or custom phone numbers.
- Copy Code buttons: Must be configured as a button of type
copy_codewith the dynamic OTP parameter bound to it.
Dynamic parameters mapping
When sending an OTP template with a Copy Code button, you must provide parameters for both the message body and the button.
Suppose your template is configured as:
- Body:
"{{1}} is your verification code. For security, do not share this code." - Button: Copy Code
Your API request must provide:
- A body parameter: the code (e.g.,
582910). - A button parameter: the code itself to be copied by the button (e.g.,
582910).
Send code example
Use the following request pattern to dispatch an OTP code:
curl -X POST "https://api.wazapin.com/v1/messages" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"channel_id": "wzp_abc123",
"to": "6281234567890",
"type": "template",
"content": {
"name": "otp_verification",
"language": {
"code": "en_US"
},
"components": [
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "582910"
}
]
},
{
"type": "button",
"sub_type": "copy_code",
"index": 0,
"parameters": [
{
"type": "text",
"text": "582910"
}
]
}
]
}
}'import { WazapinClient } from "@wazapin/sdk";
const wazapin = new WazapinClient({ apiKey: process.env.WAZAPIN_API_KEY! });
await wazapin.messages.send({
channel_id: "wzp_abc123",
to: "6281234567890",
type: "template",
content: {
name: "otp_verification",
language: { code: "en_US" },
components: [
{
type: "body",
parameters: [{ type: "text", text: "582910" }]
},
{
type: "button",
sub_type: "copy_code",
index: 0,
parameters: [{ type: "text", text: "582910" }]
}
]
}
});import requests
requests.post(
"https://api.wazapin.com/v1/messages",
headers={"X-Api-Key": "YOUR_API_KEY", "Content-Type": "application/json"},
json={
"channel_id": "wzp_abc123",
"to": "6281234567890",
"type": "template",
"content": {
"name": "otp_verification",
"language": {"code": "en_US"},
"components": [
{
"type": "body",
"parameters": [{"type": "text", "text": "582910"}]
},
{
"type": "button",
"sub_type": "copy_code",
"index": 0,
"parameters": [{"type": "text", "text": "582910"}]
}
]
}
},
timeout=30
).raise_for_status()Troubleshooting
Button does not copy the code
Make sure the index matches the zero-based index of the Copy Code button in your template configuration (usually 0 if it is the only button). Ensure the sub_type is set exactly to "copy_code".
Template validation errors
If Meta rejects the template during creation, confirm you did not include links, media, or any text suggesting promotional offers in the template body or buttons.