# Get a version's language

`GET /v1/whatsapp/templates/{template_ref}/versions/{version_id}/languages/{language}`

Returns one language of one version: its content blocks, what this version's submission did with it, and everything Meta holds about it: review outcome and category.

## Code samples

### TypeScript

```ts
const language = await bird.whatsapp.templates.versions.languages.get(
  "bird_otp",
  "wav_01ky4x8e4genzb7way45txfkm1",
  "nl-BE",
);
for (const component of language.components) console.log(component.type);
```

### Python

```py
language = client.whatsapp.templates.versions.languages.get(
    "bird_otp", "wav_01ky4x8e4genzb7way45txfkm1", "nl-BE"
)
for component in language.components:
    print(component.type)
```

### Go

```go
language, err := client.Whatsapp.Templates.Versions.Languages.Get(context.Background(), "bird_otp", "wav_01ky4x8e4genzb7way45txfkm1", "nl-BE")
if err != nil {
	log.Fatal(err)
}
fmt.Println(language.Language, len(language.Components))
```

### PHP

```php
$language = $bird->whatsapp->templates->versions->languages->get('bird_otp', 'wav_01ky4x8e4genzb7way45txfkm1', 'nl-BE');
foreach ($language->getComponents() ?? [] as $component) {
    echo $component->getType(), "\n";
}
```

### CLI

```sh
bird whatsapp templates versions languages get <template-ref> <version-id> <language>
```

### cURL

```sh
curl -X GET "https://us1.platform.bird.com/v1/whatsapp/templates/{template_ref}/versions/{version_id}/languages/{language}" \
  -H "Authorization: Bearer $TOKEN"
```

## Example response `200`

```json
{
  "language": "pt-BR",
  "components": [
    {
      "type": "body",
      "format": "text",
      "text": "Your verification code is {{1}}.",
      "code_expiration_minutes": 60,
      "example_parameters": [
        {
          "type": "text",
          "text": "123456",
          "url": "https://www.example.com/holiday/banner.jpg",
          "name": "first_name"
        }
      ],
      "buttons": [
        {
          "type": "url",
          "otp_type": "copy_code",
          "text": "Copy code",
          "url": "https://www.example.com/orders/{{1}}",
          "phone_number": "+14155550100",
          "example_parameters": [
            {
              "type": "text",
              "text": "123456",
              "url": "https://www.example.com/holiday/banner.jpg",
              "name": "first_name"
            }
          ]
        }
      ],
      "cards": [
        {
          "components": [
            {
              "type": "header",
              "format": "image",
              "text": "Chronograph, brown leather",
              "example_parameters": [
                {
                  "text": "123456",
                  "url": "https://www.example.com/holiday/banner.jpg",
                  "name": "first_name"
                }
              ],
              "buttons": [
                {
                  "type": "url",
                  "otp_type": "copy_code",
                  "text": "Copy code",
                  "url": "https://www.example.com/orders/{{1}}",
                  "phone_number": "+14155550100"
                }
              ]
            }
          ]
        }
      ]
    }
  ],
  "status": "approved",
  "revision": 4,
  "content_hash": "sha256:9f2c4e1a7b03d85fbc6e29d417a05e8c3b1d9f76a2e4c018d53b7f9a6c2e18d4",
  "category": "authentication",
  "previous_category": "authentication",
  "quality": {
    "current_score": "green",
    "previous_score": "green",
    "updated_at": "2026-07-26T16:41:00Z"
  },
  "rejection": {
    "category": "invalid_format",
    "reason": "Parameters are adjacent.",
    "recommendation": "Add text between the two parameters."
  },
  "error": {
    "description": "component of type HEADER is missing expected field(s)",
    "meta_error_code": "2388043"
  },
  "submitted_at": "2026-07-26T16:40:00Z",
  "approved_at": "2026-07-21T08:15:00Z",
  "updated_at": "2026-07-26T16:41:00Z",
  "updated_by": "usr_01krdgeqcxet5s7t44vh8rt9mg"
}
```

## Path parameters

