Email is part of almost every modern application. Whether you are building an e-commerce store, a SaaS product, or a mobile app, you will eventually need to send emails automatically: a welcome message, a password reset link, an order confirmation.
These are called transactional emails, and there are two common ways to send them: SMTP and an email API. This guide explains both, shows a small code example for each, and covers the practices that help your emails actually reach the inbox.
Disclosure: I'm part of the team behind Sendzovo, which is mentioned near the end of this article. The rest of the guide applies to any email provider.
What are transactional emails?
Transactional emails are automated messages sent to a user after they do something in your app. Common examples:
- Welcome emails after registration
- Password reset emails
- Email verification links
- Order confirmations and payment receipts
- Account activity notifications
Unlike newsletters or promotions, users expect these messages right away, and they often can't continue without them. That is why delivery matters so much.
Option 1: SMTP
SMTP (Simple Mail Transfer Protocol) is the standard protocol for sending email between servers. With an email delivery service, you put the provider's SMTP host and credentials into your app, and your app hands each message to that server.
The flow looks like this:
- A user performs an action in your app.
- Your app builds the email.
- The email is sent to the SMTP server.
- The receiving mail server processes the message.
- The message is delivered to the inbox, subject to filtering and delivery policies.
SMTP is supported by almost every language, framework, and CMS, which makes it a good fit when you already have an SMTP-based setup.
Here is an example with Node.js and Nodemailer. First, install it:
npm install nodemailer These examples use ES modules, so add "type": "module" to your package.json (or save the file as .mjs). They also assume Node.js 18 or later.
Keep credentials in environment variables, never in your source code. For example, in a .env file (and never commit it to Git):
SMTP_HOST=your-smtp-host SMTP_USER=your-smtp-username SMTP_PASS=your-smtp-password Load them with the dotenv package, or run your script with Node's --env-file=.env flag (Node.js 20.6+). Then send the email:
import nodemailer from "nodemailer"; const transporter = nodemailer.createTransport({ host: process.env.SMTP_HOST, port: 587, auth: { user: process.env.SMTP_USER, pass: process.env.SMTP_PASS, }, }); await transporter.sendMail({ from: "no-reply@yourdomain.com", to: "user@example.com", subject: "Reset your password", text: "Click the link to reset your password.", }); Option 2: An email API
An email API lets you send email with a plain HTTP request instead of an SMTP connection. You authenticate with an API key, send a JSON body, and handle the response in your code.
The workflow:
- Get API credentials from your email provider.
- Store the key securely on your server.
- Build the request with the recipient, subject, and content.
- Send the authenticated HTTP request.
- Handle the API response, including errors.
A generic example (the exact endpoint and field names depend on your provider, so check their documentation):
const response = await fetch(process.env.EMAIL_API_URL, { method: "POST", headers: { Authorization: `Bearer ${process.env.EMAIL_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ from: "no-reply@yourdomain.com", to: "user@example.com", subject: "Reset your password", text: "Click the link to reset your password.", }), }); if (!response.ok) { // log the error and decide whether to retry console.error("Email request failed:", response.status); } SMTP vs email API
Both get the message out. They differ in how you connect.
| SMTP | Email API | |
|---|---|---|
| Connection | SMTP protocol | HTTP requests |
| Authentication | SMTP credentials | API key |
| Integration | Configure host and credentials | Call the API from your code |
| Good fit for | Existing SMTP-based systems, CMS plugins | Modern apps and custom integrations |
If your framework or tool already speaks SMTP, start there. If you want more control from your own code, use the API. Many teams use both.
Best practices for reliable delivery
Sending is only half the job. Getting the email into the inbox is the other half.
1. Authenticate your domain
Set up SPF, DKIM, and DMARC records for your sending domain.
- SPF lists which servers may send email for your domain.
- DKIM adds a cryptographic signature so receivers can check the message was not altered.
- DMARC tells receivers what to do when SPF or DKIM checks fail, and gives you reports.
2. Verify email addresses
Typos and fake addresses cause bounces, and bounces hurt your sender reputation. Check addresses before you send, for example at signup. Useful checks include syntax, whether the domain has valid mail records (MX), and whether the address uses a disposable domain.
3. Keep content clear and relevant
Use a meaningful subject line and keep the message focused on what the user just did. A password reset email should look like a password reset email.
4. Separate transactional and marketing email
They build different reputations. Keep critical messages like receipts and password resets apart from promotional sends, ideally on a different subdomain.
5. Monitor what happens after sending
Watch delivery, bounces, and complaints so you can spot problems early, and stop sending to addresses that keep bouncing.
6. Protect your credentials
Never expose SMTP passwords or API keys in frontend code or public repositories. Store them on the server as environment variables, and rotate them if they leak.
How Sendzovo fits in
Sendzovo is a transactional email delivery and email verification platform. In short, it offers:
- Email delivery over SMTP and a REST API
- Email verification, for single addresses or lists, plus a verification API
- Message streams and email templates
- Delivery health, email activity, and suppression tools in the dashboard
SMTP and API credentials are created automatically once you add and verify a sending domain.
If you'd like to see how to get started with Sendzovo, here is a short walkthrough:
If you just want to check an address, there is also a Free Email Checker that shows whether an address looks deliverable, risky, or undeliverable.
Final thoughts
SMTP and email APIs both work well for transactional email. SMTP is familiar and widely supported. An API gives you HTTP-based control from your own code. Whichever you choose, authenticate your domain, verify addresses, and keep an eye on your delivery results.
If you have questions about either approach, leave a comment and I'll do my best to help.
Happy coding!
