Create a template
A draft unless you ask for it to be published. A draft can be previewed and cannot be sent.
Runs the real call against your workspace, with your own key.
POST /templates
A draft unless you ask for it to be published. A draft can be previewed and cannot be sent.
Example
Needs templates:write. Returns 201. slug is derived from the name when you omit it, and it is the handle to pin in code, because a name is the thing somebody renames.
curl -X POST "$OE/templates" -H "$AUTH" -H "Content-Type: application/json" \ -d '{ "name": "Order shipped", "engine": "html", "subject": "Order {{orderId}} is on its way", "html": "<p>Hello {{customer}}, {{orderId}} left the warehouse.</p>", "props": [ { "key": "orderId", "kind": "text", "required": true }, { "key": "customer", "kind": "text", "default": "there" } ], "publish": true }'{ "object": "template", "id": "tpl_9c1f0a4b7e05d3862c1f0a44", "name": "Order shipped", "slug": "order-shipped", "description": null, "status": "active", "publishedVersion": 1, "latestVersion": 1, "subject": "Order {{orderId}} is on its way", "engine": "html", "slots": [], "props": [ { "key": "orderId", "kind": "text", "required": true, "default": null }, { "key": "customer", "kind": "text", "required": false, "default": "there" } ], "createdAt": "2026-08-30T10:41:02.000Z", "updatedAt": "2026-08-30T10:41:02.000Z"}Set publish: true from a deploy script. Without it you get version 1 as a draft, which is right when a person is going to read the copy first and wrong in anything automated.
A duplicate name is template_name_taken and a duplicate slug is template_slug_taken, both 409s on the connection rather than on the account.
A connection holds 200 templates. The 201st is template_limit_reached, a guard against a runaway script, not a plan limit.