- `template_ref` (string): Template ID (`wat_` prefix) or slug. A value that parses as a valid ID resolves by ID; any other value resolves as a slug.
- `version_id` (string): ID of the template version (`wav_` prefix), as returned by the version list.
- `language` (string): The language, as a BCP-47 tag. Case and separator variance is accepted and normalised, and the canonical form is returned.

## Response body

- `language` (string, required): The canonical tag this language is addressed by.
- `components` (array of object, required): This language's content blocks, in display order, exactly as submitted or as they stand in the draft.
- `components.type` (string, required)

  The content block's type within the template.

  Possible values (may grow over time): `header`, `body`, `footer`, `buttons`, `carousel`
- `components.format` (string)

  The header block's content type. Present on a header block. A `text` header carries a line of copy. The `image`, `video`, `gif`, and `document` formats each show a file whose address is in the block's `example_parameters`. The `location` format shows a map. It carries no content because the coordinates belong to the message rather than the template.

  Possible values (may grow over time): `text`, `image`, `video`, `gif`, `document`, `location`
- `components.text` (string): The block's text content, with any variable placeholders shown inline. Present when the block carries text. An authentication template's body and footer are written by WhatsApp from the two settings below rather than by you, so their text is absent until the language has been submitted and WhatsApp has supplied it.
- `components.add_security_recommendation` (boolean): Whether this authentication template's body ends with WhatsApp's advice not to share the code. Present on an authentication template's body block.
- `components.code_expiration_minutes` (integer): How long the passcode stays valid, which WhatsApp states in this footer. Present on an authentication template's footer block. Omitting it on a write leaves the footer off entirely.
- `components.example_parameters` (array of object): Example values for this block's variables, in placeholder order (one per `{{n}}`). Use them to see what a filled message looks like. Present when the block has variables.
- `components.example_parameters.type` (string, required): The kind of value this parameter accepts.
- `components.example_parameters.text` (string): An example value for a text parameter. Present when `type` is `text`.
- `components.example_parameters.url` (string): The address of the file a media header shows, as it was given when the header was authored rather than WhatsApp's copy of it. Present when `type` is `image`, `video`, `gif` or `document`.
- `components.example_parameters.name` (string): The named placeholder this example fills. Present whenever the template declares named parameters, which is what a send must name; absent only for a positional template, whose values go in `{{n}}` order.
- `components.buttons` (array of object): The buttons attached to this block. Present when the block carries buttons.
- `components.buttons.type` (string, required)

  The button's behavior.

  - `url`: opens a link.
  - `quick_reply`: sends its own label back to you as an inbound message.
  - `phone_number`: dials the number it carries.
  - `otp`: copies a one-time passcode. It belongs only on an authentication
    template, and that template takes no other button type.
  - `copy_code`: copies a coupon code to the recipient's clipboard. It
    belongs only on a marketing template, which takes at most one.
  - `request_contact_info`: asks the recipient to share the phone number
    their WhatsApp account carries. It belongs only on a utility or
    marketing template, as that template's only button.

  This is an open enum. Accept unrecognized values.

  Possible values (may grow over time): `url`, `quick_reply`, `phone_number`, `otp`, `copy_code`, `request_contact_info`
- `components.buttons.otp_type` (string)

  How the recipient receives the one-time passcode. Present on authentication-template OTP buttons.

  Possible values (may grow over time): `copy_code`
