Resend is a developer-first transactional email API for sending, tracking, and managing mail without running your own SMTP. TanStack Ship uses Resend for:
- Magic-link sign-in — one-time login links after email entry (
src/lib/auth.ts) - Email campaigns — admin HTML campaigns delivered via Cloudflare Queues (
email-campaign-queue) - Lifecycle workflows — automated sequence emails (
workflow-queue)
Important
Pushing to GitHub does not update production secrets. Set
RESEND_API_KEYin.dev.vars(local) or viawrangler secret put(production).
Sign Up & API Key
- Register at resend.com
- Go to API Keys → Create API Key
- Copy the key starting with
re_ - Add to local
.dev.vars:
RESEND_API_KEY=re_xxxxxxxx
- For production:
pnpm wrangler secret put RESEND_API_KEY
Good to know
The API key is equivalent to send credentials. Never commit it or expose it in client code. Revoke and rotate immediately if leaked.
Configure EMAIL_FROM
EMAIL_FROM sets the display name and address recipients see:
EMAIL_FROM="TanStack Ship <no-reply@your-domain.com>"
| Requirement | Notes |
|---|---|
| Domain verification | Domain after @ must show Verified in Resend Domains |
| Display name | Quote when it contains spaces, e.g. "My App <no-reply@example.com>" |
| Production storage | Non-sensitive; can live in wrangler.jsonc → vars or as a secret |
Domain & DNS Verification
Add a Domain
- Resend Dashboard → Domains → Add Domain
- Enter your sending root domain (e.g.
your-domain.com) - Add DNS records as shown (typically SPF, DKIM, etc.)
- If DNS is on Cloudflare, try Sign in to Cloudflare to import the first three records
- Add the
_dmarcrecord manually in Cloudflare DNS - When all pass, Status is Verified
Good to know
If verification stalls, click Restart on the Domains page. Keep email DNS records DNS only (grey cloud) — proxying can break verification.
DMARC Phased Policy
| Phase | Record value | Purpose |
|---|---|---|
| Monitor | v=DMARC1; p=none; rua=mailto:dmarc@your-domain.com; pct=100 | Collect reports only |
| Quarantine | v=DMARC1; p=quarantine; rua=mailto:dmarc@your-domain.com; pct=100 | Failures go to spam |
| Reject | v=DMARC1; p=reject; rua=mailto:dmarc@your-domain.com; pct=100 | Block spoofed mail |
Replace rua with a real mailbox for aggregate reports.
Usage in Code
Magic links call the Resend API synchronously during auth:
// src/lib/auth.ts
const resend = new Resend(requireEnv('RESEND_API_KEY'))
await resend.emails.send({
from: requireEnv('EMAIL_FROM'),
to: input.email,
subject: 'Your sign-in link',
html: `<p><a href="${url}">Sign in</a></p>`,
})
Bulk campaigns run in the Queue consumer — see src/server/email-campaign-queue.ts.
Good to know
TanStack Ship does not use
RESEND_SEGMENT_ID. Manage contacts in Resend Audiences or send marketing mail via Dashboard Broadcast.
Environment Variables
| Variable | Secret | Local | Production |
|---|---|---|---|
RESEND_API_KEY | ✓ | .dev.vars | wrangler secret |
EMAIL_FROM | .dev.vars | wrangler.jsonc vars |
Full reference: Environment Variables.
Verification Checklist
After setup, confirm:
- Enter email on sign-in page → magic link triggered
- Resend → Emails shows Delivered
- Resend → Logs shows the API request
- Inbox receives mail; link completes sign-in
- (Optional) Create a test campaign in admin
/dashboard/admin/...and confirm Queue consumption
Warning
If local works but production fails, check
wrangler secret listforRESEND_API_KEYand thatEMAIL_FROMdomain is Verified in production too.