Documentation
Sign inGet started

WhatsApp templates

Business-initiated WhatsApp sends use a pre-approved template. A template contains fixed text and variables, so a send supplies only values such as an OTP code or order number.
Bird manages the template catalog and registers its contents with WhatsApp. Catalog availability depends on the API region. The Templates page shows the templates available to the workspace and how each one renders.
The WhatsApp Templates page in the Bird dashboard: a search box with Status and Category filters above a table of active templates (bird_otp, bird_signin_alert, bird_appointment_reminder, bird_delivery_update), each row showing its Status, Name, its stocked Languages, a Category of authentication or utility, and a Bird-managed WABA

Browsing templates in the dashboard

Open Templates at WhatsApp > Templates. Search by name or filter by status and category.
Each row shows the fields you need to pick and send a template:
  • Status: whether the template is sendable overall. Bird-managed catalog templates report active. Check the language list to confirm that the required language is available.
  • Name: the display label, such as bird_otp. Send with the template's slug.
  • Language: the languages the template is registered in, such as en and pt-BR.
  • Category: authentication, utility, or marketing. The category governs how WhatsApp treats the message, which sender number we use, and, with the destination country, the price.
  • WABA: Bird-managed for templates in the managed catalog.
Click a row to open the template's detail.

What's in a template

The detail view renders the message body, variables, and buttons in a WhatsApp-style preview.
The detail also provides a cURL example for POST /v1/whatsapp/messages, using the regional host and the template's example values. Replace the API key, recipient, and variable values before sending.
The example is the fastest way to see the shape a send has to match. Over the API, the same content comes from the template's version (Reading a template's content).

Listing templates from the API

GET /v1/whatsapp/templates returns a cursor-paginated catalog. The request requires whatsapp_management read access. Use HTTP or an SDK raw-request method.
type Templates = { data: Array<{ slug: string; status: string }> };

const templates = await bird.request<Templates>({
  method: "GET",
  path: "/v1/whatsapp/templates",
});
Each entry identifies the template, its category, and its available languages. Read the live version separately for message content.
Exemple de code
{
  "available_languages": ["en", "es", "pt-BR", "..."],
  "category": "authentication",
  "default_language": "en",
  "description": "One-time passcode",
  "id": "wat_01ky4x8e4genzb7way45txfkm1",
  "languages": {
    "en": { "status": "approved" },
    "es": { "status": "approved" },
    "pt-BR": { "status": "approved" },
    "...": "..."
  },
  "name": "bird_otp",
  "on_missing_language": "fail",
  "scope": "system",
  "slug": "bird_otp",
  "status": "active"
}
The example response abbreviates the bird_otp language lists.
The fields a send depends on:
  • slug: the handle used in a send. Bird-managed template slugs begin with bird_.
  • available_languages: languages that can be sent. A paused, disabled, archived, or limited language leaves this list.
  • on_missing_language: what happens when the requested language is unavailable. Bird-managed WhatsApp templates use fail, which rejects the send rather than substituting another language.

Status and language status

Bird-managed templates report status: active. languages.<tag>.status reports WhatsApp's state for one language, such as approved, paused, or disabled.
An active template can still have an unavailable language. Use available_languages to decide whether a language is sendable.

Reading a template's content

Message content belongs to a language in the live version. Read live_version_id from the template, then request the required language:
const language = await bird.request({
  method: "GET",
  path: "/v1/whatsapp/templates/bird_order_confirmation/versions/{version_id}/languages/en",
});
The template reference accepts a slug or wat_ ID. GET …/versions/{version_id}/languages lists the version's languages without their content.
Exemple de code
{
  "category": "utility",
  "components": [
    {
      "example_parameters": [
        { "name": "ref", "text": "A1B2C3D4", "type": "text" },
        { "name": "amount", "text": "EUR 49.99", "type": "text" }
      ],
      "text": "Your order {{ref}} has been confirmed for a total of {{amount}}. Thanks for shopping with us.",
      "type": "body"
    }
  ],
  "language": "en",
  "status": "approved"
}
The send's components must match the template. example_parameters identifies each placeholder. In this example, the body parameters use name: "ref" and name: "amount". A positional template omits name and takes values in {{n}} order. Parameterized buttons have their own example_parameters.
The language category is the Meta category used for pricing. It can differ from the template's registered category if Meta reclassifies the language.
The version's variables list summarizes every placeholder with its key, type, required flag, and constraint. Named placeholders use their names as keys. Positional placeholders use their number.

Sending with a template

Name the template in the send's template object and fill its variables through components; see Sending WhatsApp messages for the full payload:
const msg = await bird.whatsapp.send({
  to: "+15551234567",
  template: {
    slug: "bird_otp",
    components: [{ type: "body", parameters: [{ type: "text", text: "123456" }] }],
  },
});
console.log(msg.id, msg.status);

Next steps