---
title: "List email template versions"
method: GET
path: "/v1/email/templates/{template_ref}/versions"
tags: ["email-templates"]
---

# List email template versions

`GET /v1/email/templates/{template_ref}/versions`

## Request

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

Returns the template's versions as a cursor page (the current draft plus all published versions), newest first. Each entry names its languages without returning their content. Templates retain every language of every submitted version, so listing their content would grow the response with the template's history. Read a single version for its content.

## Query parameters

- `limit` integer
- `starting_after` string
- `ending_before` string

## Headers

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

## Response `200`

The template's versions.

- EmailTemplateVersionList
  - `data` EmailTemplateVersionSummary[], required: One page of the template's versions, newest first. Each entry describes a version and which languages it holds. Read a single version if you want its actual content.
    - `id` string, required
    - `template_id` string, required
    - `version_number` integer, nullable: Sequential published-version number (1, 2, 3…). Null while the version is a draft.
    - `status` 'draft' | 'published' | 'archived', required: Whether this version is still being edited or has been published. It records the version's publication history: a version that a later one replaced stays `published`. The template's `live_version_id` names the version a send resolves to now. `archived` is reserved and no version carries it yet. Version retirement will produce it, so it is declared here ahead of that feature: a client written against this list today keeps working when the first archived version arrives, rather than the value's arrival being a breaking change.
    - `revision` integer, required: The version's revision counter.
    - `variables` TemplateVariable[], required: Input definitions this version uses, including caller parameters and reserved Bird inputs. An entry with `system` false is yours to send in `template.parameters`. An entry with `system` true names a reserved Bird key; supported paths receive Bird values. A draft can also report unsupported reserved paths, including bare `bird`, whose `constraint` explains that no Bird value fills them. Correct these paths before publishing. Naming a reserved Bird key in a send is rejected with a `422`. The list combines all the languages, because languages do not have to use the same inputs: if the English body uses `discount_code` and the French body uses `shipping_date`, both appear here. A send requires values only for the caller parameters referenced by its resolved language. Preview each language to see its inputs. Extra parameters are ignored; omitting a caller parameter referenced by the resolved language returns a `422` naming it.
      - `key` string, required: The key this slot is filled by. When `system` is true it is the reserved `bird` key or a dotted path beneath it, such as `bird.contact.first_name`, and naming it in a send is rejected. Otherwise, on email and SMS it is the key you set in the send's `parameters` object, and on WhatsApp the `name` you repeat on the matching parameter inside `components`, or, for a template whose placeholders are positional, the position itself as `1`, `2` and so on.
      - `type` string, required: The value type this slot accepts. Built-in SMS templates use typed slots (`code`, `amount` and the rest), each of which rejects a value that does not match its `constraint`. Email, WhatsApp and workspace SMS templates use `text`. Workspace SMS parameters must be scalar values. Open enum: treat an unrecognized value as a future type rather than an error.
      - `required` boolean, required: Whether the send must supply this variable. Omitting a required value returns `422` on email, SMS, and WhatsApp sends. Always false when `system` is true, because you do not supply that slot's value.
      - `constraint` string, required: A plain-language description of what values this variable accepts. When `system` is true it names where Bird takes the value from instead, because there is no value for you to send.
      - `sensitive` boolean: Whether this slot's value is redacted from stored message content. A placeholder replaces the sensitive value in message history; transport queues can still carry the text needed for delivery.
      - `system` boolean: Whether the value comes from Bird rather than from the send. Absent means false. Only email templates have system slots, identified by the reserved `bird` key or a dotted path beneath it; every SMS and WhatsApp slot is yours to fill. A draft can also name a reserved key no Bird value fills, including `bird` itself: `constraint` says so, and publishing that draft is rejected.
    - `default_language` string, required: A language tag in BCP-47 form, for example `en` or `pt-BR`.
    - `available_languages` LanguageTag[], required: The languages this version holds, as BCP-47 tags: the keys its `languages` map would return, without the content itself.
    - `created_at` string, date-time, required: When this version was created.
    - `published_at` string, date-time, nullable: When this version was published, or null if it has not been published.
    - `updated_by` Actor
      - `id` string, required: Actor identifier.
      - `type` string, required: New actor types may be added. Treat unrecognized values as future types, not errors. - `user`: a member's own session. - `api_key`: a workspace API key. - `oauth_token`: a token issued to a caller on a member's behalf. - `system`: an action we perform without a customer actor. - `sso`: an organization's SSO connection. - `service_account`: a workspace's connected Integration acting with no member behind it. - `automation`: an automation execution in your workspace.
      - `display_name` string, nullable: The label the actor is shown under: typically a member's name or email address, or the API key's name. Null when it could not be resolved.
  - `next_cursor` string, nullable, required: Cursor for the next page. Pass back as `starting_after` to advance forward. `null` when no next page exists.
  - `prev_cursor` string, nullable, required: Cursor for the previous page. Pass back as `ending_before` to step backward. `null` when no previous page exists.
  - `refresh_cursor` string, nullable, required: Refresh anchor, the first row of this response. Pass back as `ending_before` to fetch what precedes it in the current sort order. On a newest-first sort those are the items that have appeared since; on any other sort they are the items that sort earlier, so refreshing such a list means re-fetching it instead. Non-`null` whenever `data` is non-empty; `null` only on an empty page. Distinct from `prev_cursor`.

## 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)
