Templates
Store reusable subjects and bodies with {{token}} placeholders, then send them by id.
A template holds a subject, an HTML body and/or a text body, all of which may contain {{token}} placeholders. Send it with templateId and templateData on POST /send.
All endpoints on this page accept an email API key (or a Helipod API key with the Email API enabled) and act on the key's project.
Token syntax
{{name}} or {{ name }}. Token names may contain letters, digits, _ and .. When you send, every token used in the template's subject, HTML and text must have a non-empty value in templateData, or the send is refused with 400 MISSING_VARIABLES.
Template object
Prop
Type
List templates
/templatescurl https://mail.helipod.io/api/email/templates \
-H "Authorization: Bearer your_email_api_key"Returns data as an array of template objects.
Create a template
/templatesProp
Type
At least one of htmlBody or textBody is required.
curl -X POST https://mail.helipod.io/api/email/templates \
-H "Authorization: Bearer your_email_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "password-reset",
"subject": "Reset your password, {{name}}",
"htmlBody": "<p>Hi {{name}},</p><p>Your code is <b>{{code}}</b>.</p>",
"textBody": "Hi {{name}}, your code is {{code}}."
}'Response 202: the template object plus a jobId. Wait for the job to complete before sending with the template; a send that runs before the template is ready fails in the background.
{
"success": true,
"data": {
"id": "c1a2b3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"name": "password-reset",
"subject": "Reset your password, {{name}}",
"htmlBody": "<p>Hi {{name}},</p><p>Your code is <b>{{code}}</b>.</p>",
"textBody": "Hi {{name}}, your code is {{code}}.",
"isActive": true,
"lastTestRenderAt": null,
"createdAt": "2026-10-16T09:20:00.000Z",
"updatedAt": "2026-10-16T09:20:00.000Z",
"jobId": "eml_4d1f0a2b3c4d5e6f7a8b"
}
}Errors: 400 INVALID_TEMPLATE_NAME, 400 EMPTY_TEMPLATE, 402 TEMPLATE_LIMIT_REACHED.
Get a template
/templates/{id}curl https://mail.helipod.io/api/email/templates/c1a2b3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d \
-H "Authorization: Bearer your_email_api_key"Returns the template object, or 404 TEMPLATE_NOT_FOUND.
Update a template
/templates/{id}Prop
Type
curl -X PATCH https://mail.helipod.io/api/email/templates/c1a2b3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d \
-H "Authorization: Bearer your_email_api_key" \
-H "Content-Type: application/json" \
-d '{"subject":"Your password reset code, {{name}}"}'Response 202: the updated template object plus a jobId. The change takes effect for sends once the job completes. The template must keep at least one body (400 EMPTY_TEMPLATE).
Preview a template
/templates/{id}/testProp
Type
curl -X POST https://mail.helipod.io/api/email/templates/c1a2b3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d/test \
-H "Authorization: Bearer your_email_api_key" \
-H "Content-Type: application/json" \
-d '{"data":{"name":"Ana"}}'{
"success": true,
"data": {
"subject": "Reset your password, Ana",
"html": "<p>Hi Ana,</p><p>Your code is <b>{{code}}</b>.</p>",
"text": "Hi Ana, your code is {{code}}.",
"missingVariables": ["{{code}}"]
}
}Tokens without a value are left in place in the preview and listed in missingVariables. The same template would be refused on send until code is supplied.
Delete a template
/templates/{id}curl -X DELETE https://mail.helipod.io/api/email/templates/c1a2b3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d \
-H "Authorization: Bearer your_email_api_key"{ "success": true, "data": { "deleted": true, "jobId": "eml_7a8b9c0d1e2f3a4b5c6d" } }The template is removed immediately; sends that use its id return 404 TEMPLATE_NOT_FOUND.