Skip to main content

Email Templates

Store reusable HTML email templates with {{variable}} placeholders, then send personalized email by referencing a template name and passing variables — no need to embed HTML in every request.

Endpoints​

ActionMethod & Path
Create templatePOST /v1/email/templates
List templatesGET /v1/email/templates
Get a templateGET /v1/email/templates/:name
Update a templatePUT /v1/email/templates/:name
Delete a templateDELETE /v1/email/templates/:name

Create a Template​

POST /v1/email/templates

Parameters​

FieldTypeRequiredDescription
namestringYesUnique template identifier (e.g. order_confirmation)
subjectstringYesSubject line; may contain {{variables}}
htmlstringYesHTML body with {{variables}}
textstringNoPlain-text alternative
curl -X POST https://api.afriroute.ai/api/v1/email/templates \
-H "Authorization: Bearer $AFRIROUTE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "order_confirmation",
"subject": "Order {{order_id}} Confirmed",
"html": "<h2>Hi {{customer_name}},</h2><p>Your order {{order_id}} is confirmed!</p>"
}'

Response​

{
"name": "order_confirmation",
"subject": "Order {{order_id}} Confirmed",
"variables": ["customer_name", "order_id"],
"created_at": "2026-05-28T10:30:00Z",
"updated_at": "2026-05-28T10:30:00Z"
}

Send Using a Template​

Reference the template by name and pass variables. Any placeholder not supplied resolves to an empty string.

send-template.js
await fetch('https://api.afriroute.ai/api/v1/email/send', {
method: 'POST',
headers: {
'Authorization': 'Bearer $AFRIROUTE_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
from: '[email protected]',
to: '[email protected]',
template: 'order_confirmation',
variables: {
customer_name: 'John Doe',
order_id: '#12345'
}
})
});
send_template.py
import requests

requests.post(
'https://api.afriroute.ai/api/v1/email/send',
headers={'Authorization': 'Bearer $AFRIROUTE_API_KEY'},
json={
'from': '[email protected]',
'to': '[email protected]',
'template': 'order_confirmation',
'variables': {
'customer_name': 'John Doe',
'order_id': '#12345'
}
}
)

Responsive HTML Example​

Templates are plain HTML — design them mobile-first and inline critical styles for the widest client support.

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body { font-family: Arial, sans-serif; line-height: 1.6; }
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
.button {
background: #0066FF; color: #fff; padding: 12px 24px;
text-decoration: none; border-radius: 4px; display: inline-block;
}
@media (max-width: 600px) { .container { padding: 10px; } }
</style>
</head>
<body>
<div class="container">
<h2>Hi {{customer_name}},</h2>
<p>Your order {{order_id}} is confirmed and ships soon.</p>
<a href="{{tracking_url}}" class="button">Track Order</a>
</div>
</body>
</html>

List & Manage Templates​

# List all templates
curl https://api.afriroute.ai/api/v1/email/templates \
-H "Authorization: Bearer $AFRIROUTE_API_KEY"

# Update an existing template
curl -X PUT https://api.afriroute.ai/api/v1/email/templates/order_confirmation \
-H "Authorization: Bearer $AFRIROUTE_API_KEY" \
-d '{"subject": "Your order {{order_id}} is on the way"}'

# Delete a template
curl -X DELETE https://api.afriroute.ai/api/v1/email/templates/order_confirmation \
-H "Authorization: Bearer $AFRIROUTE_API_KEY"

Best Practices​

  • Use descriptive, stable names (order_confirmation, password_reset) — these are referenced in code.
  • Inline CSS for maximum email-client compatibility; many clients strip <style> blocks.
  • Provide a text part in every template for accessibility and deliverability.
  • Validate variables: a missing variable renders as empty rather than erroring.
  • Version cautiously — updating a template affects all future sends that reference it.

Errors​

CodeHTTPMeaning
TEMPLATE_EXISTS409A template with that name already exists
TEMPLATE_NOT_FOUND404Referenced template does not exist
INVALID_TEMPLATE400Malformed HTML or unbalanced {{ }} placeholders

Last Updated: May 2026 · Need help? Contact Support →