Every app that has users needs to send emails — welcome messages, password resets, order confirmations. This guide shows you how to set it up cleanly in Node.js using a REST API, with real code you can copy and run today.
What is a transactional email?
Transactional emails are triggered by user actions — not marketing campaigns. Examples include:
- Welcome email when someone signs up
- Password reset link
- Order confirmation
- Account verification
- Invoice or receipt
Unlike newsletters, these emails are sent one at a time in response to something the user did. They have very high open rates and are critical to your product experience.
Prerequisites
- Node.js 18+ installed
- A PrimeTimeMail account (free, no card required)
- Your API key from the dashboard
Step 1 — Get your API key
Sign up at primetimemail.com. After email verification, your API key arrives in your inbox. It looks like ptm_live_.... Keep it safe — treat it like a password.
Step 2 — Send your first email
No SDK needed. Use the native fetch API built into Node.js 18+:
const response = await fetch('https://api.primetimemail.com/v1/send', {
method: 'POST',
headers: {
'X-API-Key': 'ptm_live_your_key_here',
'Content-Type': 'application/json'
},
body: JSON.stringify({
to: 'user@example.com',
subject: 'Welcome to MyApp!',
html: '<h1>Welcome!</h1><p>Thanks for signing up.</p>'
})
});
const data = await response.json();
console.log(data); // { id: '...', status: 'sent' }
Step 3 — Store your API key safely
Never hardcode your API key. Use environment variables:
# .env
PTM_API_KEY=ptm_live_your_key_here
import 'dotenv/config';
const response = await fetch('https://api.primetimemail.com/v1/send', {
method: 'POST',
headers: {
'X-API-Key': process.env.PTM_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
to: 'user@example.com',
subject: 'Welcome!',
html: '<p>Thanks for signing up.</p>'
})
});
Step 4 — Create a reusable email helper
// lib/email.js
export async function sendEmail({ to, subject, html }) {
const res = await fetch('https://api.primetimemail.com/v1/send', {
method: 'POST',
headers: {
'X-API-Key': process.env.PTM_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({ to, subject, html })
});
if (!res.ok) {
const err = await res.json();
throw new Error(err.error || 'Failed to send email');
}
return res.json();
}
Now use it anywhere:
await sendEmail({
to: user.email,
subject: 'Welcome to MyApp!',
html: `<h1>Hey ${user.name}!</h1><p>Thanks for signing up.</p>`
});
Step 5 — Handle errors properly
try {
await sendEmail({
to: newUser.email,
subject: 'Verify your email',
html: `<a href="${verifyUrl}">Verify your email →</a>`
});
} catch (error) {
console.error('Failed to send welcome email:', error.message);
// Don't crash the signup flow — log it and move on
}
Tip: Don't block your signup flow on email sending. Send it async, catch errors silently, and log them for monitoring.
Step 6 — Use custom From name
Set a friendly sender name in your dashboard under Settings → From Name. Instead of noreply@primetimemail.com, your users will see MyApp <noreply@yourdomain.com>.
Full working example
import express from 'express';
import 'dotenv/config';
const app = express();
app.use(express.json());
async function sendEmail({ to, subject, html }) {
const res = await fetch('https://api.primetimemail.com/v1/send', {
method: 'POST',
headers: {
'X-API-Key': process.env.PTM_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({ to, subject, html })
});
if (!res.ok) throw new Error('Email failed');
return res.json();
}
app.post('/register', async (req, res) => {
const { email, name } = req.body;
try {
await sendEmail({
to: email,
subject: 'Welcome to MyApp!',
html: `<h1>Hey ${name}!</h1><p>Your account is ready.</p>`
});
} catch (err) {
console.error('Welcome email failed:', err.message);
}
res.json({ success: true });
});
app.listen(3000);
What's next?
- Add webhooks to track bounces and complaints
- Set up a custom sending domain for better deliverability
- Monitor your email logs in the dashboard
Built with PrimeTimeMail — transactional email API for developers. 3,000 emails/month free.
Top comments (0)