Templates
Create, update, list, and preview email templates built with MJML and Liquid variables.
Templates define the content and layout of your emails. They are written in MJML for responsive rendering and support Liquid variables for personalisation.
Create or update template
PUT /api/templates/:idCreates a new template or updates an existing one. This endpoint is idempotent — calling it multiple times with the same ID and body produces the same result.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id | string | A unique identifier for the template (e.g. welcome-email, password-reset). |
Request body
On create, name, subject, and content are all required. On update (when the template already exists) every field is optional, but at least one must be provided. The template ID comes from the path — it is not part of the body.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | On create | Human-readable name for the template. |
subject | string | On create | Email subject line. Supports Liquid variables (e.g. Welcome, {{ firstName }}!). |
content | string | On create | The email body. MJML is expected; raw HTML is accepted and automatically wrapped in MJML. Dangerous tags and unsafe link schemes are stripped. |
enabled | boolean | No | Update only. Enable or disable the template for sending. |
disableReason | string | No | Update only. Optional note recorded when disabling. |
Required variables are derived from the template content by the server and returned as requiredVariables — they are not supplied in the request.
Response
Returns the created (201) or updated (200) template metadata. The stored content is not echoed back; fetch it with GET /api/templates/:id.
{
"templateId": "welcome-email",
"name": "Welcome Email",
"subject": "Welcome, {{ firstName }}!",
"currentVersion": 3,
"enabled": true,
"requiredVariables": ["firstName"],
"createdAt": "2025-09-10T08:00:00.000Z",
"updatedAt": "2025-09-15T14:00:00.000Z"
}Errors
| Code | Description |
|---|---|
VALIDATION_ERROR | Missing required fields, invalid MJML, or no fields provided on update. |
PLAN_LIMIT_EXCEEDED | The plan's template limit has been reached. |
Examples
curl -X PUT https://api.kraiter.com/api/templates/welcome-email \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Welcome Email",
"subject": "Welcome, {{ firstName }}!",
"content": "<mjml><mj-body><mj-section><mj-column><mj-text>Hello {{ firstName }}, welcome to Kraiter!</mj-text></mj-column></mj-section></mj-body></mjml>"
}'const template = await kraiter.templates.put("welcome-email", {
name: "Welcome Email",
subject: "Welcome, {{ firstName }}!",
content:
"<mjml><mj-body><mj-section><mj-column><mj-text>Hello {{ firstName }}, welcome to Kraiter!</mj-text></mj-column></mj-section></mj-body></mjml>",
});List templates
GET /api/templatesReturns a paginated list of templates.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
cursor | string | — | Pagination cursor from a previous response. |
limit | number | 20 | Number of templates to return (max 100). |
Response
{
"items": [
{
"templateId": "welcome-email",
"name": "Welcome Email",
"subject": "Welcome, {{ firstName }}!",
"currentVersion": 3,
"enabled": true,
"requiredVariables": ["firstName"],
"createdAt": "2025-09-10T08:00:00.000Z",
"updatedAt": "2025-09-15T14:00:00.000Z"
}
],
"nextCursor": null
}Examples
curl "https://api.kraiter.com/api/templates?limit=10" \
-H "Authorization: Bearer YOUR_API_KEY"const templates = await kraiter.templates.list({ limit: 10 });Get template
GET /api/templates/:idReturns a single template including its full MJML source.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id | string | The template ID. |
Errors
| Code | Description |
|---|---|
TEMPLATE_NOT_FOUND | No template with this ID exists. |
Examples
curl https://api.kraiter.com/api/templates/welcome-email \
-H "Authorization: Bearer YOUR_API_KEY"const template = await kraiter.templates.get("welcome-email");Delete template
DELETE /api/templates/:idPermanently deletes a template. Sequences referencing this template will fail on their next send.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id | string | The template ID. |
Response
Returns 204 No Content on success.
Errors
| Code | Description |
|---|---|
TEMPLATE_NOT_FOUND | No template with this ID exists. |
Examples
curl -X DELETE https://api.kraiter.com/api/templates/welcome-email \
-H "Authorization: Bearer YOUR_API_KEY"await kraiter.templates.delete("welcome-email");List template versions
GET /api/templates/:id/versionsReturns the version history for a template. Each time a template is updated via PUT, a new version is created.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id | string | The template ID. |
Response
The full version history is returned in a single items array (not cursor-paginated).
{
"items": [
{
"version": 3,
"subject": "Welcome, {{ firstName }}!",
"updatedAt": "2025-09-15T14:00:00.000Z"
},
{
"version": 2,
"subject": "Welcome to Kraiter!",
"updatedAt": "2025-09-12T09:00:00.000Z"
}
]
}Examples
curl "https://api.kraiter.com/api/templates/welcome-email/versions" \
-H "Authorization: Bearer YOUR_API_KEY"const versions = await kraiter.templates.listVersions("welcome-email");Preview template
POST /api/templates/:id/previewRenders the template with the provided variables and returns the resulting HTML. Use this to preview how an email will look before sending.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id | string | The template ID. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
variables | object | No | Key-value pairs to inject into the template. |
Response
{
"subject": "Welcome, Alice!",
"html": "<!doctype html><html>...",
"text": "Welcome, Alice! ...",
"templateVersion": 3
}The variables object also accepts structured contact and event objects (as used at send time) in addition to arbitrary top-level custom variables.
Examples
curl -X POST https://api.kraiter.com/api/templates/welcome-email/preview \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "variables": { "firstName": "Alice" } }'const preview = await kraiter.templates.preview("welcome-email", {
variables: { firstName: "Alice" },
});
console.log(preview.html);