DEV Community

Omni Genz
Omni Genz

Posted on Originally published at omnigenz.site

Send app emails through the Brevo SMTP relay with Node.js (Nodemailer)

A shorter, code-first version of a guide first published on Omni Genz.

If your app's password resets and order receipts keep vanishing, sending straight from your web server is often the problem. Big inboxes don't trust mail from a random host. An SMTP relay fixes that: your app hands the email to a server built for sending, and the relay delivers it.

Brevo (formerly Sendinblue) includes its SMTP relay on every plan, including the free one (300 emails a day, according to Brevo's pricing page). Here's how to wire it into a Node.js app.

1. Get your SMTP details

In Brevo, go to Settings > SMTP & API > SMTP. You need:

Setting Value
Host smtp-relay.brevo.com
Port 587 (try 2525 if your host blocks 587, or 465 for SSL)
Username The SMTP login shown on that page
Password An SMTP key, not your Brevo password and not an API key

Generate the SMTP key on the same tab. You only see it once, so put it straight into your secrets manager or .env file.

2. Install Nodemailer

npm install nodemailer dotenv
Enter fullscreen mode Exit fullscreen mode
# .env
BREVO_SMTP_LOGIN=your-login-from-the-smtp-page
BREVO_SMTP_KEY=your-smtp-key
MAIL_FROM="Your App <hello@yourdomain.com>"
Enter fullscreen mode Exit fullscreen mode

3. Create the transport and send

require('dotenv').config();
const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({
  host: 'smtp-relay.brevo.com',
  port: 587,
  secure: false, // STARTTLS on 587; set true only for port 465
  auth: {
    user: process.env.BREVO_SMTP_LOGIN,
    pass: process.env.BREVO_SMTP_KEY,
  },
});

async function sendReset(to, link) {
  const info = await transporter.sendMail({
    from: process.env.MAIL_FROM,
    to,
    subject: 'Reset your password',
    text: `Use this link to reset your password: ${link}`,
    html: `<p>Use this link to reset your password:</p><p><a href="${link}">${link}</a></p>`,
  });
  console.log('Queued:', info.messageId);
}

transporter.verify()
  .then(() => sendReset('you@example.com', 'https://example.com/reset/123'))
  .catch(console.error);
Enter fullscreen mode Exit fullscreen mode

transporter.verify() checks the login before you send anything, which saves a lot of guessing.

4. Fix "535 Authentication failed"

This is the error almost everyone hits once. Common causes:

  • You used smtp-relay.brevo.com as the username. Use the login from the SMTP page.
  • You used your account password or an API key. Use an SMTP key.
  • Extra spaces or a line break came along when you pasted the key.
  • secure: true on port 587, or secure: false on 465. Match them.
  • The key was switched off. Brevo disables keys that haven't sent a good email in 90 days, so generate a new one.

5. Before you go live

Add and authenticate your sending domain in Brevo (SPF, DKIM and DMARC) and use a from address on that domain. Then send a test to yourself, check inbox and spam, and look under Transactional > Logs in Brevo to see what happened to it.

The full guide, with the step-by-step key setup and the port table, is here: What is an SMTP relay? Brevo SMTP relay setup guide.

Top comments (0)