List email templates

Search Documentation

Search across all developer documentation

entities

List email templates

GET /v1/templates
Auth required api.templates.view

Returns the org's templates, newest-first: email templates and layouts (kind). Every template is written through this API, MCP or the dashboard. ?kind= narrows to one kind.

content_hash is the optimistic-concurrency token: send it back as expected_content_hash on a write to make that write conditional.

Query parameters

limit integer optional

Page size (1–200). Default 50.

cursor string optional

Opaque cursor returned from the previous page.

kind string enum optional

Only templates of this kind: email (sendable templates) or layout (wrappers a composed broadcast's body is placed into). Omitted lists both.

Responses

Errors follow the RFC 7807 problem format — see the error reference.

200 Templates, newest-first application/json
data array<object> required

Each entry in data:

slug string required

The template's name, used in the path (e.g. welcome).

name string required

Same as slug — there is no separate display-name column.

kind string enum required

email — a template a broadcast or a workflow send uses. layout — a branded wrapper with exactly one {{> content}} slot that a composed broadcast's body is placed into. A layout is never deployed to SES (deploy_state: not_applicable), never sent on its own, and does not count against the plan's template limit.

One of: email, layout

subject string | null required

The email's subject line, itself a Handlebars template. Null when the template carries none.

channel string | null required

Always null. Templates carry no channel binding in the data model; the field is kept so existing readers keep working.

content_hash string | null required

The optimistic-concurrency token. Send it back as expected_content_hash on a write to make that write conditional. It covers the BODY only, so a subject-only change does not move it.

deploy_state string enum required

Whether this content is live in the org's SES account. not_applicable for a layout, which is never deployed. pending means saved but not yet in SES — including on the response to a write of an already-deployed template, where SES is still serving the previous body. Poll GET /v1/templates/{slug} to see it settle.

One of: pending, deployed, failed, not_applicable

ses_template_name string | null required

The name the template holds in SES ({namespace}--{name}); null before it has ever deployed.

deploy_error string | null required

Why the last deploy failed. Null when nothing has.

deployed_at string<date-time> | null required

When SES last accepted this template. Null while a deploy is outstanding, including on a write whose new content has not landed.

default_topic string | null required

The topic NAME a send of this template opts recipients out of when the step names none. Resolved late, at send time, so it may name a topic that does not exist yet — requires[] on a write says whether it does.

default_consent_class string enum required

"" — marketing, the default. transactional — sanctioned lifecycle mail, which is topic-exempt.

One of: ``, transactional

variables array<string> required

The merge fields the body references, as stored on the row.

last_modified_at string<date-time> required
requires array<object> optional

What this template still needs — its default_topic, and every {{asset}} path it references — with the state of each. Present on writes only; absent on the reads, which resolve nothing.

Each entry in requires:

kind string enum required

The namespace key is looked up in. Branch on this; never parse detail.

One of: template, segment, list, topic, identity, channel, attribute, activity_property, asset

key string required

The identifier as the definition names it — a template name, a segment id or key, a from-address. Empty for a requirement about the ABSENCE of a reference: a send with no topic at all names no topic.

status string enum required

ok — resolves and is usable now. missing — nothing in this organization answers to that key. Correct the reference, or create the thing. not_ready — it exists, in a state that cannot be used yet. Usually a wait, and retrying the identical request is the move. Treating this as missing sends you hunting for a typo that is not there.

One of: ok, missing, not_ready

detail string required

The state, in the words that say which state — deploy_state=pending, member_count=null (evaluation queued). For display and logs; do not parse it.

fix string required

The call that clears this requirement, as an HTTP route where there is one and as a plain instruction where there is not (a template deploy is waited for, not called). Empty on an ok entry.

pagination object required

Fields of pagination:

has_more boolean required
next_cursor string | null optional
401 Missing, malformed, or unknown API key application/problem+json
403 Key lacks the required scope or plan limit violated application/problem+json
422 A query parameter, path value or body field failed validation. The body is a validation_failed Problem. When the refusal is about a reference — a segment key, template slug, topic or attribute name the organization does not have — it additionally carries validation_code, field, line/column, missing, candidates and next_step, so a client can correct the call without a second round of guessing. See ValidationProblem. application/problem+json
429 Per-org rate limit exceeded application/problem+json
500 Unexpected server-side failure. The code is internal_error. The request_id field can be quoted to SendOps support to investigate. application/problem+json