# List email templates

`GET /v1/email/templates`

Returns a paginated list of email templates, newest first.

The list covers both the workspace's own templates and our built-in `system` templates. Use
`scope` to get only one of the two, or leave it out to get both. When you leave it out, the
workspace's own templates come first, newest first, and our built-in templates fill the rest of
the list once the workspace's templates run out.

Filter further by category or authoring format, or search with `q`, a case-insensitive substring
match against the template's slug, name, and description.

Our built-in templates come in five visual themes. Each theme ships its own set of eight
emails, and the sets overlap only partly. Use `theme` to see one of them. A template your
workspace authored has no theme, so naming one returns our built-ins alone.

## Code samples

### TypeScript

```ts
for await (const tpl of bird.email.templates.list({ scope: "workspace" })) {
  console.log(tpl.slug, tpl.name);
}
```

### Python

```py
for template in client.email.templates.list(scope="workspace"):
    print(template.slug, template.name)
```

### Go

```go
for tpl, err := range client.Email.Templates.List(context.Background(), bird.EmailTemplatesListParams{Scope: "workspace"}) {
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(*tpl.Slug, tpl.Name)
}
```

### PHP

```php
foreach ($bird->email->templates->list(['scope' => 'workspace']) as $template) {
    echo $template->getSlug(), ' ', $template->getName(), "\n";
}
```

### CLI

```sh
bird email templates list
```

### cURL

```sh
curl -X GET "https://us1.platform.bird.com/v1/email/templates" \
  -H "Authorization: Bearer $TOKEN" \
  --url-query "limit=25"
```

## Example response `200`

```json
{
  "data": [
    {
      "id": "emt_01krdgeqcxet5s7t44vh8rt9mg",
      "workspace_id": "ws_01krdgeqcxet5s7t44vh8rt9mg",
      "slug": "welcome-email",
      "name": "Welcome email",
      "scope": "system",
      "status": "active",
      "category": "transactional",
      "source": "html",
      "theme": "arcane",
      "draft_version_id": "emv_01krdgeqcxet5s7t44vh8rt9mg",
      "live_version_id": "emv_01krdgeqcxet5s7t44vh8rt9mg",
      "published_version_id": "emv_01krdgeqcxet5s7t44vh8rt9mg",
      "available_languages": [
        "en"
      ],
      "default_language": "pt-BR",
      "languages": {
        "en": {
          "status": "live"
        },
        "de": {
          "status": "draft"
        }
      }
    }
  ],
  "next_cursor": "eyJ2IjoxLCJzIjoiXCIyMDI2LTA1LTI1VDE0OjAzOjEwWlwiIiwiaSI6IjAxOTJmM2IxLTRjN2UtN2EyYi05ZDYxLThmM2E1YzJlN2I0MCJ9",
  "prev_cursor": null,
  "refresh_cursor": "eyJ2IjoxLCJzIjoiXCIyMDI2LTA1LTI1VDE2OjQyOjAxWlwiIiwiaSI6IjAxOTJmM2IxLTllMDQtN2NkMy1iODE3LTJhNmY0ZDFjOGUwOSJ9"
}
```

## Query parameters

- `scope` (string)

  Filter by who owns the template. Use `system` for our built-in templates and `workspace` for the ones your workspace created. Leave it out to get both.

  Possible values: `system`, `workspace`
- `category` (string)

  Return only `transactional` or `marketing` templates; omit to return both categories.

  Possible values: `transactional`, `marketing`
- `source` (string)

  Return only templates authored in this format.

  Possible values (may grow over time): `html`
- `theme` (string)

  Filter by the visual theme a built-in template is designed in. Only our built-in templates have a theme, so naming one returns built-ins alone.

  Possible values: `arcane`, `barebone`, `matte`, `protocol`, `studio`
