Transactional Email Best Practices for SaaS Apps
How to set up reliable transactional emails for your SaaS application. From infrastructure to templates to monitoring.
Why Transactional Emails Matter
Transactional emails — password resets, order confirmations, welcome emails — have the highest open rates of any email type (80%+ average). They're critical for user experience and retention.
If a user can't reset their password because your email didn't arrive, you lose that user forever.
Infrastructure Decisions
Dedicated Domain
Never send transactional emails from your marketing domain. Use a subdomain:
mail.yourapp.comfor transactionalnews.yourapp.comfor marketing
This protects your transactional reputation if marketing emails cause spam complaints.
API vs SMTP
| Factor | REST API | SMTP |
|---|---|---|
| Speed | Faster (single HTTP call) | Slower (multi-step handshake) |
| Reliability | Better error handling | Connection timeouts |
| Features | Full API features | Basic send only |
| Setup | Simple (HTTP client) | Requires SMTP library |
Recommendation: Use REST API for new applications. Use SMTP only for legacy systems.
Essential Transactional Emails
Every SaaS app should have these:
- Welcome email — Sent immediately after signup
- Email verification — Confirm the address is real
- Password reset — Time-limited, secure tokens
- Invoice/receipt — After payment
- Usage alerts — Approaching plan limits
Template Best Practices
- Keep it simple — Transactional emails should be functional, not flashy
- One clear CTA — Each email should have one primary action
- Mobile responsive — 60%+ of emails are opened on mobile
- Consistent branding — Same logo, colors, and footer on every email
- Plain text fallback — Always include a text version
Error Handling
async function sendEmailWithRetry(params: EmailParams, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
const { data, error } = await unosend.emails.send(params);
if (error) throw new Error(error.message);
return data;
} catch (err) {
if (i === retries - 1) throw err;
await new Promise(r => setTimeout(r, 1000 * Math.pow(2, i)));
}
}
}Key points:
- Retry with exponential backoff — Don't hammer the API on failure
- Log failures — Track which emails fail and why
- Alert on critical failures — Password resets and verifications must succeed
- Queue non-urgent emails — Notifications can be slightly delayed
Monitoring
Set up webhooks to track:
- Delivered — Email accepted by recipient's server
- Opened — Recipient opened the email (pixel tracking)
- Clicked — Recipient clicked a link
- Bounced — Email rejected (remove from list!)
- Complained — Marked as spam (stop emailing this person!)
// Webhook handler
app.post('/webhooks/email', (req, res) => {
const event = req.body;
switch (event.type) {
case 'email.bounced':
suppressEmail(event.data.to);
break;
case 'email.complained':
suppressEmail(event.data.to);
alertTeam(event.data);
break;
}
res.sendStatus(200);
});Quick Setup Guide
- Sign up for an email API (Unosend gives 5,000 free/month)
- Verify your sending domain (SPF + DKIM)
- Build your core email templates
- Implement send with retry logic
- Set up webhook handlers for bounces/complaints
- Monitor deliverability in your dashboard
Ready to send your first email?
Get started with 5,000 free emails/month. No credit card required.
Start for freeRelated Articles
Email Deliverability Guide: How to Land in the Inbox
Everything you need to know about email deliverability. Learn SPF, DKIM, DMARC, sender reputation, and inbox placement strategies.
SPF, DKIM, and DMARC Explained: Email Authentication for Developers
A developer-friendly guide to email authentication. Learn how SPF, DKIM, and DMARC work together to protect your domain and improve deliverability.