Skip to main content
Requirements: To create AUTHENTICATION templates, your WhatsApp business account needs:
  • Business verification
  • At least 2000 business initiated conversations
Authentication templates have a fixed body text generated by Meta: *{{1}}* is your verification code. You can’t customize the body text, but you can:
  • Add a security recommendation: “For your security, do not share this code.”
  • Add code expiration: “This code expires in X minutes.”

OTP types

TypeButtonUse case
COPY_CODE”Copy code”Universal - works on all devices
ONE_TAP”Autofill”Android only - auto-fills code in your app
ZERO_TAPNoneSilent auto-fill, no user interaction needed

Create copy code template

The most common type. Shows a “Copy code” button.
await client.templates.create({
  businessAccountId: '123456789',
  name: 'auth_copy_code',
  category: 'AUTHENTICATION',
  language: 'en_US',
  components: [
    {
      type: 'BODY',
      add_security_recommendation: true
    },
    {
      type: 'FOOTER',
      code_expiration_minutes: 10
    },
    {
      type: 'BUTTONS',
      buttons: [
        { type: 'OTP', otp_type: 'COPY_CODE' }
      ]
    }
  ]
});

Create one-tap template (Android)

Auto-fills the code in your Android app. Requires your app’s package name and signature hash.
await client.templates.create({
  businessAccountId: '123456789',
  name: 'auth_one_tap',
  category: 'AUTHENTICATION',
  language: 'en_US',
  components: [
    {
      type: 'BODY',
      add_security_recommendation: true
    },
    {
      type: 'BUTTONS',
      buttons: [
        {
          type: 'OTP',
          otp_type: 'ONE_TAP',
          supported_apps: [
            {
              package_name: 'com.example.myapp',
              signature_hash: 'K8a/AINcD...'
            }
          ]
        }
      ]
    }
  ]
});
Get your Android app’s signature hash:
keytool -exportcert -alias YOUR_ALIAS -keystore YOUR_KEYSTORE | xxd -p | tr -d "[:space:]" | openssl sha256

Create zero-tap template

No visible button. The code is broadcast to your app via Android’s SMS Retriever API.
await client.templates.create({
  businessAccountId: '123456789',
  name: 'auth_zero_tap',
  category: 'AUTHENTICATION',
  language: 'en_US',
  components: [
    {
      type: 'BODY',
      add_security_recommendation: true
    },
    {
      type: 'BUTTONS',
      buttons: [
        {
          type: 'OTP',
          otp_type: 'ZERO_TAP',
          supported_apps: [
            {
              package_name: 'com.example.myapp',
              signature_hash: 'K8a/AINcD...'
            }
          ]
        }
      ]
    }
  ]
});

Send

When sending, pass the OTP code in both the body and button parameters.
await client.messages.sendTemplate({
  phoneNumberId: '647015955153740',
  to: '15551234567',
  template: {
    name: 'auth_copy_code',
    language: { code: 'en_US' },
    components: [
      {
        type: 'body',
        parameters: [
          { type: 'text', text: '123456' }
        ]
      },
      {
        type: 'button',
        sub_type: 'otp',
        index: '0',
        parameters: [
          { type: 'text', text: '123456' }
        ]
      }
    ]
  }
});

Component reference

Body

FieldTypeDescription
add_security_recommendationbooleanAdds “For your security, do not share this code.”
FieldTypeDescription
code_expiration_minutesnumber1-90. Adds “This code expires in X minutes.”

OTP button

FieldTypeDescription
otp_typestringCOPY_CODE, ONE_TAP, or ZERO_TAP
supported_appsarrayRequired for ONE_TAP and ZERO_TAP. List of {package_name, signature_hash}

Restrictions

  • No headers - AUTHENTICATION templates cannot include HEADER components
  • Fixed body text - Body text is generated by Meta, not customizable
  • No custom parameters - Only the OTP code can be passed as a variable