Email Templates

Templates let you create reusable email designs with dynamic content. TrackPost uses the Liquid templating engine for powerful, flexible templates.

Table of Contents

What Are Templates?

Templates are pre-designed email layouts with placeholder variables that get replaced with actual data when sending.

Example Template:

<h1>Welcome, {{user_name}}!</h1>
<p>Thanks for joining {{company}}.</p>
<a href="{{activation_link}}">Activate your account</a>

When Sent:

<h1>Welcome, John Doe!</h1>
<p>Thanks for joining Acme Inc.</p>
<a href="https://yourapp.com/activate?token=abc123">Activate your account</a>

Creating Templates

Via Dashboard

  1. Log in to TrackPost Dashboard
  2. Navigate to Templates
  3. Click Create Template
  4. Fill in the form:
    • Name: Unique identifier (e.g., welcome_email)
    • Subject: Email subject line (supports Liquid)
    • HTML: HTML content (supports Liquid)
    • Text: Plain text version (optional, auto-generated if not provided)
  5. Click Save Template

Via API

curl -X POST https://api.trackpost.de/v1/templates \
  -H "Authorization: Bearer tp_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "welcome_email",
    "subject": "Welcome to {{company}}, {{user_name}}!",
    "html": "<h1>Welcome, {{user_name}}!</h1><p>Thanks for joining {{company}}.</p>",
    "text": "Welcome {{user_name}}! Thanks for joining {{company}}."
  }'

Via CLI

Create a file welcome.liquid:

<h1>Welcome, {{user_name}}!</h1>
<p>We're excited to have you at {{company}}.</p>
<p>Your account details:</p>
<ul>
  <li>Username: {{username}}</li>
  <li>Plan: {{plan_name}}</li>
</ul>
<a href="{{activation_link}}" style="...">Activate Account</a>

Then create the template:

trackpost templates create \
  --name "welcome_email" \
  --subject "Welcome to {{company}}, {{user_name}}!" \
  --file welcome.liquid

Liquid Syntax

TrackPost uses Liquid - a safe, flexible templating language.

Variables

Display values using double curly braces:

Hello, {{user_name}}!
Your order #{{order_id}} has been shipped.

Filters

Modify output with filters:

{{user_name | capitalize}}           → "John" → "John"
{{price | money}}                     → "99.99" → "$99.99"
{{created_at | date: "%B %d, %Y"}}   → "2025-01-15" → "January 15, 2025"
{{items | size}}                      → Array length
{{description | truncate: 100}}       → First 100 chars
{{url | url_encode}}                  → URL encoding

Common Filters:

FilterDescriptionExample
capitalizeFirst letter uppercase{{"john" | capitalize}} → “John”
upcaseAll uppercase{{"john" | upcase}} → “JOHN”
downcaseAll lowercase{{"JOHN" | downcase}} → “john”
dateFormat date{{date | date: "%Y-%m-%d"}}
moneyFormat as currency{{99.99 | money}} → “$99.99”
truncateLimit length{{text | truncate: 50}}
strip_htmlRemove HTML{{"<p>Hi</p>" | strip_html}} → “Hi”
url_encodeURL encoding{{"hello world" | url_encode}} → “hello%20world”
defaultFallback value{{nickname | default: user_name}}

Conditionals

Show content conditionally:

{% if user_type == 'premium' %}
  <p>Thank you for being a premium member!</p>
{% else %}
  <p>Upgrade to premium for more features.</p>
{% endif %}

Operators:

  • == equal
  • != not equal
  • > greater than
  • < less than
  • >= greater than or equal
  • <= less than or equal
  • and logical AND
  • or logical OR

Multiple Conditions:

{% if plan == 'premium' and usage > 80 %}
  <p>You're using 80% of your premium quota.</p>
{% endif %}

Loops

Iterate over arrays:

<h2>Your Order Items</h2>
{% for item in items %}
  <div class="item">
    <h3>{{item.name}}</h3>
    <p>Quantity: {{item.quantity}}</p>
    <p>Price: {{item.price | money}}</p>
  </div>
{% endfor %}

<p>Total items: {{items | size}}</p>

