Transactional Emails
Transactional emails are triggered programmatically for individual users—order confirmations, password resets, account notifications, and other time-sensitive communications.
Transactional vs Marketing
Transactional Marketing Triggered by user action Sent to segments One recipient at a time Multiple recipients Time-sensitive Can be scheduled Expected by user Promotional Higher deliverability May be filtered
Examples of transactional emails:
Order confirmation
Shipping notification
Password reset
Account verification
Payment receipt
Security alert
Two Sending Modes
1. Template Mode (Recommended)
Create reusable templates in the dashboard, send via API using the template slug.
curl -X POST "https://api.sequenzy.com/api/v1/transactional/send" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "customer@example.com",
"slug": "order-confirmation",
"variables": {
"orderNumber": "ORD-12345",
"total": "$99.99",
"deliveryDate": "January 20, 2024"
}
}'
Benefits:
Non-developers can edit templates
Consistent branding
Version control in dashboard
Analytics per template
2. Direct Mode
Send email content directly without a pre-created template.
curl -X POST "https://api.sequenzy.com/api/v1/transactional/send" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "customer@example.com",
"subject": "Your Order #{{orderNumber}}",
"body": "<h1>Thank you for your order!</h1><p>Order: {{orderNumber}}</p>",
"variables": {
"orderNumber": "ORD-12345"
}
}'
Use cases:
Dynamic content generated by your app
One-off emails that don’t need templates
Testing and development
React Email templates (see below)
3. React Email Mode
Build type-safe, responsive email templates using React Email components and render them to HTML.
import { render } from "@react-email/render" ;
import {
Body ,
Button ,
Container ,
Head ,
Heading ,
Html ,
Preview ,
Text ,
} from "@react-email/components" ;
// Create your email component
function OrderConfirmation ({ orderNumber , total } : { orderNumber : string ; total : string }) {
return (
< Html >
< Head />
< Preview > Your order #{ orderNumber } is confirmed </ Preview >
< Body style = {{ fontFamily : "sans-serif" }} >
< Container >
< Heading > Thank you for your order !</ Heading >
< Text > Order : #{ orderNumber }</ Text >
< Text > Total : { total }</ Text >
< Button href = "https://example.com/orders" > View Order </ Button >
</ Container >
</ Body >
</ Html >
);
}
// Render and send
const html = await render ( OrderConfirmation ({ orderNumber: "ORD-12345" , total: "$99.99" }));
await fetch ( "https://api.sequenzy.com/api/v1/transactional/send" , {
method: "POST" ,
headers: {
Authorization: `Bearer ${ process . env . SEQUENZY_API_KEY } ` ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({
to: "customer@example.com" ,
subject: "Your Order #ORD-12345" ,
body: html ,
}),
});
Benefits:
Type-safe templates with TypeScript
Reusable components
Responsive design built-in
Preview emails during development
Creating Templates
In the Dashboard
Go to Transactional in your dashboard
Click Create Template
Enter a slug (URL-friendly identifier)
Design your email with the visual editor
Add variable placeholders where needed
Save and activate
Template Slugs
Slugs are unique identifiers for your templates:
order-confirmation
password-reset
welcome-email
invoice-reminder
shipping-update
Slugs are auto-generated from the template name but can be customized. They
cannot be changed after creation.
Variables
Variables let you personalize transactional emails.
Syntax
< p > Hello {{FIRST_NAME}}, </ p >
< p > Your order {{orderNumber}} has shipped! </ p >
With Defaults
Provide fallback values for missing variables:
< p > Hello {{FIRST_NAME|Customer}}, </ p >
If FIRST_NAME is empty, “Customer” is used.
System Variables
These are automatically available:
Variable Source {{NAME}}Subscriber full name {{FIRST_NAME}}Subscriber first name {{LAST_NAME}}Subscriber last name {{EMAIL}}Subscriber email
Custom Attributes
Any subscriber custom attributes are available:
< p > Your plan: {{plan}} </ p >
< p > Account ID: {{userId}} </ p >
Passed Variables
Variables passed in the API request:
{
"variables" : {
"orderNumber" : "ORD-123" ,
"total" : "$99.99"
}
}
< p > Order: {{orderNumber}} </ p >
< p > Total: {{total}} </ p >
API Reference
Send Email
POST /api/v1/transactional/send
Template mode:
{
"to" : "user@example.com" ,
"slug" : "template-slug" ,
"variables" : {
"key" : "value"
}
}
Direct mode:
{
"to" : "user@example.com" ,
"subject" : "Email Subject" ,
"body" : "<html>Email content</html>" ,
"variables" : {
"key" : "value"
}
}
Response:
{
"success" : true ,
"data" : {
"jobId" : "job_abc123" ,
"email" : "user@example.com"
}
}
List Templates
GET /api/v1/transactional
Response:
{
"success" : true ,
"data" : [
{
"id" : "trans_abc123" ,
"slug" : "order-confirmation" ,
"name" : "Order Confirmation" ,
"subject" : "Your Order #{{orderNumber}}" ,
"enabled" : true
}
]
}
Get Template Details
GET /api/v1/transactional/:slug
Response:
{
"success" : true ,
"data" : {
"id" : "trans_abc123" ,
"slug" : "order-confirmation" ,
"name" : "Order Confirmation" ,
"subject" : "Your Order #{{orderNumber}}" ,
"body" : "<html>...</html>" ,
"enabled" : true ,
"variables" : [ "orderNumber" , "total" , "items" ]
}
}
Auto-Creation
When you send to an email that doesn’t exist:
A new subscriber is created automatically
Status is set to active
Custom attributes from variables are saved (if applicable)
This makes integration seamless—no need to create subscribers first.
Error Handling
Common Errors
Error Cause Solution Template not foundInvalid slug Check slug spelling Template disabledTemplate is deactivated Enable in dashboard Missing required fieldsNo to, slug/subject Include required fields Missing variablesTemplate has unfilled variables Pass all required variables No sender configuredNo sender profile Set up sender in dashboard Sending pausedAccount sending is paused Check sending status
Response Codes
Code Description 200Email queued successfully 400Validation error 401Invalid API key 404Template not found 500Server error
Best Practices
1. Use Templates
Templates are easier to maintain and update:
✓ Template: Update once, affects all future sends
✗ Direct: Must update every code path that sends email
2. Handle Variables Gracefully
Always provide defaults or check for required variables:
<!-- Good: Has default -->
< p > Hi {{FIRST_NAME|there}}, </ p >
<!-- Better: Check in template -->
{{#if firstName}}
< p > Hi {{firstName}}, </ p >
{{else}}
< p > Hi there, </ p >
{{/if}}
3. Log Job IDs
Save the returned job ID for debugging:
const response = await sendTransactional ({
to: user . email ,
slug: "order-confirmation" ,
variables: { orderNumber: order . id },
});
await saveToDatabase ({
orderId: order . id ,
emailJobId: response . data . jobId ,
});
4. Use Meaningful Slugs
✓ "order-confirmation"
✓ "password-reset"
✓ "trial-expiring-reminder"
✗ "email1"
✗ "template_2024_01"
5. Test in Development
Use test emails before production:
const to =
process . env . NODE_ENV === "development" ? "test@yourdomain.com" : user . email ;
Integration Examples
Order Confirmation
async function sendOrderConfirmation ( order ) {
await fetch ( "https://api.sequenzy.com/api/v1/transactional/send" , {
method: "POST" ,
headers: {
Authorization: `Bearer ${ process . env . SEQUENZY_API_KEY } ` ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({
to: order . customerEmail ,
slug: "order-confirmation" ,
variables: {
orderNumber: order . id ,
total: formatCurrency ( order . total ),
items: order . items . map (( i ) => i . name ). join ( ", " ),
shippingAddress: formatAddress ( order . shippingAddress ),
estimatedDelivery: formatDate ( order . estimatedDelivery ),
},
}),
});
}
Password Reset
async function sendPasswordReset ( email , resetToken ) {
const resetUrl = ` ${ APP_URL } /reset-password?token= ${ resetToken } ` ;
await fetch ( "https://api.sequenzy.com/api/v1/transactional/send" , {
method: "POST" ,
headers: {
Authorization: `Bearer ${ process . env . SEQUENZY_API_KEY } ` ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({
to: email ,
slug: "password-reset" ,
variables: {
resetUrl ,
expiresIn: "24 hours" ,
},
}),
});
}
Welcome Email
async function sendWelcome ( user ) {
await fetch ( "https://api.sequenzy.com/api/v1/transactional/send" , {
method: "POST" ,
headers: {
Authorization: `Bearer ${ process . env . SEQUENZY_API_KEY } ` ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({
to: user . email ,
slug: "welcome" ,
variables: {
firstName: user . firstName ,
dashboardUrl: ` ${ APP_URL } /dashboard` ,
docsUrl: ` ${ APP_URL } /docs` ,
},
}),
});
}
API Reference Full API documentation
Subscribers Auto-creation and attributes
Campaigns Broadcast marketing emails
Sequences Automated email workflows