- `components.buttons.text` (string): The button's label. Absent on an authentication template's passcode button until the language has been submitted, since WhatsApp writes that label itself. Absent on a `request_contact_info` draft for a related reason: WhatsApp fixes that label, so a draft that carried it reads back without it. Once the language is submitted, this carries the label WhatsApp wrote, which is `Share Contact Info` in every language today.
- `components.buttons.url` (string): The address the button opens, with any variable placeholder shown inline. Present on link buttons.
- `components.buttons.phone_number` (string): The number the button dials. Present on dial buttons.
- `components.buttons.example_parameters` (array of object): Example values for this button's variables, in placeholder order. Present when the button address has variables, and on a `copy_code` button, where the single value is the sample coupon code WhatsApp reviewed.
- `components.buttons.example_parameters.type` (string, required): The kind of value this parameter accepts.
- `components.buttons.example_parameters.text` (string): An example value for a text parameter. Present when `type` is `text`.
- `components.buttons.example_parameters.url` (string): The address of the file a media header shows, as it was given when the header was authored rather than WhatsApp's copy of it. Present when `type` is `image`, `video`, `gif` or `document`.
- `components.buttons.example_parameters.name` (string): The named placeholder this example fills. Present whenever the template declares named parameters, which is what a send must name; absent only for a positional template, whose values go in `{{n}}` order.
- `components.cards` (array of object): The cards this block scrolls through, in display order. Present on a `carousel` block.
- `components.cards.components` (array of object, required): This card's content blocks, in display order.
- `components.cards.components.type` (string, required)

  The card block's type.

  Possible values (may grow over time): `header`, `body`, `buttons`
- `components.cards.components.format` (string)

  The card header's content type. Present on a card's header block.

  Possible values (may grow over time): `image`, `video`
- `components.cards.components.text` (string): The block's text content, with any variable placeholders shown inline.
- `components.cards.components.example_parameters` (array of object): Example values for this block's variables, in placeholder order.
- `components.cards.components.example_parameters.type` (string, required): The kind of value this parameter accepts.
- `components.cards.components.example_parameters.text` (string): An example value for a text parameter. Present when `type` is `text`.
- `components.cards.components.example_parameters.url` (string): The address of the file a media header shows, as it was given when the header was authored rather than WhatsApp's copy of it. Present when `type` is `image`, `video`, `gif` or `document`.
- `components.cards.components.example_parameters.name` (string): The named placeholder this example fills. Present whenever the template declares named parameters, which is what a send must name; absent only for a positional template, whose values go in `{{n}}` order.
- `components.cards.components.buttons` (array of object): The buttons this card carries. Present on a card's buttons block.
- `components.cards.components.buttons.type` (string, required)

  The button's behavior.

  - `url`: opens a link.
  - `quick_reply`: sends its own label back to you as an inbound message.
  - `phone_number`: dials the number it carries.
  - `otp`: copies a one-time passcode. It belongs only on an authentication
    template, and that template takes no other button type.
  - `copy_code`: copies a coupon code to the recipient's clipboard. It
    belongs only on a marketing template, which takes at most one.
  - `request_contact_info`: asks the recipient to share the phone number
    their WhatsApp account carries. It belongs only on a utility or
    marketing template, as that template's only button.

  This is an open enum. Accept unrecognized values.

  Possible values (may grow over time): `url`, `quick_reply`, `phone_number`, `otp`, `copy_code`, `request_contact_info`
- `components.cards.components.buttons.otp_type` (string)

  How the recipient receives the one-time passcode. Present on authentication-template OTP buttons.

  Possible values (may grow over time): `copy_code`
- `components.cards.components.buttons.text` (string): The button's label. Absent on an authentication template's passcode button until the language has been submitted, since WhatsApp writes that label itself. Absent on a `request_contact_info` draft for a related reason: WhatsApp fixes that label, so a draft that carried it reads back without it. Once the language is submitted, this carries the label WhatsApp wrote, which is `Share Contact Info` in every language today.
- `components.cards.components.buttons.url` (string): The address the button opens, with any variable placeholder shown inline. Present on link buttons.
- `components.cards.components.buttons.phone_number` (string): The number the button dials. Present on dial buttons.
- `components.cards.components.buttons.example_parameters` (array of object): Example values for this button's variables, in placeholder order. Present when the button address has variables, and on a `copy_code` button, where the single value is the sample coupon code WhatsApp reviewed.
- `components.cards.components.buttons.example_parameters.type` (string, required): The kind of value this parameter accepts.
- `components.cards.components.buttons.example_parameters.text` (string): An example value for a text parameter. Present when `type` is `text`.
- `components.cards.components.buttons.example_parameters.url` (string): The address of the file a media header shows, as it was given when the header was authored rather than WhatsApp's copy of it. Present when `type` is `image`, `video`, `gif` or `document`.
- `components.cards.components.buttons.example_parameters.name` (string): The named placeholder this example fills. Present whenever the template declares named parameters, which is what a send must name; absent only for a positional template, whose values go in `{{n}}` order.
- `status` (string)

  What this submission did with this language. Absent on a draft, which has not been submitted. On a superseded version this is history: how that submission went. It does not report whether the language is sendable now.

  Possible values (may grow over time): `approved`, `pending`, `rejected`, `paused`, `disabled`, `in_appeal`, `pending_deletion`, `limit_exceeded`, `archived`, `deleted`, `submit_failed`, `outcome_unknown`