Loop Properties:

{% for item in items %}
  {{forloop.index}} - {{item.name}}     {# 1-based index #}
  {{forloop.index0}} - {{item.name}}    {# 0-based index #}
  {{forloop.first}}                     {# true if first item #}
  {{forloop.last}}                      {# true if last item #}
  {{forloop.length}}                    {# total items #}
{% endfor %}

Case Statements

Switch-like conditional:

{% case status %}
  {% when 'pending' %}
    <span class="badge yellow">Pending</span>
  {% when 'shipped' %}
    <span class="badge blue">Shipped</span>
  {% when 'delivered' %}
    <span class="badge green">Delivered</span>
  {% else %}
    <span class="badge gray">{{status}}</span>
{% endcase %}

Comments

Add comments that don’t appear in output:

{% comment %}
  This is a note for template editors only.
  It won't appear in the sent email.
{% endcomment %}

Template Examples

Welcome Email

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Welcome to {{company}}</title>
  <style>
    body { font-family: Arial, sans-serif; line-height: 1.6; }
    .container { max-width: 600px; margin: 0 auto; padding: 20px; }
    .button { background: #007bff; color: white; padding: 12px 24px; 
              text-decoration: none; border-radius: 4px; display: inline-block; }
  </style>
</head>
<body>
  <div class="container">
    <h1>Welcome, {{user_name | capitalize}}!</h1>
    
    <p>Thanks for joining <strong>{{company}}</strong>. We're excited to have you!</p>
    
    {% if plan == 'premium' %}
      <p>As a premium member, you have access to all features.</p>
    {% else %}
      <p>You're on our free plan. <a href="{{upgrade_link}}">Upgrade</a> anytime.</p>
    {% endif %}
    
    <p>Get started by activating your account:</p>
    
    <p><a href="{{activation_link}}" class="button">Activate Account</a></p>
    
    <p style="color: #666; font-size: 14px;">
      Or copy and paste this link: {{activation_link}}
    </p>
    
    <hr>
    <p style="color: #666; font-size: 12px;">
      If you didn't create this account, you can ignore this email.
    </p>
  </div>
</body>
</html>

Order Confirmation

<h1>Order Confirmation #{{order_id}}</h1>

<p>Hi {{customer_name}},</p>

<p>Thank you for your order! Here are the details:</p>

<table style="width: 100%; border-collapse: collapse;">
  <tr style="background: #f5f5f5;">
    <th style="padding: 10px; text-align: left;">Item</th>
    <th style="padding: 10px; text-align: center;">Qty</th>
    <th style="padding: 10px; text-align: right;">Price</th>
  </tr>
  {% for item in items %}
  <tr>
    <td style="padding: 10px; border-bottom: 1px solid #ddd;">
      {{item.name}}
      {% if item.variant %}
        <br><small>{{item.variant}}</small>
      {% endif %}
    </td>
    <td style="padding: 10px; text-align: center; border-bottom: 1px solid #ddd;">
      {{item.quantity}}
    </td>
    <td style="padding: 10px; text-align: right; border-bottom: 1px solid #ddd;">
      {{item.price | money}}
    </td>
  </tr>
  {% endfor %}
  <tr>
    <td colspan="2" style="padding: 10px; text-align: right;"><strong>Total:</strong></td>
    <td style="padding: 10px; text-align: right;"><strong>{{total | money}}</strong></td>
  </tr>
</table>

{% if shipping_address %}
<h3>Shipping Address</h3>
<p>
  {{shipping_address.name}}<br>
  {{shipping_address.street}}<br>
  {{shipping_address.city}}, {{shipping_address.state}} {{shipping_address.zip}}
</p>
{% endif %}

<p>
  <a href="{{order_tracking_url}}" style="...">Track Your Order</a>
</p>

Password Reset

<h1>Password Reset Request</h1>

<p>Hi {{user_name}},</p>

<p>We received a request to reset your password. Click the link below to set a new password:</p>

<p>
  <a href="{{reset_url}}" style="background: #dc3545; color: white; padding: 12px 24px; 
     text-decoration: none; border-radius: 4px; display: inline-block;">
    Reset Password
  </a>
</p>

<p style="color: #666;">This link will expire in {{expiry}}.</p>

<p>If you didn't request this, please ignore this email or 
   <a href="{{security_url}}">contact our security team</a>.</p>

Using Templates

Send with Template ID

curl -X POST https://api.trackpost.de/v1/emails \
  -H "Authorization: Bearer tp_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "[email protected]",
    "from": "[email protected]",
    "template_id": "welcome_email",
    "variables": {
      "user_name": "John Doe",
      "company": "Acme Inc",
      "plan": "premium",
      "activation_link": "https://yourapp.com/activate?token=abc123"
    }
  }'

Via Node.js SDK

await client.emails.send({
  to: '[email protected]',
  from: '[email protected]',
  template_id: 'welcome_email',
  variables: {
    user_name: 'John Doe',
    company: 'Acme Inc',
    plan: 'premium',
    activation_link: 'https://yourapp.com/activate?token=abc123'
  }
});

Via CLI

trackpost send \
  --to [email protected] \
  --from [email protected] \
  --template welcome_email \
  --variables '{"user_name":"John Doe","company":"Acme Inc"}'

Template Validation

TrackPost validates templates when you save them.

Valid Template Requirements

  • Syntax: All Liquid tags properly closed
  • Structure: Valid HTML structure
  • Variables: No syntax errors in variable names
  • Size: Under 512KB

Common Validation Errors

ErrorCauseFix
Unexpected end of templateUnclosed tagAdd {% endif %}, {% endfor %}, etc.
Unknown filterInvalid filter nameCheck filter spelling
Invalid syntaxMalformed LiquidCheck tag syntax

Testing Templates

Preview via API:

curl -X POST https://api.trackpost.de/v1/templates/tpl_abc123/render \
  -H "Authorization: Bearer tp_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "variables": {
      "user_name": "Test User",
      "company": "Test Company"
    }
  }'

Response:

{
  "success": true,
  "data": {
    "subject": "Welcome to Test Company, Test User!",
    "html": "<h1>Welcome, Test User!</h1>...",
    "text": "Welcome Test User!..."
  }
}

Preview via CLI:

trackpost templates render welcome_email \
  --variables '{"user_name":"Test User","company":"Test Company"}'

Managing Templates

List Templates

Via Dashboard:

  • Go to Templates to see all templates
  • Filter by name or creation date

Via API:

curl https://api.trackpost.de/v1/templates \
  -H "Authorization: Bearer tp_live_your_key"

Update Templates

Via Dashboard:

  1. Go to Templates
  2. Click on the template
  3. Edit and Save Changes

Via API:

curl -X PATCH https://api.trackpost.de/v1/templates/tpl_abc123 \
  -H "Authorization: Bearer tp_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "<h1>New HTML content</h1>"
  }'

Delete Templates

Via Dashboard:

  1. Go to Templates
  2. Find the template
  3. Click Delete
  4. Confirm deletion

Via API:

curl -X DELETE https://api.trackpost.de/v1/templates/tpl_abc123 \
  -H "Authorization: Bearer tp_live_your_key"

Advanced Features

MJML Support

MJML makes responsive email design easier:

<mjml>
  <mj-body>
    <mj-section>
      <mj-column>
        <mj-text font-size="20px" color="#F45E43">
          Welcome, {{user_name}}!
        </mj-text>
        <mj-button href="{{activation_link}}">
          Activate Account
        </mj-button>
      </mj-column>
    </mj-section>
  </mj-body>
</mjml>

TrackPost automatically converts MJML to responsive HTML.

Template Versioning

TrackPost keeps track of template changes:

  • View version history in dashboard
  • Roll back to previous versions
  • See who made changes and when

Best Practices

  1. Always Provide Text Version - Some clients block HTML
  2. Test with Real Data - Use the preview feature
  3. Keep Variables Simple - Use snake_case naming
  4. Validate Before Sending - Check for Liquid errors
  5. Mobile-First Design - 60%+ of emails are opened on mobile
  6. Limit Variables - Don’t pass sensitive data
  7. Use Default Filters - Handle missing variables gracefully

Next Steps