Resend, a verified domain, and the sender address that makes confirmation and reset codes land.
Two names, RESEND_API_KEY and EMAIL_FROM, both read by the deployment. Without them the app still runs,
sign in by password still works for confirmed accounts, and nothing that needs a code does.
What uses mail
| Message | When |
|---|---|
| Confirmation code | A new account, before it can be used |
| Password reset code | Somebody who has forgotten their password |
| Support replies | Anything answered from People → Support |
| Team invitations | An invitation to a team, if it is sent rather than copied |
| Receipts and notices | Wherever a payment or a plan change is worth telling somebody about |
Every one of them is a template you can edit in Brand → Emails, with a test-send to any address, and the
support inbox replies with the templates rather than with hard-coded text.
Setting it up
An account, and a domain
resend.com, then Domains → Add domain. Enter the domain the mail will come from,
for example your-domain.com, and Resend shows a handful of DNS records: a couple of TXT records for
ownership and policy, and one or more for the sending itself.
Paste them into whichever DNS provider holds the domain. They are not secret and they are not specific to this product.
Wait for verified
The domain shows Verified when the records have propagated, which is usually minutes and occasionally a few hours. Nothing about the mail works before this: Resend refuses to send from a domain it has not verified, and the refusal arrives as an error rather than as silence.
You can test before the domain is ready
Resend gives every account a sandbox sender that can only send to the address that owns the account. That is enough to test confirmation and reset while DNS settles.
The key
API Keys → Create API key. Name it after the installation, because a month from now there may be several. Choose sending access rather than full access: nothing here needs to manage the account.
The value starts with re_ and is shown once.
The sender
EMAIL_FROM is who the messages appear to come from. Two rules, and both are enforced by the provider
rather than by this app:
- The address must be on a verified domain.
- The name is optional and goes in front, in the form
Name <address@domain.com>.
EMAIL_FROM=Loomis <hello@your-domain.com>Set them on the deployment
npx convex env set RESEND_API_KEY "re_your_key"
npx convex env set EMAIL_FROM "Loomis <hello@your-domain.com>"Add --prod on the production deployment. Then send yourself one from Brand → Emails, which tests the
whole path rather than only the key.
Where the words come from
Brand → Emails holds the sender identity and a template per message. Two things about the templates are worth
knowing:
- They are plain HTML with inline styles, because mail clients are not browsers and a stylesheet is often dropped.
- Values are inserted as text rather than as markup, so a name containing an angle bracket arrives as a name.
The same screen can send a test to any address, which is the fastest way to check a change without creating an account.
When it does not work
Mail is the one thing worth testing with a stranger
Send a real sign-up to an address you do not own, at a provider you do not use, and check that it arrives and looks right. Everything else in the installation can be fixed later; a user who cannot confirm an account has no way in.

