Templates
Pre-built templates with dynamic variable substitution. HTML, React Email (.tsx), and plain text bodies all supported. Required-variable enforcement prevents silent missing-variable bugs.
Templates are created and managed through the dashboard. Each template has a name, subject, HTML body, optional plain text body, and an optional list of **required variables**.
## Three template formats
• **HTML** — paste raw HTML; `{{variableName}}` placeholders are substituted at send time
• **React Email** — write a `.tsx` component using @react-email/components; Posthawk renders it server-side and substitutes `{{}}` placeholders in the rendered HTML
• **Plain text** — simple text bodies for transactional emails that don't need styling
You can switch a template's format at any time without losing the existing body. The dashboard editor surfaces a one-shot hint pointing this out.
## Variables
Variables use double-curly-brace syntax: `{{variableName}}`. Pass a `variables` object on send and Posthawk substitutes them in the subject, HTML body, and text body.
Explicit values in the request (subject, html, text) override template values for per-send customization.
## Required variables (production-grade)
Each template can declare a list of `required_variables` (managed via the dashboard's "Req" pill toggle next to each variable, or via the database's `email_templates.required_variables` column).
When you send with a template that has required variables, Posthawk validates them at send time:
• If the variables object is missing any required variable, the API returns 400 with `error: "missing_required_variables"` and a `missing` array listing the names
• If a required variable is present but empty (`""`), it also fails — empty strings would render as blank text, which is almost always a bug
• Non-required variables that are missing render as the literal placeholder (e.g. `{{tagline}}`) — same as before
This catches the classic "I sent 5,000 emails saying 'Hello {{name}}'" bug at the API layer instead of the recipient inbox.POST
/v1/sendAPI KeySend an email using a template with variable substitution.
| Parameter | Type | In | Description |
|---|---|---|---|
fromrequired | string | body | Sender email address |
torequired | string[] | body | Array of recipient email addresses |
templateIdrequired | string | body | UUID of the email template |
variables | Record<string, string> | body | Key-value pairs for template variable substitution |
subject | string | body | Override template subject |
Request
bash
curl -X POST https://your-posthawk-instance.com/v1/send \
-H "Content-Type: application/json" \
-H "X-API-Key: your_api_key" \
-d '{
"from": "hello@yourdomain.com",
"to": ["user@example.com"],
"templateId": "template-uuid-here",
"variables": {
"firstName": "John",
"companyName": "Acme Inc",
"unsubscribeUrl": "https://example.com/unsub/123"
}
}'Response
json
{
"success": true,
"scheduled": false,
"jobId": "abc-123-def",
"message": "Email queued for sending",
"statusUrl": "/v1/send/abc-123-def"
}POST
/v1/renderAPI KeyRender a template with variables without sending. Useful for previewing templates or generating HTML for other purposes.
| Parameter | Type | In | Description |
|---|---|---|---|
templateIdrequired | string | body | UUID of the email template to render |
variables | Record<string, string> | body | Key-value pairs for template variable substitution |
Request
bash
curl -X POST https://your-posthawk-instance.com/v1/render \
-H "Content-Type: application/json" \
-H "X-API-Key: your_api_key" \
-d '{
"templateId": "template-uuid-here",
"variables": {
"firstName": "John",
"companyName": "Acme Inc"
}
}'Response
json
{
"success": true,
"html": "<h1>Welcome, John!</h1><p>Thanks for joining Acme Inc.</p>",
"text": "Welcome, John! Thanks for joining Acme Inc.",
"subject": "Welcome to Acme Inc"
}