Resend vs SendGrid vs Brevo: Transactional Email APIs 2026
TL;DR
Transactional emails — order confirmations, password resets, notifications — need reliable delivery, not a mailing list platform. Resend is the developer-first newcomer built by former Vercel engineers — it's the only provider with first-class React Email integration, a clean API, and a generous free tier designed for indie hackers and startups. SendGrid (Twilio) is the enterprise standard — built for massive volume (billions of emails per month), IP warming, dedicated IPs, and complex deliverability needs; it's the safe choice for high-volume production. Brevo (formerly Sendinblue) is the EU-first alternative — GDPR-native, servers in Europe, affordable pricing, and both transactional and marketing email in one platform. For startups and developers: Resend. For high-volume enterprise: SendGrid. For GDPR-compliance and EU data residency: Brevo.
Key Takeaways
- Resend free tier: 3,000 emails/month, 100/day — generous for early-stage apps
- SendGrid delivers 100 billion+ emails per month — highest volume capacity
- Brevo stores all data on EU servers — important for GDPR-regulated businesses
- Resend is the only provider built around React Email — templates as JSX components
- SendGrid requires IP warming for dedicated IPs — 30-60 day process for new domains
- Brevo includes marketing email + SMS + transactional in one platform (SendGrid is transactional-only for developers)
- All three have Node.js SDKs with TypeScript support
Why Transactional Email Providers Exist
Sending email directly (SMTP from your server) results in poor deliverability:
Direct SMTP issues:
- New server IP → spam filters flag it as unknown sender
- No feedback loops → you don't know when recipients report spam
- Bounces damage your IP reputation silently
- No DKIM/DMARC management → authentication failures
Email API providers solve:
- Shared or dedicated IP reputation with warm history
- Bounce/spam tracking and automatic unsubscribe
- DKIM signing and DMARC alignment
- Delivery analytics and debugging
Resend: Developer-First Email API
Resend was founded by the team behind Vercel's email infrastructure. It's built around the idea that email should feel like any other API — clean, predictable, and well-documented.
Installation
npm install resend
# Optional: React Email templates
npm install react-email @react-email/components
Basic Email Sending
import { Resend } from "resend";
const resend = new Resend(process.env.RESEND_API_KEY);
// Send a simple text email
const { data, error } = await resend.emails.send({
from: "Acme <onboarding@acme.com>", // Must be from your verified domain
to: ["user@example.com"],
subject: "Welcome to Acme!",
html: "<h1>Welcome!</h1><p>Thanks for joining Acme.</p>",
text: "Welcome! Thanks for joining Acme.", // Plain text fallback
});
if (error) {
console.error("Email failed:", error);
return;
}
console.log("Email ID:", data?.id); // Store for tracking
React Email Templates
// emails/welcome.tsx — React Email component
import {
Html,
Head,
Body,
Container,
Heading,
Text,
Button,
Hr,
Link,
Preview,
} from "@react-email/components";
interface WelcomeEmailProps {
userName: string;
loginUrl: string;
}
export function WelcomeEmail({ userName, loginUrl }: WelcomeEmailProps) {
return (
<Html>
<Head />
<Preview>Welcome to Acme — let's get you started</Preview>
<Body style={{ backgroundColor: "#f6f9fc", fontFamily: "sans-serif" }}>
<Container style={{ maxWidth: "560px", margin: "0 auto", padding: "20px" }}>
<Heading style={{ color: "#333", fontSize: "24px" }}>
Welcome, {userName}!
</Heading>
<Text style={{ color: "#555", lineHeight: "1.6" }}>
Thanks for signing up for Acme. Your account is ready and waiting.
</Text>
<Button
href={loginUrl}
style={{
backgroundColor: "#5469d4",
color: "#ffffff",
padding: "12px 20px",
borderRadius: "6px",
display: "inline-block",
textDecoration: "none",
}}
>
Get Started →
</Button>
<Hr style={{ borderColor: "#e6ebf1", margin: "20px 0" }} />
<Text style={{ color: "#999", fontSize: "12px" }}>
If you didn't create an account, you can ignore this email.
</Text>
</Container>
</Body>
</Html>
);
}
// api/send-welcome.ts — Send React Email template
import { Resend } from "resend";
import { render } from "@react-email/render";
import { WelcomeEmail } from "@/emails/welcome";
const resend = new Resend(process.env.RESEND_API_KEY);
export async function sendWelcomeEmail(userId: string, email: string, name: string) {
const html = await render(
WelcomeEmail({
userName: name,
loginUrl: `https://app.acme.com/login?userId=${userId}`,
})
);
const { data, error } = await resend.emails.send({
from: "Acme <welcome@acme.com>",
to: [email],
subject: `Welcome to Acme, ${name}!`,
html,
});
if (error) throw new Error(`Email failed: ${error.message}`);
return data?.id;
}
Batch Sending
// Send up to 100 emails per batch request
const { data, error } = await resend.batch.send([
{
from: "Acme <notify@acme.com>",
to: "user1@example.com",
subject: "Your weekly report",
html: "<p>Your stats for this week...</p>",
},
{
from: "Acme <notify@acme.com>",
to: "user2@example.com",
subject: "Your weekly report",
html: "<p>Your stats for this week...</p>",
},
]);
Webhooks for Delivery Tracking
// api/webhooks/email.ts — Track delivery events
import type { NextApiRequest, NextApiResponse } from "next";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const event = req.body;
switch (event.type) {
case "email.sent":
console.log("Email sent:", event.data.email_id);
break;
case "email.delivered":
console.log("Email delivered to:", event.data.to);
break;
case "email.bounced":
// Mark user's email as invalid in your database
await markEmailBounced(event.data.to);
break;
case "email.complained":
// User reported as spam — unsubscribe them
await unsubscribeUser(event.data.to);
break;
case "email.opened":
await trackEmailOpen(event.data.email_id);
break;
case "email.clicked":
await trackLinkClick(event.data.email_id, event.data.click.link);
break;
}
res.status(200).json({ received: true });
}
SendGrid: Enterprise-Grade Volume
SendGrid (Twilio) powers email for Airbnb, Spotify, Uber, and other high-volume senders. It's built for reliability at massive scale with granular deliverability controls.
Installation
npm install @sendgrid/mail
Basic Usage
import sgMail from "@sendgrid/mail";
sgMail.setApiKey(process.env.SENDGRID_API_KEY!);
await sgMail.send({
to: "user@example.com",
from: {
email: "noreply@acme.com",
name: "Acme",
},
subject: "Order Confirmation #12345",
text: "Your order has been confirmed.",
html: "<strong>Your order has been confirmed.</strong>",
// Tracking settings
trackingSettings: {
clickTracking: { enable: true },
openTracking: { enable: true },
},
// Custom data attached to this email (for webhook events)
customArgs: {
orderId: "12345",
userId: "user_abc",
},
});
Dynamic Templates
// SendGrid Dynamic Templates — template defined in SendGrid dashboard
// Uses Handlebars syntax: {{name}}, {{#if condition}}...{{/if}}
await sgMail.send({
to: "user@example.com",
from: "orders@acme.com",
templateId: "d-xxxxxxxxxxxxxxxxxxxx", // Template ID from SendGrid dashboard
dynamicTemplateData: {
first_name: "Alice",
order_id: "12345",
items: [
{ name: "Widget A", price: "$29.99", quantity: 2 },
{ name: "Widget B", price: "$49.99", quantity: 1 },
],
total: "$109.97",
tracking_url: "https://track.example.com/12345",
},
});
Sending to Multiple Recipients
// Personalized emails at scale
const messages = users.map((user) => ({
to: user.email,
from: "newsletter@acme.com",
templateId: "d-yyyyyyyyyyy",
dynamicTemplateData: {
name: user.name,
plan: user.plan,
usage: user.currentUsage,
limit: user.usageLimit,
},
customArgs: { userId: user.id },
}));
// Send all in a single API call (up to 1,000 personalizations)
await sgMail.send(messages);
Event Webhooks
// SendGrid calls your webhook for delivery events
export async function handleSendGridWebhook(events: SendGridEvent[]) {
for (const event of events) {
switch (event.event) {
case "delivered":
await db.emailLogs.update({
where: { messageId: event.sg_message_id },
data: { deliveredAt: new Date(event.timestamp * 1000) },
});
break;
case "bounce":
await handleBounce(event.email, event.reason);
break;
case "spamreport":
await handleSpamReport(event.email);
break;
}
}
}
Brevo: EU-First Email Platform
Brevo (formerly Sendinblue) combines transactional email with marketing tools in one platform, with EU data residency and GDPR-native design.
Installation
npm install @getbrevo/brevo
Basic Transactional Email
import * as Brevo from "@getbrevo/brevo";
const transactional = new Brevo.TransactionalEmailsApi();
transactional.setApiKey(
Brevo.TransactionalEmailsApiApiKeys.apiKey,
process.env.BREVO_API_KEY!
);
const email = new Brevo.SendSmtpEmail();
email.subject = "Order Confirmation";
email.htmlContent = "<h1>Your order is confirmed!</h1>";
email.sender = { name: "Acme", email: "orders@acme.com" };
email.to = [{ email: "user@example.com", name: "Alice" }];
email.params = { orderId: "12345" };
const response = await transactional.sendTransacEmail(email);
console.log("Message ID:", response.body.messageId);
Template-Based Sending
// Brevo templates created in the dashboard
await transactional.sendTransacEmail({
to: [{ email: "user@example.com", name: "Alice" }],
templateId: 12, // Numeric template ID from Brevo dashboard
params: {
FIRST_NAME: "Alice",
ORDER_ID: "12345",
ITEMS: [
{ name: "Widget A", price: "€29.99" },
],
TOTAL: "€29.99",
},
sender: { name: "Acme", email: "orders@acme.com" },
});
Feature Comparison
| Feature | Resend | SendGrid | Brevo |
|---|---|---|---|
| Free tier | 3,000/mo, 100/day | 100/day (Forever) | 300/day |
| Paid pricing | $20/mo for 50k | $19.95/mo for 50k | $25/mo for 60k |
| React Email | ✅ Native | ❌ (Handlebars) | ❌ (drag-drop) |
| EU data residency | ❌ (US) | ❌ (US) | ✅ EU servers |
| GDPR features | Basic | Basic | ✅ GDPR-first |
| Marketing email | ❌ | Separate product | ✅ Included |
| IP warming | Shared pool | Manual (dedicated) | Shared/dedicated |
| Dedicated IPs | ❌ | ✅ | ✅ |
| Deliverability tools | Basic | ✅ Advanced | Good |
| TypeScript SDK | ✅ | ✅ | ✅ |
| Webhook events | ✅ | ✅ | ✅ |
| API design | ✅ Modern REST | Good (older) | Good |
| Volume capacity | Medium | ✅ Billions/month | Large |
When to Use Each
Choose Resend if:
- You're building a startup or indie product and want the fastest path to working email
- React Email for type-safe, component-based templates is appealing
- Clean modern API design matters more than enterprise feature breadth
- Volume is under ~500k emails/month
Choose SendGrid if:
- You're at high volume (millions+ of emails per month) and need proven deliverability at scale
- Dedicated IPs with full IP warming control is required
- You need deep integration with Twilio for SMS + email in one platform
- Advanced deliverability analytics and ISP feedback loops are needed
Choose Brevo if:
- EU data residency is a compliance requirement (GDPR, financial services, healthcare)
- You want transactional email + marketing campaigns + SMS in one account
- Affordable pricing for mid-volume senders in Europe
- You need a complete CRM/marketing platform alongside email sending
Deliverability, IP Reputation, and Domain Authentication
Email deliverability is not just about sending — it is about whether your emails reach the inbox rather than the spam folder. All three providers require proper DNS configuration before your emails will achieve good deliverability: DKIM (DomainKeys Identified Mail) signing, SPF record configuration, and ideally DMARC policy setup. Resend's domain setup guide walks through these three records and validates them automatically — most setups take under 30 minutes. SendGrid requires the same records but additionally offers domain authentication with a branded tracking domain (replacing sendgrid.net links with your own domain in tracking pixels and unsubscribe links), which improves deliverability by avoiding the association with SendGrid's shared reputation. Brevo's domain authentication similarly supports custom tracking domains. For high-stakes transactional emails (password resets, payment confirmations), warm your sending domain gradually if it is new — sending thousands of emails from a fresh domain in the first week will trigger spam filters regardless of provider. Start with a few hundred per day and scale over two to three weeks.
Bounce Handling, Unsubscribe Management, and List Hygiene
Bounce and complaint management is operationally critical — repeatedly sending to invalid addresses damages your sender reputation and eventually results in your domain being blocklisted. Resend's webhook events include email.bounced (hard bounce — invalid address) and email.complained (spam report) events that your application should handle by marking the recipient's email address as invalid and suppressing future sends. All three providers maintain automatic suppression lists — once an address hard bounces, they automatically block future sends to that address from your account — but you must also reflect this suppression in your own database to avoid paying for API calls to suppressed addresses. SendGrid's Suppression Manager provides a UI for viewing and managing the suppression list; Resend and Brevo have similar dashboards. For marketing email functionality (Brevo's unified platform strength), CAN-SPAM and GDPR compliance require honoring unsubscribe requests within 10 business days. Brevo's unsubscribe link management handles this automatically in campaign flows, but for Resend and SendGrid transactional sends, you are responsible for implementing your own unsubscribe mechanism.
React Email Template Architecture and Testing
Resend's React Email integration changes the template authoring experience fundamentally. Email HTML has historically been a maintenance nightmare — tables for layout, inline styles required for Gmail compatibility, media queries that only work in some clients, and no component reuse. React Email solves these problems by compiling JSX to email-safe HTML at render time. The <Container>, <Section>, <Column> components generate table-based layouts automatically. The <Button> component applies the bulletproof button pattern (a table-based button that renders correctly in Outlook). Test your React Email templates locally using npx email dev, which launches a browser preview that renders the email in multiple simulated email clients. For production testing across real email clients before launch, integrate with Email on Acid or Litmus — both services render your HTML in 90+ actual email client and device combinations, revealing rendering differences between Gmail, Outlook 2019, Apple Mail, and mobile clients that a browser preview cannot catch. Send test emails to a seed list of real accounts (Gmail, Outlook, Apple Mail) before every major template change.
GDPR Compliance and Data Processing Agreements
For applications serving EU users, email sending involves processing personal data (email addresses, names, event tracking pixels) — making your email provider a data processor under GDPR. You must have a Data Processing Agreement (DPA) with your email provider. SendGrid provides a GDPR DPA through Twilio's compliance portal. Brevo's EU-first architecture means their DPA and data residency commitments are particularly relevant — all processing occurs on EU servers, simplifying your GDPR compliance documentation by keeping data within the EU. Resend's infrastructure is US-based, which means standard contractual clauses (SCCs) are required in your Resend DPA to legitimize EU-to-US data transfers under GDPR. For healthcare applications (HIPAA) or financial services, verify whether your email provider offers a Business Associate Agreement or equivalent compliance certification — Resend is oriented toward developer products and may not provide the compliance artifacts required in regulated industries, while SendGrid (as part of Twilio) has enterprise compliance programs for regulated sectors.
Methodology
Data sourced from official pricing pages for all three providers (as of February 2026), developer documentation, and community reviews on r/webdev, Hacker News, and the Indie Hackers community. Deliverability comparisons from third-party email testing services (Mail-Tester, GlockApps reports). React Email integration verified against official Resend documentation.
Related: Resend vs Nodemailer vs Postmark for Node.js email library comparison, or Novu vs Knock vs Courier for full notification infrastructure including in-app and push.
See also: How to Add Email Sending to Your Node.js App and Best Email Libraries for Node.js in 2026