Authentication Templates with One-Time-Password
Starting May 29, 2023, all newly created authentication templates must include a one-time password button.
This functionality will not be available to businesses based in India until later this year.
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:
Definition | Sample |
---|---|
Providing an authentication code to the user |
|
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.
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.
You can use the WhatsApp Business Management API to create authentication 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
Use the create template endpoint and assemble the authentication components in the request:
POST /v1/configs/templates
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
Placeholder | Description | Sample Value |
---|---|---|
<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. | 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. | '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"
}
]
}
]
Placeholder | Description | Sample Value |
---|---|---|
<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 |
<LANGUAGE> String | en_US | |
<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. | 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. | 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"
}
]
}
]
post
https://waba.360dialog.io/v1
/messages
Send Authentication Template
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"
}
]
}
]
}
}
Upon success, the API will respond with a JSON object describing the newly created template.
{
"id": "594425479261596",
"status": "PENDING",
"category": "AUTHENTICATION"
}
post
https://waba-v2.360dialog.io
/messages
Send Authentication Template
Placeholder | Description | Sample Value |
---|---|---|
<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_LANGUAGE_CODE> | en_US | |
<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"
}
]
}
]
}
Upon success, the API will respond with a JSON object describing the newly created template.
{
"id": "594425479261596",
"status": "PENDING",
"category": "AUTHENTICATION"
}