DEV Community

Cover image for Send Supabase Auth emails through Resend SMTP (with Cloudflare DNS)
Aravind Govindhasamy
Aravind Govindhasamy

Posted on Originally published at starter.budeglobal.in on

Send Supabase Auth emails through Resend SMTP (with Cloudflare DNS)

Out of the box, Supabase Auth sends confirmation, magic-link and password-reset emails through a shared service meant for testing. It only delivers to members of your Supabase team, and only about 2 messages an hour. The first real user who signs up won't get their email. The fix is custom SMTP, and Resend is a quick, developer-friendly option.

What you need

  • A Resend account
  • A domain you control, with DNS on Cloudflare (other DNS hosts work the same way)
  • Your Supabase project

1. Pick a sending domain

Send from a subdomain, such as mail.example.com or auth.example.com, rather than your root domain. It keeps your sending reputation separate from your main domain's mail, and Supabase's own guidance recommends a separate domain for auth emails.

Watch out: the address you send from must be on the domain you verify. If you verify mail.example.com, send from no-reply@mail.example.com. Sending from no-reply@example.com fails with a "domain is not verified" error.

2. Add the domain in Resend

In Resend, go to Domains → Add domain and enter your sending domain. Resend shows the DNS records to add.

On Cloudflare, Resend's Sign in to Cloudflare button can add them for you. To add them by hand, open your zone's DNS → Records and create:

Type Name Content Notes
MX send (or send.mail for a subdomain) the feedback-smtp...amazonses.com value Resend shows Priority 10
TXT send (or send.mail) v=spf1 include:amazonses.com ~all SPF
TXT resend._domainkey (or resend._domainkey.mail) the long p=... value Resend shows DKIM, DNS only

Copy the exact names Resend gives you: for a subdomain they include it. In the Name field, enter only the part before your zone's domain; Cloudflare adds the rest.

Then click Verify in Resend. Records usually propagate in minutes.

Recommended: add a DMARC record too, for example a TXT record named _dmarc with v=DMARC1; p=none; to start, then tighten it once mail flows cleanly.

3. Create an API key

In Resend, go to API Keys → Create API key. For SMTP, a key with Sending access is enough. Copy it now; it's shown once.

4. Turn on custom SMTP in Supabase

In the Supabase dashboard, open Authentication → Emails → SMTP Settings and enable custom SMTP:

Field Value
Sender email no-reply@mail.example.com (on your verified domain)
Sender name Your product name
Host smtp.resend.com
Port 587 (STARTTLS) or 465 (SSL)
Username resend
Password your Resend API key (re_...)

Save. Supabase now sends to any address, starting with a limit of 30 emails an hour; raise it under Authentication → Rate Limits once you're sure the setup is right.

5. Send a test

Sign up with an address outside your team, or trigger a password reset. The email should arrive within seconds, and it shows up in Resend's Emails list with its delivery status. If it doesn't:

  • "Domain is not verified": the sender address isn't on the verified domain (see step 1).
  • Nothing in Resend's list: the SMTP details in Supabase are wrong; re-enter the password.
  • Lands in spam: check SPF and DKIM pass in the message headers, and add DMARC.

6. Send your app's own emails

Invitations and notifications from your API can use the same SMTP details. In FastAPI with the standard library:

import smtplib
from email.message import EmailMessage

msg = EmailMessage()
msg["From"] = "no-reply@mail.example.com"
msg["To"] = "user@example.com"
msg["Subject"] = "You're invited"
msg.set_content("Join the team: https://example.com/invite/abc")

with smtplib.SMTP("smtp.resend.com", 587) as smtp:
    smtp.starttls()
    smtp.login("resend", RESEND_API_KEY)
    smtp.send_message(msg)

Enter fullscreen mode Exit fullscreen mode

Run it in a thread (run_in_threadpool) or a background task so a slow mail server doesn't block requests.

Using it with FastAPI Supabase Starter

Steps 1 to 5 are the same. For the app's own emails (organization invitations and templates from Admin › Messaging ), put the same values in .env:

SMTP_HOST=smtp.resend.com
SMTP_PORT=587
SMTP_USER=resend
SMTP_PASSWORD=re_xxx
EMAILS_FROM_EMAIL=no-reply@mail.example.com

Enter fullscreen mode Exit fullscreen mode

Every message is recorded with its status in the delivery log under Admin › Messaging. More in Email, SMS and WhatsApp.

Top comments (0)