Explainer
Transactional email is the backbone of every web application — password resets, receipts, alerts. Here's what separates a good service from a great one.
You've signed up for an app and immediately got a "Confirm your email" message in your inbox. That's a transactional email. Thirty seconds later you reset your password — that's another one. The order receipt you got from an e-commerce store, the 2FA code, the "your export is ready" notification — all transactional emails.
These emails are triggered by user actions, not scheduled campaigns. They're expected, which is why they get opened at 50-70% rates compared to 20-25% for marketing email. And they're critical — a failed password reset is a support ticket. A failed receipt is a lost customer. You can't afford for them to land in spam.
The legal and practical definition: a transactional email is sent in response to an action taken by a specific user, contains information they requested or that is directly related to a transaction they initiated. Key characteristics:
The gray zone is product email: onboarding drips, feature tips, check-ins. Technically not transactional, but closely tied to product usage. Many teams route these through the same infrastructure but keep them on a separate sending domain for deliverability hygiene.
Three reasons you can't use regular email infrastructure for transactional sends at any meaningful scale:
Gmail limits you to 500 emails/day (10,000 via Google Workspace). A mid-sized app sends 10K+ transactional emails a day. Even "SMTP via web host" caps out fast and isn't built for concurrent triggered sends.
Shared hosting IPs are frequently on blocklists. A transactional email service maintains dedicated IPs, manages bounce handling, and monitors sender reputation — things you don't want to own yourself.
You need to know if your password reset was delivered. SMTP gives you nothing. A proper service gives you delivery status, open tracking, bounce handling, and webhooks to act on events in real time.
Under the hood, every email service is a layer on top of SMTP infrastructure. The difference is what they add on top:
Here's how the main options compare for a typical SaaS application sending 50K emails/month:
| Service | Price (50K/mo) | Sequences | BYOK | Best for |
|---|---|---|---|---|
| tinysend | ~$5 (BYOK) or $52 | Yes | Yes | Developer-first, full platform |
| Amazon SES | $5 | No | — | Low cost, high volume infra |
| Postmark | $50 | No | No | Best raw deliverability |
| SendGrid | $89.95 | Yes | No | Enterprise / Salesforce stack |
| Mailgun | $35 | No | No | Infrastructure, good API |
| Resend | $20 | No | No | Clean API, React templates |
Marketing pages all claim "99.9% deliverability." Here's what to actually dig into:
Here's a complete working example for a password reset email using tinysend:
// server/routes/auth.ts
import { Tinysend } from '@tinysend/node'
const email = new Tinysend({ apiKey: process.env.TINYSEND_API_KEY })
export async function POST(req: Request) {
const { emailAddress } = await req.json()
// Generate reset token (store in DB with expiry)
const token = crypto.randomUUID()
await db.passwordResets.create({
email: emailAddress,
token,
expiresAt: new Date(Date.now() + 60 * 60 * 1000) // 1 hour
})
// Send transactional email
await email.send({
from: '[email protected]',
to: emailAddress,
subject: 'Reset your password',
template: 'password-reset',
variables: {
resetUrl: `https://app.yourdomain.com/reset?token=${token}`,
expiresIn: '1 hour'
}
})
return Response.json({ ok: true })
}tinysend handles transactional sends, drip sequences, contact management, and BYOK — all in one API. Free tier, no credit card required.
Start for free →