---
title: "Create a template"
method: POST
path: "/v1/templates"
tags: ["Templates"]
---

# Create a template

`POST /v1/templates`

## Request

- Base URL: `https://smtpfa.st/api`
- URL: `https://smtpfa.st/api/v1/templates`
- Auth: HTTP bearer

Create a template as a draft. Publish it with POST /v1/templates/{id}/publish before sending with it. Same body as Resend's create template; markdown, preview_text and category are SMTPfast additions. Requires the email:send scope.

## Request body

- CreateTemplateRequest: Requires html, or markdown (an SMTPfast addition).
  - `name` string, required
  - `alias` string, nullable: A second handle, unique in the team, that works wherever the id does.
  - `from` string, nullable: Default sender, e.g. "Acme <orders@acme.com>". A send can override it.
  - `subject` string, nullable: Default subject. Can use variables. A send can override it.
  - `reply_to` union: Default Reply-To address or addresses. A send can override it.
    - string
    - string[]
  - `html` string: The HTML body. Variables are written {{{KEY}}}, optionally with an inline fallback: {{{KEY|default}}}.
  - `text` string, nullable: Plain-text body. When left out, the text part is generated from the HTML at send time. Exactly "" stops that, as in Resend; the email then carries an empty plain-text alternative.
  - `markdown` string, nullable: Not in Resend. A Markdown body, rendered into SMTPfast's email layout. Used when html is empty.
  - `preview_text` string, nullable: Not in Resend. The inbox preview line, put into the email as a hidden first line.
  - `category` string, nullable: Not in Resend. A label for grouping templates in the dashboard.
  - `variables` TemplateVariable[]
    - `id` string
    - `key` string, required: Use it in the content as {{{KEY}}}. Letters, digits and underscores. FIRST_NAME, LAST_NAME, EMAIL, UNSUBSCRIBE_URL, RESEND_UNSUBSCRIBE_URL, contact and this are reserved.
    - `type` 'string' | 'number', required
    - `fallback_value` union: Used when a send gives no value. Must match the type. Without one, every send must pass a value for this variable or it answers 422.
      - string
      - number
    - `created_at` string, date-time
    - `updated_at` string, date-time

## Response `201`

Template created as a draft

- TemplateRef: Resend's { id, object }. Create, update and publish also return the fields below (not in Resend): updated_at is the revision that write set, to pass as expected_updated_at next time.
  - `id` string
  - `object` string
  - `updated_at` string, date-time: Not in Resend. The revision this write created.
  - `status` 'draft' | 'published': Not in Resend.
  - `published_at` string, date-time, nullable: Not in Resend.
  - `has_unpublished_versions` boolean: Not in Resend.

## Other responses

- `400`: Bad request - check your payload
- `401`: Invalid or missing API key
- `403`: Forbidden - domain not verified or insufficient permissions
- `409`: Conflict - the resource already exists or changed meanwhile
- `422`: The request is well formed but cannot be carried out in the current state, for example an unpublished template
- `429`: Rate limit exceeded - retry after the period indicated in the Retry-After header
- `500`: Internal server error

---

[API](https://skmtc.dev/smtpfa/apis/smtpfast-api.md) · [All operations](https://skmtc.dev/smtpfa/apis/smtpfast-api/llms.txt) · [OpenAPI document](https://skmtc.dev/smtpfa/apis/smtpfast-api/revisions/79dda742f53e?raw)
