---
title: "Get a message template"
method: GET
path: "/v1/whatsapp/templates/{template_ref}"
tags: ["whatsapp-templates"]
---

# Get a message template

`GET /v1/whatsapp/templates/{template_ref}`

## Request

- Base URL: `https://us1.platform.bird.com`
- URL: `https://us1.platform.bird.com/v1/whatsapp/templates/{template_ref}`
- Auth: one of:
  - HTTP bearer
  - API key in cookie `bird_session`

Returns one template by its ID or slug: its lifecycle, the languages a send can currently resolve, a summary of where every language stands at Meta, and a pointer to the version that is live. Content is not here: read [a version](/docs/api/reference/get-whatsapp-template-version) for that.

## Headers

- `X-Workspace-Id` string
- `X-Organization-Id` string

## Response `200`

The requested template.

- WhatsAppTemplate: A message template: one identity holding a copy of the message per language. Each language is reviewed, priced and paused by Meta on its own, so the template's own status is an aggregate and the per-language detail is in `languages`. A version contains the content.
  - `id` string, required
  - `slug` string, required: A template's slug: what you send it by, for example `welcome-email`. Email and SMS slugs stay fixed after creation. WhatsApp slugs can change only before the first submission. A slug can contain lowercase letters, numbers, hyphens, and underscores, has to start and end with a letter or a number, and can be up to 63 characters long.
  - `slug_editable` boolean, required: Whether the slug can still be changed. False after the first submission and for built-in templates.
  - `name` string, required: A display name for the template. Nothing resolves through it, so it is safe to show wherever a human reads the template.
  - `description` string, nullable, required: What the template is for. Null when unset.
  - `scope` 'system' | 'workspace', required: Whether the template is one of our built-in templates (`system`) or one your workspace created (`workspace`).
  - `waba` string: The WhatsApp Business Account that holds this template's languages at Meta. Absent on a built-in template: those live on a WABA that Bird manages centrally rather than on your account, so it is not yours to reconcile against and is not disclosed.
  - `category` string, required: Meta's content classification for a template. - `authentication`: delivers one-time passcodes. - `utility`: delivers transaction-triggered updates (receipts, order status). - `marketing`: carries promotional content. The category determines the sender number and price. This is an open enum. Accept unrecognized values.
  - `status` 'draft' | 'pending' | 'active' | 'rejected' | 'inactive', required: Where the template stands as a whole. The same five states on every channel. - `draft`: nothing has ever gone live. - `pending`: nothing is live and at least one language is in review. - `active`: at least one language is live, so something can be sent. - `rejected`: it was reviewed and every language was refused. - `inactive`: nothing is live and nothing is in review, so content was withdrawn or was blocked before anything went live. A template with one language live is `active` even while another is still drafted or refused. Read `languages` for the state of each language and its reason. Which values a channel reports follows its review model. A channel whose content a third party reviews uses all five. On email and SMS, where content goes live on publish, a template is `draft`, `active` or `inactive`, and `pending` and `rejected` are reserved for the review stage coming to both, so a template reaching either is not a breaking change.
  - `default_language` string, required: A language tag in BCP-47 form, for example `en` or `pt-BR`.
  - `on_missing_language` 'fallback' | 'fail', required: What a send or a preview does when it asks for a language the template cannot serve. `fallback` serves the closest match instead. It tries a broader form of the same language first, so a request for `pt-BR` can be served by a stocked `pt`, and then the template's default language. A send never fails because a language is missing. `fail` rejects the send rather than serving a different language, for content where sending the wrong language is worse than not sending at all. It matches the requested tag or a broader form of it and refuses a sibling variant, so `pt-BR` is never served by `pt-PT`. A send that names no language still uses the default language. The default is per channel and stated on each channel's own field, because what a wrong-language send costs differs. Where every language is separately reviewed and separately priced, falling back silently would send content the recipient did not expect at a rate the sender did not choose.
  - `language_source_required` boolean, required: When true, a send must name a language explicitly rather than letting the template resolve one.
  - `available_languages` LanguageTag[], required: The languages a send can resolve right now: approved and not held back by Meta. It shrinks for reasons you did not cause: Meta pauses, disables, archives or limits a language and it leaves the set with nobody having edited anything. Read `languages` to see which languages exist and why one is missing.
  - `languages` object, required: Where each of the template's languages stands, keyed by BCP-47 language tag. This is the summary of the version currently in service, so a template reading `active` can still hold a rejected or paused language: the aggregate says something is sendable, and this says which. Content is not here; it lives under a version.
  - `draft_version_id` string, required
  - `live_version_id` string, required
  - `pending_version_id` string, required
  - `last_submitted_at` string, date-time, nullable, required: When this template was last submitted. Null for a pre-approved built-in template.
  - `created_at` string, date-time, nullable, required: When the template was created. Null for a built-in template, which Bird ships rather than stores.
  - `updated_at` string, date-time, nullable, required: When the template was last modified. Null for a built-in template, which Bird ships rather than stores.
  - `next` NextAction[]: What to do next with this template, given the state it is in. Each entry names one action and says why it is worth taking, so you can act on this response without working out the order yourself. Present on reads that compute it: an empty list means there is nothing to do, and the field is absent entirely on responses that do not report next actions. A `draft` template routes to opening its draft, a `pending` one to the version under review, and a `rejected` or `inactive` one to a fresh draft. The template's `status` is the aggregate over its languages, so an entry may send you to the version to see where each language actually stands.
    - `kind` string, required: What you do about this step. - `operation`: call the operation named in `operation`, then read again. - `external`: act somewhere this API does not reach, then read again. - `wait`: nothing is asked of you, so read again later. - `terminal`: nothing you do resolves this, so stop retrying. Tolerate a value you do not recognize: show the `description` and offer no action.
    - `description` string, required: A short, human-readable label for the step, suitable for display.
    - `operation` string: The operationId to call. Present only when `kind` is `operation`. The operation's own schema says how to call it; this says only which one, and what to address it with.
    - `params` object: The parameters that address the operation, by name: `{"sender_id": "…"}` for an operation on `/v1/sms/senders/{sender_id}/requirements`. A parameter the operation takes in its query string is given the same way, so an operation addressed as `?subject_id=` carries `{"subject_id": "…"}`. Every parameter the call needs is here, whether its value came from the thing you were acting on or is fixed for this step, so you can make the call from this object alone. Present only when `kind` is `operation` and the operation names a subject. A request body, when the operation takes one, is described by the operation's own schema and never appears here.
    - `url` string, uri: A URL to open. Present only when `kind` is `external`, and only when the step has one. An external step whose `description` says to go and do something with no URL to open is normal.

## Other responses

- `400`: Bad request
- `401`: Authentication required
- `403`: Insufficient permissions
- `404`: Resource not found
- `422`: The request has invalid field values, violates a business rule, or carries a query parameter the endpoint does not declare. Field validation errors use `type: validation_error` and include the affected fields in `details`. Business-rule errors identify the failed rule in `type`.
- `429`: Rate limit exceeded
- `500`: Internal server error

---

[API](https://skmtc.dev/messagebird/apis/bird-api.md) · [All operations](https://skmtc.dev/messagebird/apis/bird-api/llms.txt) · [OpenAPI document](https://skmtc.dev/messagebird/apis/bird-api/revisions/6dfce1179799?raw)