- `revision` (integer, required): This language's write counter, incremented every time its content changes. It sits at 1 on content that has never been written through this API, which is every built-in template's language.
- `content_hash` (string, required)
- `category` (string)

  The category Meta is applying to this language, which is what messages from it are priced at.

  Possible values (may grow over time): `authentication`, `utility`, `marketing`
- `previous_category` (string)

  The category this language held before Meta moved it.

  Possible values (may grow over time): `authentication`, `utility`, `marketing`
- `quality` (object): Meta's quality rating for this language. Present only on the version currently in service, and only once Meta has rated it.
- `quality.current_score` (string, required)

  Meta's rating for this language as of `updated_at`.

  Possible values (may grow over time): `green`, `yellow`, `red`, `unknown`
- `quality.previous_score` (string)

  The rating this language held before the most recent change. Absent when Meta has rated it only once. Usually differs from `current_score`, but Meta sometimes reports both as the same value, so compare timestamps rather than assuming a transition.

  Possible values (may grow over time): `green`, `yellow`, `red`, `unknown`
- `quality.updated_at` (string, required): When the rating last changed. A re-evaluation that lands on the same rating does not move it, so this answers how long the language has held its current rating.
- `rejection` (object): Why Meta refused this content, present when `status` is `rejected`. Absent otherwise.
- `rejection.category` (string)

  Meta's own classification of the refusal.

  Possible values (may grow over time): `abusive_content`, `incorrect_category`, `invalid_format`, `scam`, `tag_content_mismatch`
- `rejection.reason` (nullable string): Meta's detail about the refusal, passed through unmodified.
- `rejection.recommendation` (nullable string): Meta's suggested fix, the only thing it says about how to make the content acceptable. Meta sends it for some refusals and not others.
- `error` (object): Why the submission did not complete, present when `status` is `submit_failed` or `outcome_unknown`. Absent otherwise, including on a rejection, whose reason is in `rejection`.
- `error.description` (string, required): Human-readable explanation of why the submission did not complete.
- `error.meta_error_code` (nullable string): WhatsApp's most specific code for the refusal: its error subcode when it sent one, otherwise its top-level code. Opaque, treat it as a string. Absent when the failure was Bird's own verdict rather than a WhatsApp refusal.
- `submitted_at` (nullable string, required): When this content was submitted to Meta. Null on a draft, which has not been submitted, and null for a built-in template's language, which Bird ships already approved rather than submitting on your behalf.
- `approved_at` (nullable string): When Meta approved this exact content. It is a permanent mark on the content rather than a status, so a later pause or archival does not clear it. Null for a built-in template's language, whose approval predates Bird holding a date for it.
- `updated_at` (nullable string, required): When this language last changed. Null for a built-in template's language, which Bird ships rather than stores.
- `updated_by` (nullable string): The workspace member who last wrote this language. Always null for a built-in template's language: nobody in the workspace authored it.

## Related resources

- [Should I use a Bird SDK or call the API directly?](/explained/platform/should-i-use-an-sdk-or-call-the-api-directly) (answer)
- [Build your first integration](/learn/paths/integration) (course)
- [Send your first email](/docs/get-started/send-your-first-email) (docs)

[Get an implementation brief](/learn/workspace?topic=api-basics)
