SaaS Starter
Integrations

Resend

Send transactional email (auth, billing, invitations) through Resend — wired to the notifications module's mailer port. Drop-in replacement for SMTP / SendGrid / Postmark.

Status: scaffold. Fill in the sections below before publishing.

What you get

The modules/notifications bounded context owns transactional email. The IMailer port is consumed by iam (verification, password reset, magic-link), tenancy (member invitations), and billing (receipts). UseDeploy ships adapters for SMTP, SendGrid, Postmark, and Resend — switched via MAIL_PROVIDER.

Templates are React Email components rendered at request time, so you get type-checked subject + body + plain-text fallback in one file.

Setup

1. Create the Resend account

In the Resend dashboard:

  1. Verify the sending domain (DNS records: SPF + DKIM).
  2. Create an API key with emails:send scope.

2. Set env vars

# apps/server/.env
MAIL_PROVIDER=resend
RESEND_API_KEY=re_...
MAIL_FROM="UseDeploy <[email protected]>"
MAIL_REPLY_TO="[email protected]"   # optional

With MAIL_PROVIDER unset, the mailer is a no-op (logs the email payload to Pino at info level) — perfect for local dev without burning Resend credits.

3. Test the templates

Each template ships with a Storybook-style preview at /admin/mail/preview (non-production only). Use it to verify rendering before triggering real sends. The preview accepts ?template=auth.verify-email&locale=es query params.

4. Smoke test

Trigger a password-reset flow from /login → forgot password and confirm the email lands in the inbox. Cross-check the Resend dashboard → Logs pane for the message ID.

Where it lives in the codebase

  • apps/server/src/modules/notifications/application/ports/mailer.ts — the port
  • apps/server/src/modules/notifications/infrastructure/resend/ — the adapter
  • apps/server/src/modules/notifications/infrastructure/templates/ — React Email components (auth verify, password reset, magic link, invitation, billing receipt)

On this page