> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zavu.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Creating WhatsApp Templates

> Learn how to create and manage WhatsApp message templates for your business

WhatsApp templates are pre-approved message formats that allow you to initiate conversations with users outside the 24-hour messaging window. This guide covers how to create, submit, and manage templates.

## Overview

Templates are required for:

* Starting new conversations with users
* Re-engaging users after the 24-hour window expires
* Sending transactional notifications (order updates, appointments, etc.)

## Template Structure

A WhatsApp template consists of:

| Component | Required | Description |
| - | - | - |
| **Name** | Yes | Unique identifier (lowercase, underscores only) |
| **Language** | Yes | Language code (e.g., `en`, `es`, `pt`) |
| **Category** | Yes | UTILITY, MARKETING, or AUTHENTICATION |
| **Body** | Yes | Main message content with variables |
| **Header** | No | Text, image, video, or document |
| **Footer** | No | Short footer text |
| **Buttons** | No | Quick reply or URL buttons (max 3) |

## Creating a Template

### Via Dashboard

1. Navigate to **Senders** in your dashboard
2. Select the sender you want to create templates for
3. Go to the **Templates** tab
4. Click **Create Template**
5. Fill in the template details and submit

### Via API

<CodeGroup>
  ```typescript TypeScript theme={null}
  import Zavudev from '@zavudev/sdk';

  const zavu = new Zavudev({
    apiKey: process.env["ZAVUDEV_API_KEY"],
  });

  const template = await zavu.templates.create({
    name: 'order_confirmation',
    language: 'en',
    body: 'Hi {{1}}, your order {{2}} has been confirmed and will ship within 24 hours.',
    category: 'UTILITY',
    variables: ['customer_name', 'order_id'],
  });

  console.log('Template ID:', template.id);
  console.log('Status:', template.whatsappStatus); // "draft"
  ```

  ```python Python theme={null}
  import os
  from zavudev import Zavudev

  zavu = Zavudev(
      api_key=os.environ.get("ZAVUDEV_API_KEY"),
  )

  template = zavu.templates.create(
      name="order_confirmation",
      language="en",
      body="Hi {{1}}, your order {{2}} has been confirmed and will ship within 24 hours.",
      category="UTILITY",
      variables=["customer_name", "order_id"]
  )

  print("Template ID:", template.id)
  print("Status:", template.whatsapp_status)  # "draft"
  ```

  ```ruby Ruby theme={null}
  template = client.templates.create(
    name: "order_confirmation",
    language: "en",
    body: "Hi {{1}}, your order {{2}} has been confirmed and will ship within 24 hours.",
    category: "UTILITY",
    variables: ["customer_name", "order_id"]
  )

  puts "Template ID: #{template.id}"
  puts "Status: #{template.whatsapp_status}" # "draft"
  ```

  ```go Go theme={null}
  template, err := client.Templates.New(context.TODO(), zavudev.TemplateCreateParams{
      Name:      zavudev.String("order_confirmation"),
      Language:  zavudev.String("en"),
      Body:      zavudev.String("Hi {{1}}, your order {{2}} has been confirmed and will ship within 24 hours."),
      WhatsappCategory: zavudev.String("UTILITY"),
      Variables: []string{"customer_name", "order_id"},
  })

  fmt.Println("Template ID:", template.ID)
  fmt.Println("Status:", template.WhatsappStatus) // "draft"
  ```

  ```php PHP theme={null}
  $template = $client->templates->create([
      'name' => 'order_confirmation',
      'language' => 'en',
      'body' => 'Hi {{1}}, your order {{2}} has been confirmed and will ship within 24 hours.',
      'whatsappCategory' => 'UTILITY',
      'variables' => ['customer_name', 'order_id'],
  ]);

  echo 'Template ID: ' . $template->id . "\n";
  echo 'Status: ' . $template->whatsappStatus . "\n"; // "draft"
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.zavu.dev/v1/templates \
    -H "Authorization: Bearer $ZAVUDEV_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "order_confirmation",
      "language": "en",
      "body": "Hi {{1}}, your order {{2}} has been confirmed and will ship within 24 hours.",
      "category": "UTILITY",
      "variables": ["customer_name", "order_id"]
    }'
  ```
</CodeGroup>

## Template Variables

Use numbered placeholders for dynamic content:

```
Hi {{1}}, your order {{2}} is ready for pickup at {{3}}.
```

