Tutorials Search / Backend integrations / Send transactional email with Resend
📝 Written ● Intermediate Updated 2026-05-13

Send transactional email with Resend

Resend is the developer-first email API — small SDK, generous free tier, real HTML templates. Setup takes ten minutes once you accept that the slow part is configuring DNS for your domain, not writing code.

Sending email from a web app is one of those things that's easy until you actually need to do it. You write a small function that POSTs to an email provider's API. Your test message goes out. It lands in your Gmail inbox. Done. Then production traffic kicks in and the mail starts landing in spam. Or worse, getting rejected by recipient servers entirely. The code is identical; the problem isn't the code.

Email deliverability is mostly a function of three DNS records — SPF, DKIM, and DMARC — that tell receiving servers "yes, this provider is authorized to send mail on behalf of this domain, here's how to verify it." Without them set, modern receivers (Gmail, Apple Mail, Outlook) at best put your mail in spam and at worst reject it. Setting them up is annoying because they have to live on the domain you're sending from, which means changing DNS at your registrar, which means waiting for propagation.

Resend's value proposition is "the email API where this whole dance is the easiest." The dashboard tells you exactly which DNS records to add and verifies them automatically. The SDK is small. The free tier (3,000 emails/month, 100/day) is enough for almost any indie project. Their HTML template story uses React components, which is unusual in this space and notably nicer than dragging a WYSIWYG editor around. This tutorial covers the setup; the principles apply to any modern email provider (Postmark, SendGrid, Loops, etc.) — the specifics are Resend-shaped.

What you'll learn

Step 1: Decide what domain you'll send from

1

Use your real domain

You should send mail from a domain you own — [email protected], not [email protected]. There are two reasons:

  • Trust. Recipients see "from your-real-brand" instead of "from a generic email address that could be anyone."
  • Deliverability. A domain you control can have proper SPF/DKIM/DMARC records. A free email address can't.

If you don't have a domain yet, see the registrar tutorials. You can also use a subdomain dedicated to transactional mail — mail.yourapp.com or notifications.yourapp.com — which is good practice because it isolates your sending reputation from anything else on the root domain.

Step 2: Create a Resend account

2

Sign up at resend.com

Sign up. The free tier gives you 3,000 emails per month and 100 per day, sent from the shared [email protected] domain. That's enough to test the SDK; it's not enough to ship to real users (because mail from resend.dev won't look like it's from you, and recipients may suspect it).

To send from your own domain you need to add and verify it. That's the next step.

Step 3: Add your domain in the dashboard

3

Resend → Domains → Add Domain

Click Add Domain, type the domain (or subdomain) you'll send from, click Add. Resend shows you a list of DNS records to add. Typically 3–5 records: one for SPF, two or three for DKIM (depending on configuration), optionally one for DMARC, and an MX record if you want to also receive bounce notifications back through Resend.

The records look intimidating but you don't need to understand the cryptography — just copy each one verbatim into your DNS provider.

Step 4: Add the records at your DNS provider

4

Match Resend's instructions exactly

For each record Resend shows, go to your DNS provider (see the DNS tutorial if needed) and add:

  • Type: matches what Resend says (TXT, CNAME, MX, etc.).
  • Name/Host: matches exactly. Some providers want just resend; others want resend.yourdomain.com. Either format is fine if used consistently.
  • Value: paste verbatim. Watch for whitespace — DNS values are exact strings.
  • TTL: defaults are fine.

After adding all records, click Verify DNS Records in Resend. Propagation can take minutes to hours. Resend re-checks automatically; you'll get a "verified" status when all records resolve correctly.

What each record actually does: SPF (the TXT record) declares which mail servers are allowed to send for your domain. DKIM (a TXT or CNAME) is a cryptographic signature that proves the mail came from those servers and wasn't tampered with. DMARC (a TXT at _dmarc) tells receivers what to do when SPF or DKIM fail — quarantine, reject, or just report. Together they're the modern "yes, this mail is legitimate" handshake.

Step 5: Get an API key

5

Resend → API Keys → Create

Click Create API Key, name it (e.g., "production"), choose permissions (typically Sending access — restricted scope is better than full access). Copy the key (re_…); you only see it once.

Put it in your backend's env file: RESEND_API_KEY=re_…. As always, never commit to git.

Step 6: Send your first email

6

The SDK call

Install the SDK in your project:

npm install resend
# or: pip install resend, or: gem install resend

Send a test email:

import { Resend } from 'resend';

const resend = new Resend(process.env.RESEND_API_KEY);

await resend.emails.send({
  from: 'You <[email protected]>',
  to: ['[email protected]'],
  subject: 'Hello from Resend',
  html: '<p>This is the body of the email.</p>',
});

Check your recipient inbox. If it arrives, you're done. If it doesn't, check the Resend dashboard's Emails log — it shows every send attempt with its status (delivered, bounced, spam-folder, etc.) and the receiver's response.

Step 7: Real templates with React Email

7

Or any HTML you want

For one-off emails, raw HTML strings work fine. For anything you'll send repeatedly (welcome emails, receipts, password resets), use templates. Resend's official option is React Email — write your email as a React component, render it to HTML at send time.

import { Resend } from 'resend';
import { ReceiptEmail } from './emails/Receipt';

await resend.emails.send({
  from: 'Receipts <[email protected]>',
  to: customer.email,
  subject: `Receipt for $${amount}`,
  react: ReceiptEmail({ customerName: customer.name, amount, items }),
});

React Email components have email-safe primitives (<Container>, <Text>, <Button>) that render to the table-based HTML email clients require. You write modern JSX; the library handles the legacy markup.

Step 8: When emails land in spam

8

The deliverability checklist

Mail in spam usually means one of these is true:

  • DNS records aren't fully verified. Check the Resend dashboard. Some records may have propagated; some not. All must be green.
  • Your From domain doesn't match your DKIM domain. If you set up DKIM for mail.yourdomain.com but send from [email protected], the DKIM signature doesn't authorize the From. Either send from [email protected] or set up DKIM for the root.
  • The content looks spammy. All caps, lots of "FREE!!!", many emoji, weird link patterns. Test with mail-tester.com — it'll give you a score and explain why.
  • You're new and sending in volume. New domains have no sender reputation. Mail providers err on the side of suspicion until you've sent legitimate-looking mail for a week or two. Ramp up gradually.
Never send marketing email from a transactional account. Resend's terms (and similar providers') reserve the transactional tier for non-marketing mail — receipts, password resets, security alerts, notifications. Sending newsletters from a transactional account can get you suspended. Use a separate marketing platform (Loops, Customer.io, ConvertKit) for that.

What's next