send transactional email (verify, receipts, notifications) with resend. trigger on "send email", "transactional email", "email receipts", or "notify users by email".
---
description: send transactional email with resend. verify, receipts, notifications. trigger on "send email", "transactional email", "email receipts".
---
# transactional email
reliable transactional email without a self-hosted SMTP yak-shave. uses the verified resend module.
## intent
take a builder from "i need to email users" to verified, deliverable transactional email: verification links, receipts, alerts. the failure mode this prevents: fire-and-forget sends that swallow delivery errors, so a broken verification email looks fine in code and fails in production.
## inputs
- a resend account + verified sending domain
- RESEND_API_KEY in env
- the from address on the verified domain
## procedure
### step 1, send
```js
const { Resend } = require('resend');
const resend = new Resend(process.env.RESEND_API_KEY);
const { data, error } = await resend.emails.send({
from: 'you@yourdomain.com', to, subject, html,
});
if (error) throw error; // surface, never swallow
```
### step 2, handle the error path
resend returns { data, error }, not a throw. check error every time or you will ship a silent failure.
### step 3, optional, author the body with react-email
if the project uses react, render templates with react-email for consistent, testable markup.
## decision points
- domain auth: SPF + DKIM on the sending domain or everything lands in spam.
- transactional vs marketing: keep them on separate keys/domains.
- retries: transient 5xx can retry, a 4xx (bad address) should not.
## output contract
a send helper that checks the { data, error } shape on every call, a verified sending domain, and transactional sends isolated from any bulk path.
## outcome signal
success means a verification email arrives in the inbox (not spam) within seconds, and a deliberately bad address surfaces the error in your logs rather than failing silently.
don't have the plugin yet? install it then click "run inline in claude" again.
added env var setup guidance, explicit input validation and error handling branches, rate limit and api key expiry edge cases, structured response shapes for success and failure, and separated decision logic into if-else form.
reliable transactional email without a self-hosted SMTP yak-shave. uses the verified resend module.
take a builder from "i need to email users" to verified, deliverable transactional email: verification links, receipts, alerts. the failure mode this prevents: fire-and-forget sends that swallow delivery errors, so a broken verification email looks fine in code and fails in production. use this when you need guaranteed delivery tracking, not bulk marketing sends.
initialize resend client with api key from env.
call resend.emails.send() with from, to, subject, html.
check the error field on every call. if error exists, throw or log and surface to caller.
(optional) if using react, render template with react-email before passing html to resend.
domain verification required: SPF and DKIM records must be live on sending domain or messages land in spam. verify in resend dashboard before sending production email.
transactional vs marketing: keep transactional (verify, receipt, alert) on one key/domain and marketing (campaigns, newsletters) on a separate key/domain. prevents deliverability bleed if marketing domain gets flagged.
error handling: transient 5xx errors (service temporarily down) can retry with backoff. 4xx errors (bad recipient, invalid domain) should not retry, surface immediately to caller.
empty recipient or missing subject: validate input before calling resend to avoid wasted api calls and unclear failures.
rate limits: resend enforces per-account sending limits. check current plan limits in dashboard. if hit, queue remaining sends or reject with clear error to user.
api key expiry: resend keys do not auto-expire but can be revoked. monitor logs for 401 responses and alert on key rotation.
a send helper function that:
success response shape:
{
"data": {
"id": "12345abc"
},
"error": null
}
error response shape:
{
"data": null,
"error": {
"message": "Invalid recipient email",
"code": "invalid_email"
}
}
success means a verification email arrives in the inbox (not spam) within seconds. a deliberately bad recipient email surfaces the error in logs with code and message, not silent failure. transactional sends stay on the verified domain and do not queue indefinitely or disappear without trace.
credits: original skill by implexa team.