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

JSON
{
  "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

POST/templates

Creates a draft.

FieldTypeRequiredDescription
namestringYes1 to 200 characters.
htmlstringYesThe HTML body, with optional variables.
aliasstringNoLowercase letters, digits, hyphen and underscore, up to 100 characters. Unique in the project.
subjectstringNoUp to 998 characters.
fromstringNoDefault sender.
reply_tostring or string[]NoDefault reply-to.
textstringNoThe plain-text body.
variablesobject[]NoUp to 50 of { key, type, fallback_value }. key is letters, digits and underscore, up to 50 characters. type is string or number.
Shell
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" }]
  }'
JSON
{ "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

GET/templates

Returns the project's templates, newest first. Accepts limit and after. See Pagination.

Shell
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

GET/templates/{identifier}

Returns one template object. Notable errors: not_found.

Update a template

PATCH/templates/{identifier}

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.

Shell
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" }'
JSON
{ "object": "template", "id": "jt5n7c2x9m4q8r1v6w3y0z2b" }

Notable errors: validation_error when the new alias is taken, not_found.

Publish a template

POST/templates/{identifier}/publish

Makes the current draft the live version. A publish can take up to about 30 seconds to be used by sends.

Shell
curl -X POST https://api.sooner.dev/templates/order-shipped/publish \
  -H "Authorization: Bearer $SOONER_API_KEY"
JSON
{ "object": "template", "id": "jt5n7c2x9m4q8r1v6w3y0z2b" }

Duplicate a template

POST/templates/{identifier}/duplicate

Creates a new draft named with "(copy)" appended. The copy has no alias and must be published before it can be sent.

JSON
{ "object": "template", "id": "jt8q2w5e1r4t7y0u3i6o9p2a" }

Delete a template

DELETE/templates/{identifier}
Shell
curl -X DELETE https://api.sooner.dev/templates/order-shipped \
  -H "Authorization: Bearer $SOONER_API_KEY"
JSON
{ "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.