Transactional Emails
Send transactional emails for user actions: welcome emails, password resets, order confirmations, receipts, and more. Built for reliability with tracking and analytics.
What are Transactional Emails?
Transactional emails are triggered by user actions and contain information specific to that user. Unlike marketing emails (broadcasts), they are:
🎯 Triggered
Sent automatically based on user actions like signing up, making a purchase, or resetting a password.
👤 Personalized
Contain information specific to the recipient like their name, order details, or account information.
⚡ Time-Sensitive
Expected immediately after the action. Delivery speed is critical for user experience.
Common Transactional Email Types
| Type | Trigger | Priority |
|---|---|---|
| Welcome Email | User registration | High |
| Email Verification | Account creation | High |
| Password Reset | Forgot password request | Critical |
| Order Confirmation | Purchase completed | High |
| Shipping Notification | Order shipped | Medium |
| Receipt/Invoice | Payment processed | Medium |
| Account Activity | Login, changes, etc. | Medium |
Quick Examples
import Metigan from 'metigan';
const metigan = new Metigan({
apiKey: process.env.METIGAN_API_KEY!
});
async function sendWelcomeEmail(user: { email: string; name: string }) {
const result = await metigan.email.sendEmail({
from: 'Welcome Team <welcome@myapp.com>',
recipients: [user.email],
subject: `Welcome to MyApp, ${user.name}! 🎉`,
content: `
<!DOCTYPE html>
<html>
<body style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px;">
<div style="text-align: center; padding: 40px 0;">
<h1 style="color: #2563eb; margin: 0;">Welcome, ${user.name}! 👋</h1>
</div>
<p style="font-size: 16px; line-height: 1.6; color: #374151;">
Thank you for joining MyApp! We're excited to have you on board.
</p>
<div style="background: #f3f4f6; border-radius: 8px; padding: 20px; margin: 30px 0;">
<h3 style="margin: 0 0 15px 0; color: #1f2937;">Getting Started:</h3>
<ul style="margin: 0; padding-left: 20px; color: #4b5563;">
<li style="margin-bottom: 10px;">Complete your profile</li>
<li style="margin-bottom: 10px;">Explore our features</li>
<li style="margin-bottom: 10px;">Invite your team</li>
</ul>
</div>
<div style="text-align: center; margin: 30px 0;">
<a href="https://myapp.com/dashboard"
style="display: inline-block; padding: 14px 28px; background: #2563eb; color: white;
text-decoration: none; border-radius: 8px; font-weight: 600;">
Go to Dashboard →
</a>
</div>
<p style="font-size: 14px; color: #6b7280; border-top: 1px solid #e5e7eb; padding-top: 20px;">
Questions? Reply to this email or contact support@myapp.com
</p>
</body>
</html>
`
});
return result;
}
// On user registration
sendWelcomeEmail({ email: 'newuser@example.com', name: 'John' });Using Templates with Variables
For cleaner code and easier maintenance, use templates with dynamic variables. Create the template once, then just pass the data when sending.
Step 1: Create Template
import Metigan from 'metigan';
const metigan = new Metigan({
apiKey: process.env.METIGAN_API_KEY!
});
// Create a welcome email template with variables
const template = await metigan.templates.create({
name: 'Welcome Email',
subject: 'Welcome to {{appName}}, {{firstName}}! 🎉',
content: `
<!DOCTYPE html>
<html>
<body style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px;">
<h1>Welcome, {{firstName}} {{lastName}}! 👋</h1>
<p>Thank you for joining {{appName}}!</p>
<p>Your account details:</p>
<ul>
<li>Email: {{email}}</li>
<li>Plan: {{plan}}</li>
</ul>
<a href="{{dashboardUrl}}" style="display: inline-block; padding: 14px 28px;
background: #2563eb; color: white; text-decoration: none; border-radius: 8px;">
Go to Dashboard
</a>
<p style="margin-top: 30px; color: #6b7280; font-size: 14px;">
Need help? Contact us at {{supportEmail}}
</p>
</body>
</html>
`
});
console.log('Template ID:', template.id);
// Save: WELCOME_TEMPLATE_ID = template.idStep 2: Send with Variables
import Metigan from 'metigan';
const metigan = new Metigan({
apiKey: process.env.METIGAN_API_KEY!
});
const WELCOME_TEMPLATE_ID = 'your-template-id';
async function sendWelcomeEmail(user: {
email: string;
firstName: string;
lastName: string;
plan: string;
}) {
const result = await metigan.email.sendEmail({
from: 'Welcome <welcome@myapp.com>',
recipients: [user.email],
templateId: WELCOME_TEMPLATE_ID,
variables: {
firstName: user.firstName,
lastName: user.lastName,
email: user.email,
plan: user.plan,
appName: 'MyApp',
dashboardUrl: 'https://myapp.com/dashboard',
supportEmail: 'support@myapp.com'
}
});
return result;
}
// Usage
sendWelcomeEmail({
email: 'john@example.com',
firstName: 'John',
lastName: 'Doe',
plan: 'Pro'
});Use {{variableName}} syntax in your templates. All variables passed in the variables object will be automatically replaced when sending.
Best Practices
📧 Email Design
- • Keep emails simple and focused
- • Use inline CSS for compatibility
- • Test on multiple email clients
- • Mobile-first design (600px max-width)
- • Clear call-to-action buttons
- • Include plain text fallback
⚡ Delivery
- • Send immediately after trigger event
- • Use verified sender domains
- • Implement retry logic for failures
- • Monitor delivery rates
- • Use tracking IDs for debugging
- • Set up webhooks for status updates
🔒 Security
- • Never include passwords in emails
- • Use short expiry for sensitive links
- • Generate secure random tokens
- • Validate email addresses
- • Implement rate limiting
- • Log sending events (not content)
📊 Tracking
- • Use tracking IDs for each email
- • Set up webhooks for open/click events
- • Monitor bounce and complaint rates
- • A/B test subject lines
- • Track conversion rates
- • Analyze engagement metrics
Tracking with Webhooks
Set up webhooks to receive real-time notifications about email events:
// Express webhook handler for email events
app.post('/webhooks/metigan', (req, res) => {
const event = req.body;
switch (event.event) {
case 'email.delivered':
console.log(`Email ${event.trackingId} delivered to ${event.recipient}`);
// Update your database
break;
case 'email.opened':
console.log(`Email ${event.trackingId} opened`);
// Track engagement
break;
case 'email.clicked':
console.log(`Link clicked in email ${event.trackingId}`);
// Track conversion
break;
case 'email.bounced':
console.log(`Email bounced: ${event.recipient}`);
// Mark email as invalid, stop sending
break;
case 'email.complained':
console.log(`Spam complaint from ${event.recipient}`);
// Unsubscribe user immediately
break;
}
res.status(200).send('OK');
});See the Webhook Integration Guide for complete setup instructions and event types.