When sending a message, provide the variable values:

```typescript theme={null}
await zavu.messages.send({
  to: '+14155551234',
  messageType: 'template',
  content: {
    templateId: 'tmpl_abc123',
    templateVariables: {
      '1': 'John',
      '2': 'ORD-12345',
      '3': '123 Main St'
    }
  }
});
```

Templates can also use **named** placeholders (`{{customer_name}}`) and **text-header** variables. For how named vs positional formats work and how to send them, see [How Variables Work](/guides/whatsapp/templates/sending#how-variables-work).

## Template Categories

### UTILITY

For transactional messages with specific, agreed-upon information.

**Examples:**

* Order confirmations
* Shipping updates
* Appointment reminders
* Account notifications

**Cost:** Lower messaging rates

### MARKETING

For promotional content and offers.

**Examples:**

* Sales announcements
* Product recommendations
* Newsletter content
* Promotional offers

**Cost:** Higher messaging rates

### AUTHENTICATION

For one-time passwords and verification codes.

**Examples:**

* Login verification
* Two-factor authentication
* Account verification

**Cost:** Lowest messaging rates

## Adding Headers

Add a header to make your template more engaging:

```typescript theme={null}
const template = await zavu.templates.create({
  name: 'shipping_update',
  language: 'en',
  body: 'Your package {{1}} is on its way!',
  category: 'UTILITY',
  headerType: 'text',
  headerContent: 'Shipping Update',
});
```

### Header Types

| Type | Description |
| - | - |
| `text` | Plain text header |
| `image` | Image header (provide URL) |
| `video` | Video header (provide URL) |
| `document` | PDF or document header |

## Adding Buttons

Templates can include up to 3 buttons:

```typescript theme={null}
const template = await zavu.templates.create({
  name: 'order_tracking',
  language: 'en',
  body: 'Your order {{1}} has shipped!',
  category: 'UTILITY',
  buttons: [
    {
      type: 'url',
      text: 'Track Order',
      url: 'https://example.com/track/{{1}}'
    },
    {
      type: 'quick_reply',
      text: 'Contact Support'
    }
  ]
});
```

### Button Types

| Type | Description |
| - | - |
| `quick_reply` | Sends predefined response |
| `url` | Opens a URL (can include variables) |
| `phone` | Initiates a phone call |
| `request_contact_info` | Asks the recipient to share their phone number. The label is fixed by WhatsApp (**Share Contact Info**), so `text` is not required. Useful for [username contacts](/guides/whatsapp/usernames) known only by BSUID. |

```typescript theme={null}
const template = await zavu.templates.create({
  name: 'callback_request',
  language: 'en',
  body: 'Hi {{1}}, we need a phone number to schedule your callback.',
  category: 'UTILITY',
  buttons: [
    { type: 'request_contact_info' }
  ]
});
```

The recipient's answer arrives as an inbound `contact` message, and Zavu links the shared number to the contact automatically. See [Contact Info Request Messages](/guides/whatsapp/messages/request-contact-info).

## Best Practices

<CardGroup cols={2}>
  <Card title="Keep it concise" icon="compress">
    Templates have character limits. Body text should be under 1024 characters.
  </Card>

  <Card title="Use clear variables" icon="code">
    Name your variables descriptively in the documentation for easier maintenance.
  </Card>

  <Card title="Choose the right category" icon="tag">
    Incorrect categorization may lead to rejection or higher costs.
  </Card>

  <Card title="Test before production" icon="flask">
    Always test templates with your own number first.
  </Card>
</CardGroup>

## Naming Conventions

Template names must:

* Be unique within your account
* Use only lowercase letters, numbers, and underscores
* Not exceed 512 characters
* Not start with a number

**Good examples:**

* `order_confirmation_v2`
* `appointment_reminder`
* `shipping_update_en`

**Bad examples:**

* `Order Confirmation` (spaces not allowed)
* `2fa_code` (starts with number)
* `ORDER_CONFIRMATION` (uppercase not allowed)

## Next Steps

<CardGroup cols={2}>
  <Card title="Submit for Approval" icon="paper-plane" href="/guides/whatsapp/templates/approval">
    Learn how to submit templates and track approval status
  </Card>

  <Card title="Send Template Messages" icon="message" href="/guides/whatsapp/templates/sending">
    Start sending messages with your approved templates
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.