Authentication Templates with One-Time-Password
Authentication templates enables businesses to authenticate users with one-time passcodes (usually 4-8 digit alphanumeric codes), potentially at multiple steps in the login process (e.g., account verification, account recovery, integrity challenges).
If your business offers users the option to receive one-time passwords or verification codes via WhatsApp Business App, by May 29, 2023 you must use an authentication template with a one-time password button (OTP) to deliver the password or code. It's appropriate to use an authentication template when:
Providing an authentication code to the user
"{{1}} is your verification code."
"{{1}} is your verification code. For your security, do not share this code."
"{{1}} is your verification code. This code expires in 15 minutes."
Authentication Template Requirements
Authentication templates include optional add-ons like security disclaimers and expiry warnings. In addition, authentication templates must have a one-time password button (copy code or one-tap). The presets in the authentication message template fixed text are:
<VERIFICATION_CODE> is your verification code.
Security disclaimer (optional): For your security, do not share this code.
Expiration warning (optional): This code expires in <NUM_MINUTES> minutes.
Button: Either a copy code or one-tap autofill button.

URLs, media, and emojis are not supported. Because authentication templates with OTP buttons only consist of preset text and buttons, their risk of being paused is significantly minimized.
Buttons
Authentication templates must include either a copy code or one-tap autofill button. Buttons behave differently when tapped by a user:
A copy code button copies the one-time password or code to the user's clipboard. The user can then manually switch to your app and paste the password or code into your app's interface.
A one-tap autofill button automatically loads and passes your app the one-time password or code.
One-tap buttons are the preferred solution as they offer the best user experience. However, one-tap buttons are currently only supported on Android, requires changes to your application in order to perform a "handshake" with Meta, and your app's signing key hash. See Meta's Official documentation for Handshake and App Signing Key Hash.
Best Practices for Authentication Templates
Confirm the user's WhatsApp phone number before sending the one-time password or code to that number.
Make it clear to your user that the password or code will be delivered to their WhatsApp phone number, especially if you offer multiple ways for the user to receive password or code delivery. See Template Messages for additional tips.
When the user pastes the password or code into your app, or your app receives it as part of the one-tap autofill button flow, make it clear to the user that your app has captured it.
Creating Authentication Templates with One-Time-Password
You can use the WhatsApp Business Management API to create authentication templates.
In the API
Components
The components
value in the request must be an array of objects that describes each component that makes up the template. Authentication templates must have the following components:
a single body component
a single footer component
a single OTP Button component
Use the create template endpoint and assemble the authentication components in the request:
POST /v1/configs/templates
Components
The components
value in the request must be an array of objects that describes each component that makes up the template. Authentication templates must have the following components:
a single body component
a single footer component
a single OTP Button component
Properties
<ADD_SECURITY_RECOMMENDATION>
Optional.
Boolean. Set to true
if you want the template to include the string: For your security, do not share this code. Set to false
to exclude the string.
true
<CODE_EXPIRATION_MINUTES>
Optional.
Integer. Indicates number of minutes the password or code is valid.
If omitted, the code expiration warning will not be displayed in the delivered message.
Minimum 1, maximum 90.
5
<OTP_TYPE>
Enum. Indicates button type. Set to COPY_CODE
if you want the template to use a copy code button, or ONE_TAP
to have it use a one-tap autofill button.
See Buttons above.
ONE_TAP
<TEXT>
String. Copy code button text.
Note that even if your template is using a one-tap autofill button, this value must still be supplied. If Meta's unable to validate your handshake the authentication template message will display a copy code button with this text instead.
Maximum 25 characters.
'Copy Code'
<AUTOFILL_TEXT>
One-tap buttons only.
String. One-tap button text.
Maximum 25 characters.
'Autofill'
<PACKAGE_NAME>
One-tap buttons only.
Your Android app's package name.
'com.example.myapplication'
<SIGNATURE_HASH>
One-tap buttons only.
Your app signing key hash. See Meta's Official documentation for App Signing Key Hash.
'K8a%2FAINcGX7'
Sample request with components descriptions
{
"name": "sample",
"language": "es_ES",
"category": "AUTHENTICATION",
"components": [
{
"type": "BODY",
"add_security_recommendation": "<ADD_SECURITY_RECOMMENDATION>" /*#Optional*/
},
{
"type": "FOOTER",
"code_expiration_minutes": "<CODE_EXPIRATION_MINUTES>" /*Optional*/
},
{
"type": "BUTTONS",
"buttons": [
{
"type": "OTP",
"otp_type": "<OTP_TYPE>",
"text": "<TEXT>",
"autofill_text": "<AUTOFILL_TEXT>", /*One-tap buttons only*/
"package_name": "<PACKAGE_NAME>", /*One-tap buttons only*/
"signature_hash": "<SIGNATURE_HASH>" /*#One-tap buttons only*/
}
]
}
],
}
Sample Copy Code Button Components Value
[
{
"type": "BODY",
"add_security_recommendation": true
},
{
"type": "FOOTER",
"code_expiration_minutes": 5
},
{
"type": "BUTTONS",
"buttons": [
{
"type": "OTP",
"otp_type": "COPY_CODE",
"text": "Copy Code"
}
]
}
]
Sample One-tap Autofill Button Components Value
[
{
"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.example.myapplication",
"signature_hash": "K8a%2FAINcGX7"
}
]
}
]
Properties
<ADD_SECURITY_RECOMMENDATION>
Boolean
Optional.
Set to true
if you want the template to include the string, For your security, do not share this code. Set to false
to exclude the string.
true
<CATEGORY>
String
Required.
Template category. Set this to AUTHENTICATION
.
AUTHENTICATION
<CODE_EXPIRATION_MINUTES>
Integer
Optional.
Indicates number of minutes the password or code is valid.
If omitted, the code expiration warning will not be displayed in the delivered message.
Minimum 1, maximum 90.
5
<NAME>
String
Required.
Template name.
Maximum 512 characters.
verification_code
<OTP_TYPE>
String
Indicates button type. Set to COPY_CODE
if you want the template to use a copy code button, or ONE_TAP
to have it use a one-tap autofill button.
See Buttons above.
ONE_TAP
<TEXT>
String
Copy code button text.
Note that even if your template is using a one-tap autofill button, this value must still be supplied. If Meta's unable to validate your handshake the authentication template message will display a copy code button with this text instead.
Maximum 25 characters.
Copy Code
<AUTOFILL_TEXT>
String
One-tap buttons only.
One-tap button text.
Maximum 25 characters.
Autofill
<PACKAGE_NAME>
String
One-tap buttons only.
Your Android app's package name.
com.example.myapplication
<SIGNATURE_HASH>
String
One-tap buttons only.
Your app signing key hash. See Meta's Official documentation for App Signing Key Hash.
K8a%2FAINcGX7
Sample request with components descriptions
{
"name": "sample",
"language": "es_ES",
"category": "AUTHENTICATION",
"components": [
{
"type": "BODY",
"add_security_recommendation": "<ADD_SECURITY_RECOMMENDATION>" /*#Optional*/
},
{
"type": "FOOTER",
"code_expiration_minutes": "<CODE_EXPIRATION_MINUTES>" /*Optional*/
},
{
"type": "BUTTONS",
"buttons": [
{
"type": "OTP",
"otp_type": "<OTP_TYPE>",
"text": "<TEXT>",
"autofill_text": "<AUTOFILL_TEXT>", /*One-tap buttons only*/
"package_name": "<PACKAGE_NAME>", /*One-tap buttons only*/
"signature_hash": "<SIGNATURE_HASH>" /*#One-tap buttons only*/
}
]
}
],
}
Sample Copy Code Button Components Value
[
{
"type": "BODY",
"add_security_recommendation": true
},
{
"type": "FOOTER",
"code_expiration_minutes": 5
},
{
"type": "BUTTONS",
"buttons": [
{
"type": "OTP",
"otp_type": "COPY_CODE",
"text": "Copy Code"
}
]
}
]
Sample One-tap Autofill Button Components Value
[
{
"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.example.myapplication",
"signature_hash": "K8a%2FAINcGX7"
}
]
}
]
Sending Authentication Templates with One-Time-Password
If the number is registered on On-Premise API
Send Authentication Template
POST
https://waba.360dialog.io/v1/messages
Request Body
to
string
Recepient_wa_id
language
String
Contains a language
object. Specifies the language the template may be rendered in.
The language
object can contain the following fields:
policy
string – Required. The language policy the message should follow. The only supported option is deterministic.
code
string – Required. The code of the language or locale to use.
Accepts both language
andlanguage_locale
formats (e.g., en
and en_US
).
name
String
Name of the template.
namespace
Namespace of the template.
A successful response includes a messages
object with an id
.
{
"messages": [{
"id": "gBEGkYiEB1VXAglK1ZEqA1YKPrU"
}]
}
Sample payload with Copy Code Button
{
"to": "recipient_wa_id",
"type": "template",
"template": {
"namespace": "your-namespace",
"name": "your-template-name",
"language": {
"code": "your-language-and-locale-code",
"policy": "deterministic"
},
"components": [
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "user-otp-code"
}
]
},
{
"type": "button",
"sub_type": "url",
"index": 0,
"parameters": [
{
"type": "text",
"text": "user-otp-code"
}
]
}
]
}
}
Example Response
Upon success, the API will respond with a JSON object describing the newly created template.
{
"id": "594425479261596",
"status": "PENDING",
"category": "AUTHENTICATION"
}
If the number is registered on Cloud API
Send Authentication Template
POST
https://waba-v2.360dialog.io/messages
Request Body
name
String
type
String
Message type
to
String
Recipient wa_id
messaging_product
String
Required only for Cloud API.
Messaging service used for the request. Use "whatsapp"
.
components
String
language
String
{
"messaging_product": "whatsapp",
"contacts": [
{
"input": "12015553931",
"wa_id": "12015553931"
}
],
"messages": [
{
"id": "wamid.HBgLMTY1MDM4Nzk0MzkVAgARGBI4Qzc5QkNGNTc5NTMyMDU5QzEA"
}
]
}
<CUSTOMER_PHONE_NUMBER>
The customer's WhatsApp phone number.
12015553931
<ONE-TIME PASSWORD>
The one-time password or verification code to be delivered to the customer.
Note that this value must appear twice in the payload.
J$FpnYnP
<TEMPLATE_NAME>
The template's name.
verification_code
Sample payload with Copy Code Button
{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "<CUSTOMER_PHONE_NUMBER>",
"type": "template",
"template": {
"name": "<TEMPLATE_NAME>",
"language": {
"code": "<TEMPLATE_LANGUAGE_CODE>"
}
},
"components": [
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "<ONE-TIME PASSWORD>"
}
]
},
{
"type": "BUTTONS",
"buttons": [
{
"type": "OTP",
"otp_type": "COPY_CODE",
"text": "Copy Code"
}
]
}
]
}
Example Response
Upon success, the API will respond with a JSON object describing the newly created template.
{
"id": "594425479261596",
"status": "PENDING",
"category": "AUTHENTICATION"
}
Last updated
Was this helpful?