API reference
Templates API
Reference for creating, listing, retrieving, updating, publishing, duplicating and deleting email templates.
The templates API manages the reusable emails of the project that owns your API key. Every endpoint needs a full_access key. For variables, drafts and sending with a template, see Templates.
In every path, {identifier} is either the template ID or its alias.
The template object
{
"object": "template",
"id": "jt5n7c2x9m4q8r1v6w3y0z2b",
"name": "Order shipped",
"alias": "order-shipped",
"status": "published",
"subject": "Your order {{{ORDER_ID}}} has shipped",
"html": "<p>Hi {{{FIRST_NAME|there}}},</p><p>Order {{{ORDER_ID}}} is on its way.</p>",
"text": null,
"from": "Acme <orders@mail.yourcompany.com>",
"reply_to": null,
"variables": [
{ "key": "ORDER_ID", "type": "string", "fallback_value": null },
{ "key": "FIRST_NAME", "type": "string", "fallback_value": "there" }
],
"published_at": "2026-11-14T10:10:00.000Z",
"created_at": "2026-11-14T10:00:00.000Z",
"updated_at": "2026-11-14T10:09:00.000Z",
"has_unpublished_versions": false,
"current_version_id": "jt5n7c2x9m4q8r1v6w3y0z2b-1794650940000"
}The content fields show the draft. status is published once the template has been published at least once, and draft before that. has_unpublished_versions is true when the draft differs from the live version.
Create a template
Creates a draft.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | 1 to 200 characters. |
html | string | Yes | The HTML body, with optional variables. |
alias | string | No | Lowercase letters, digits, hyphen and underscore, up to 100 characters. Unique in the project. |
subject | string | No | Up to 998 characters. |
from | string | No | Default sender. |
reply_to | string or string[] | No | Default reply-to. |
text | string | No | The plain-text body. |
variables | object[] | No | Up to 50 of { key, type, fallback_value }. key is letters, digits and underscore, up to 50 characters. type is string or number. |
curl -X POST https://api.sooner.dev/templates \
-H "Authorization: Bearer $SOONER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Order shipped",
"alias": "order-shipped",
"subject": "Your order {{{ORDER_ID}}} has shipped",
"html": "<p>Order {{{ORDER_ID}}} is on its way.</p>",
"variables": [{ "key": "ORDER_ID", "type": "string" }]
}'{ "object": "template", "id": "jt5n7c2x9m4q8r1v6w3y0z2b" }Notable errors: missing_required_field when name or html is missing, and validation_error when the alias is already used.
List templates
Returns the project's templates, newest first. Accepts limit and after. See Pagination.
curl "https://api.sooner.dev/templates?limit=10" \
-H "Authorization: Bearer $SOONER_API_KEY"The response is { "object": "list", "data": [ ... ], "has_more": false }, where each item is a template object.
Retrieve a template
Returns one template object. Notable errors: not_found.
Update a template
Changes the draft. It accepts the same fields as create, all optional, and only the fields you send change. A variables array replaces the whole list. Sends keep using the published version until you publish.
curl -X PATCH https://api.sooner.dev/templates/order-shipped \
-H "Authorization: Bearer $SOONER_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "subject": "Order {{{ORDER_ID}}} is on its way" }'{ "object": "template", "id": "jt5n7c2x9m4q8r1v6w3y0z2b" }Notable errors: validation_error when the new alias is taken, not_found.
Publish a template
Makes the current draft the live version. A publish can take up to about 30 seconds to be used by sends.
curl -X POST https://api.sooner.dev/templates/order-shipped/publish \
-H "Authorization: Bearer $SOONER_API_KEY"{ "object": "template", "id": "jt5n7c2x9m4q8r1v6w3y0z2b" }Duplicate a template
Creates a new draft named with "(copy)" appended. The copy has no alias and must be published before it can be sent.
{ "object": "template", "id": "jt8q2w5e1r4t7y0u3i6o9p2a" }Delete a template
curl -X DELETE https://api.sooner.dev/templates/order-shipped \
-H "Authorization: Bearer $SOONER_API_KEY"{ "object": "template", "id": "jt5n7c2x9m4q8r1v6w3y0z2b", "deleted": true }Emails that were already sent are not affected. New sends that reference a deleted template return 404 not_found.