Choose a sending service, verify your sending domain with DNS records, and create an API key. Build each message as a template, send it from your app through the API or SMTP, and track bounces and complaints with webhooks. Send a test to several mailbox providers before going live, then keep watching delivery.
The password reset that never arrives
A customer clicks forgot password, waits, refreshes their inbox, checks spam, and gives up. You never hear about it. That's the trouble with transactional email: the receipt, the reset link, the shipping notice. When it works, nobody notices. When it fails, it fails silently, and you lose the customer before you know there was a problem.
Transactional emails are triggered by something a user does in your app, which makes them different from a marketing broadcast. People expect them within seconds, and they often can't carry on without them. So the goal isn't clever copy. It's reliable delivery, every time, and a way of knowing when it didn't happen.
What you'll need before the first send
- A sending service with an API or SMTP access.
- A domain you control, ideally with a subdomain set aside for app mail.
- Access to your DNS settings, to publish the records the provider gives you.
- Somewhere safe in your app to keep secrets, such as environment variables.
- A short list of the messages your app sends: receipts, resets, notifications.
Setting up sending in six steps
- Pick a provider and add your sending domain. Every service in the table below starts here. Using a subdomain for app mail keeps it separate from the rest of your email, and sending from a domain you control is the basis of deliverability.
- Publish the authentication records in your DNS. The provider gives you the records; you add them, then wait for the provider to confirm they're verified. Authentication tells mailbox providers the mail is really yours. If you already send through other services, keep your SPF record within the lookup limit the SPF standard sets, and publish only one SPF record for the domain.
- Create an API key or SMTP credentials and store them as secrets. Keep them in your app's secret storage, never in the code repository. Anyone with the key can send as you.
- Build each message as a reusable template. A receipt, a reset and a notification each get their own template, sent from your app through the API or SMTP. Templates keep the wording consistent and let you change copy without a deploy. Resend lets you write templates in React, which suits teams already working in that framework.
- Add webhooks for bounces, complaints and delivery. Your app should learn what happened to each message, and stop sending to addresses that bounce. Postmark lists webhooks among its features, so check whichever provider you pick offers the same before you commit.
- Test across mailbox providers before going live. Send real messages to accounts at several providers and check the message headers show authentication passing. A test catches DNS mistakes before customers do.
Keep receipts and newsletters on separate tracks
Here's the setup rule that saves the most grief later. Mailbox providers judge your mail by its reputation, and reputation is shared by everything sent from the same place. If your marketing emails draw complaints, or a list import fills your sends with dead addresses, your password resets can suffer for it, even though nobody ever complained about a reset.
That's why providers build in ways to keep the two apart. Postmark offers message streams for separating kinds of email, so transactional mail and broadcasts don't travel together. Amazon SES offers dedicated, shared or owned IP options, which gives larger senders control over which mail shares an address. And using a subdomain for app mail, as in step one, keeps your transactional sending apart from the email your team sends day to day.
Bounces are the other half of the same problem. Repeated sends to addresses that don't exist damage your reputation, and the damage builds up quietly. So the webhooks from step five aren't a nice extra. Wire them up so that a hard bounce marks the address in your own database, and your app stops trying it. The same goes for complaints: if someone marks a message as spam, stop sending to them.
Some platforms handle both transactional and marketing email in one place, which is convenient. If you go that way, use whatever separation the provider gives you, and don't let a newsletter blast share a lane with your receipts.
Five email services compared
| Service | Type | Ways to send | Stands out for |
|---|---|---|---|
| Postmark | Email API and SMTP service | API, SMTP, templates, inbound email, webhooks | Message streams for separating kinds of email |
| Resend | Email API for developers | SDKs for many languages, REST, SMTP, webhooks | React-based templates |
| Mailgun | Transactional email API | An API with documentation and SDKs | Developer-focused API |
| Twilio SendGrid | Email API | A standalone platform for high-volume mail | Transactional and marketing in one platform |
| Amazon SES | Cloud email service | API or SMTP from your applications | Dedicated, shared or owned IP options |
If you're choosing between two of the bigger names, my comparison of SendGrid and Mailgun for app email sets them side by side. For other options in the same space, see these other transactional email services and this rundown of more developer-first email APIs.
My advice: wire up bounces before you write a single template
It's tempting to start with the nice part, the email design. Start with the plumbing instead. Verify the domain, store the key as a secret, connect the webhooks and make your app stop sending to bad addresses. Then build the templates. Keep transactional mail on its own subdomain or stream from the first day, because separating it later, once your reputation's already mixed up with your newsletters, is much harder than doing it now.
Want AI doing the heavy lifting in your marketing?
I build the systems that handle the boring 80 percent, so you get your week back. Done properly, with the human kept in.
Want your tool on this list? Featured spots and reviews here are paid partnerships. Here's how to partner with me.
Frequently asked questions
What is a transactional email?
It's an email triggered by a user's action in your app, such as a receipt, password reset or notification, rather than a marketing broadcast.
Should I use SMTP or an API?
You can often choose. Amazon SES's page, for example, describes an API or SMTP interface. An API gives you more control, while SMTP is easier to retrofit into an existing app.
Can I send transactional and marketing email from the same service?
Some services do both. SendGrid's page describes a platform for transactional and marketing email. If you go that way, use any separation the provider offers for different email types.
How do I know if an email bounced?
Use webhooks. Resend's page lists events for delivered, bounced, complained and clicked emails, which your app can use to stop sending to bad addresses.
Do I need to verify my domain?
Yes. Set up the authentication records your provider asks for, and keep your SPF record within the lookup limit.


