Templates
Saved transactional emails with declared variables. Edit a draft, publish a version, and send it by slug from the Emails API.
Draft and published
A template has a slug (1 to 63 lowercase letters, digits or dashes, unique per workspace), a name, a subject, an
email document and a list of variables. It keeps a draft you edit and a published
version that sends use. Publishing validates the draft: it needs a subject, every {{VARIABLE}} it uses must be
declared, and a dry render must succeed. Sends always use the published version, so editing the draft never
changes live mail. The detail answer includes draft, published and has_unpublished_changes.
| Variable key | Type | Description |
|---|---|---|
| name | string | Uppercase letters, digits and underscores, starting with a letter, at most 40 characters. |
| type | string | string (default), number or boolean. Values must match. |
| required | boolean | A send without it fails with missing_variable unless there is a default. |
| default | any | Used when the send omits the variable. |
| description | string | For people and agents. |
# Start from a built in starter, then edit the draft and publish.
curl -X POST https://api.runearc.com/v1/templates \
-H "Authorization: Bearer $RUNEARC_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "from_starter": "password-reset" }'
curl -X POST https://api.runearc.com/v1/templates/$TEMPLATE_ID/publish \
-H "Authorization: Bearer $RUNEARC_API_KEY"Starter gallery
Eighteen starters ship with real copy and declared variables. GET /v1/template-starters returns each with
slug, name, description, category, subject, variables, document and a rendered preview. Create one
with { "from_starter": "<slug>" }.
| Category | Starters | |
|---|---|---|
| Account | password-reset, magic-link, email-verification, verification-code, team-invite, account-deleted | |
| Security | login-alert | |
| Onboarding | welcome, trial-ending, feedback-request, waitlist-confirmation | |
| Billing | receipt, invoice, subscription-renewal, payment-failed, refund-issued | |
| Commerce | order-confirmation, shipping-notification |
Send with a template
Add template to POST /v1/emails: a slug, or { "id": "<slug>", "variables": {...} }. Do not also send
html or text (template_conflict). The subject comes from the template unless you send one. The email is
tagged template with the slug. A sending key may send with a template but cannot create or edit them. The rest
of the send, including idempotency, limits and statuses, is on Emails API and
Sending.
curl -X POST https://api.runearc.com/v1/emails \
-H "Authorization: Bearer $RUNEARC_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "from": "Acme <noreply@acme.com>", "to": ["ada@example.com"],
"template": { "id": "password-reset",
"variables": { "RESET_URL": "https://acme.com/reset/abc" } } }'API
| Request | Body | Returns |
|---|---|---|
| GET /v1/template-starters | none | The 18 starters with previews. |
| GET /v1/templates | none | Templates. |
| POST /v1/templates | from_starter, or name, slug, description, subject, document, variables | 201 and the template. Empty body makes a blank one. |
| GET /v1/templates/{id} | none | Detail with draft and published versions. |
| PATCH /v1/templates/{id} | name, description, subject, document, variables, preview_variables | The detail. Edits the draft. |
| DELETE /v1/templates/{id} | none | 204. Archives it. |
| POST /v1/templates/{id}/publish | none | The detail with the new published version. |
| POST /v1/templates/{id}/copy | slug, name (both optional) | 201 and the copy, slug suffixed -copy by default. |
| POST /v1/templates/{id}/preview | version (draft or published), variables | subject, html, text. |
CLI and MCP
runearc template starters
runearc template create --starter password-reset
runearc template publish tpl_...
runearc template send tpl_... --from "Acme <noreply@acme.com>" --to ada@example.com --var RESET_URL=https://acme.com/reset/abcMCP tools: list_templates, create_template and send_template.
Errors
| Code | Status | Meaning and fix |
|---|---|---|
| template_not_found | 404 | List templates with GET /v1/templates, or send a slug. |
| template_not_published | 409 | Publish the template before sending it. |
| template_slug_taken | 409 | Pick another slug, or copy the template. |
| invalid_template_slug | 400 | Use 1 to 63 lowercase letters, digits or dashes. |
| unknown_starter | 400 | Use a slug from GET /v1/template-starters. |
| invalid_subject, undeclared_variable, invalid_variables_schema | 400 | Fix the draft before publishing: set a subject, declare every variable it uses, use valid unique variable names. |
| missing_variable, invalid_variable | 400 | Send the required variables, as the declared type. |
| template_conflict | 400 | A send with a template cannot carry html or text. |
| invalid_template_ref | 400 | template is a slug or an object with id and variables. |
| insufficient_scope | 403 | A sending key cannot manage templates. Use a full key. |