Templates

Templates are pre-approved, reusable message formats with dynamic variables and interactive elements. They keep your messages consistent and on-brand, and are required for WhatsApp business messaging. This page covers what templates are, how to create them, the available categories, and how to send with them.

POST/templates

What are templates?

A template is a named message format that supports dynamic content and per-channel variants. Templates let you:

  • Send consistent, branded messages.
  • Meet WhatsApp requirements — templates are required for WhatsApp business messages.
  • Support dynamic content with variables.
  • Include interactive buttons and media.
  • Stay compliant with messaging policies.

For variable substitution, channel variants, and button configuration in depth, see Variables & variants.

Authentication

All requests authenticate with your API key in the x-api-key header:

-H "x-api-key: YOUR_API_KEY"

Creating templates

Create a template with a name, category, its variables, and one or more channel_variants. Each variant defines the content for a specific channel.

POST/templates
{
  "name": "welcome_message",
  "description": "Welcome message for new customers",
  "category": "transactional",
  "variables": [
    {"name": "customer_name", "type": "text", "required": true},
    {"name": "website_url", "type": "url", "required": true}
  ],
  "channel_variants": [
    {
      "channel": "sms",
      "content": "Welcome {{customer_name}}! Visit us at {{website_url}}"
    },
    {
      "channel": "whatsapp",
      "content": "Welcome {{customer_name}}! 🎉\n\nThank you for joining our platform. We're excited to have you on board!\n\nGet started by exploring our features.",
      "header": "Welcome!",
      "footer": "We're here to help",
      "buttons": [
        {
          "type": "url",
          "text": "Get Started",
          "variable_name": "website_url"
        }
      ]
    }
  ]
}

Request fields

namestringrequired
Unique template identifier used when sending.
descriptionstring
Human-readable description of the template's purpose.
categorystringrequired
Template category. One of transactional, authentication, or marketing.
variablesobject[]required
The dynamic variables used in the content. See Variables & variants.
channel_variantsobject[]required
Per-channel content definitions. Each variant sets channel and content, plus optional header, footer, and buttons for WhatsApp.

Template categories

Transactional

For order confirmations, receipts, and account updates.

{
  "name": "order_confirmation",
  "description": "Order confirmation with tracking details",
  "category": "transactional",
  "variables": [
    {"name": "customer_name", "type": "text", "required": true},
    {"name": "order_number", "type": "text", "required": true},
    {"name": "tracking_url", "type": "url", "required": true}
  ],
  "channel_variants": [
    {
      "channel": "whatsapp",
      "content": "Hi {{customer_name}}! ✅\n\nYour order #{{order_number}} has been confirmed and is being prepared for shipment.\n\nWe'll notify you when it ships!",
      "header": "Order Confirmed",
      "footer": "Thank you for your purchase",
      "buttons": [
        {
          "type": "url",
          "text": "Track Order",
          "variable_name": "tracking_url"
        }
      ]
    }
  ]
}

Authentication

For OTPs, password resets, and verification.

{
  "name": "otp_verification",
  "description": "One-time password verification",
  "category": "authentication",
  "variables": [
    {"name": "code", "type": "text", "required": true},
    {"name": "verification_url", "type": "url", "required": true}
  ],
  "channel_variants": [
    {
      "channel": "whatsapp",
      "content": "Verification Code\n\nYour verification code is:\n{{code}}\n\nClick the button below to verify your account.",
      "header": "Verification Code",
      "footer": "Secure verification",
      "buttons": [
        {
          "type": "url",
          "text": "Verify Account",
          "variable_name": "verification_url"
        }
      ]
    }
  ]
}

Marketing

For promotions, offers, and announcements.

{
  "name": "special_offer",
  "description": "Special promotional offer",
  "category": "marketing",
  "variables": [
    {"name": "customer_name", "type": "text", "required": true},
    {"name": "offer_code", "type": "text", "required": true},
    {"name": "expiry_date", "type": "text", "required": true},
    {"name": "shop_url", "type": "url", "required": true}
  ],
  "channel_variants": [
    {
      "channel": "whatsapp",
      "content": "Hi {{customer_name}}! 🎉\n\nWe have a special offer just for you!\n\nUse code: {{offer_code}}\nValid until: {{expiry_date}}\n\nDon't miss out!",
      "header": "Special Offer",
      "footer": "Limited time only",
      "buttons": [
        {
          "type": "url",
          "text": "Shop Now",
          "variable_name": "shop_url"
        }
      ]
    }
  ]
}

Using templates

Send a template by referencing its template_id and passing values for its variables in template_params. preferred_channels picks which channel variant to use.

{
  "to": "+233593152134",
  "body": "Welcome message",
  "template_id": "12345678912345",
  "template_params": {
    "customer_name": "John Doe",
    "website_url": "https://yourapp.com"
  },
  "preferred_channels": ["whatsapp", "sms"]
}

To send a template to many recipients at once with per-recipient parameters, see Bulk messaging.

Common template errors

Missing required variables

{
  "statusCode": 400,
  "message": "Template rendering failed: Required variable 'customer_name' is missing",
  "error": "Bad Request"
}

Invalid variable type

{
  "statusCode": 400,
  "message": "Invalid value for variable 'tracking_url': Must be a valid URL",
  "error": "Bad Request"
}

Template not found

{
  "statusCode": 404,
  "message": "Template 'welcome_template' not found",
  "error": "Not Found"
}

Note

Always supply every variable marked required: true. Values must match the variable's declared type — for example, a url variable must be a valid URL.

Next steps