- `q` (string): A case-insensitive substring search across the template's slug, name, and description.
- `limit` (integer): Maximum number of items to return per page.
- `starting_after` (string): Cursor from the `next_cursor` field of a previous list response. Returns items immediately after the cursor position in the current sort order.
- `ending_before` (string): Cursor from the `prev_cursor` or `refresh_cursor` field of a previous list response. Returns items immediately before the cursor position in the current sort order. `prev_cursor` returns the preceding page. `refresh_cursor` anchors at the first row of that response, which on a newest-first sort is how to fetch the items that have appeared since.

## Response body

- `data` (array of object, required): Page of email templates.
- `data.id` (string, required): Template ID.
- `data.workspace_id` (nullable string, required): The workspace that owns the template. Null for a built-in `system` template, which no workspace owns.
- `data.slug` (string, required): The name you send the template by. You can use either the slug or the id when you send. It never changes after the template is created. A built-in `system` template's slug always starts with `bird_`.
- `data.name` (string, required): The template's display name, shown wherever the template is listed. You can change it any time. It defaults to the slug if you do not set one.
- `data.description` (nullable string, required): What the template is for, in your own words. Null if you have not set one.
- `data.scope` (string, required)

  Whether the template is one of our built-in templates (`system`) or one your workspace created (`workspace`). Every SMS template is `system`.

  Possible values: `system`, `workspace`
- `data.status` (string, 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.

  This summary answers whether the template is usable at all. A template with
  one language live is `active` even while another is still drafted or refused.
  Read `languages` to determine the state of each language and its reason.

  Which of the five a template can reach follows its channel's review model. A
  channel whose content a third party reviews reaches all five; one whose
  content goes live on publish moves between `draft`, `active` and `inactive`.

  Open enum: treat a value you do not recognize as a new one rather than as
  an error.

  Possible values (may grow over time): `draft`, `pending`, `active`, `rejected`, `inactive`
- `data.category` (string, required)

  Whether the template is for `transactional` email or `marketing` email.

  Possible values: `transactional`, `marketing`
- `data.source` (string, required)

  The authoring format the template is written in, fixed at creation. `html` is finished markup you provide, optionally personalized with Liquid.

  Possible values (may grow over time): `html`
- `data.theme` (nullable string, required): The visual theme a built-in template is designed in, or null for a template your workspace authored (which has no theme).
- `data.draft_version_id` (nullable string, required): The current editable draft version. Null for a built-in `system` template, which has no draft.
- `data.live_version_id` (nullable string, required): The version a send resolves to, or null if the template has never been published.
- `data.published_version_id` (nullable string, required): Deprecated: use `live_version_id` instead, which carries the same value.
- `data.live_version_number` (nullable integer, required): The live version's sequential number (1, 2, 3…), the same one version history reports, or null if the template has never been published. A built-in `system` template is permanently published as version 1. A rollback moves it backwards, because it names the version that is live rather than how many exist.
- `data.available_languages` (array of string, required): The languages this template currently supports for sending, as BCP-47 tags. Empty until the template is published, because sends serve published content. This set may shrink for reasons other than editing, so read it rather than assuming it matches what was published.
- `data.default_language` (string, required): The language the draft defaults to. Read this language's content when you have no particular preference for which one you want.
- `data.languages` (object, required): Every language this template has, keyed by language tag, each with its state. Enough to show which templates need attention in a list without a request per row.
- `data.last_submitted_at` (nullable string, required): When this template was last submitted. Null if it never has been. Only submitting moves this timestamp, so a rollback keeps reporting the last real submit.
- `data.created_at` (nullable string, required): When the template was created. Null for a built-in `system` template.
- `data.updated_at` (nullable string, required): When the template was last modified. Null for a built-in `system` template.
- `next_cursor` (nullable string, required): Cursor for the next page. Pass back as `starting_after` to advance forward. `null` when no next page exists.
- `prev_cursor` (nullable string, required): Cursor for the previous page. Pass back as `ending_before` to step backward. `null` when no previous page exists.
- `refresh_cursor` (nullable string, 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`.

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