Skip to main content

Resend Integration

Knowledge > Integrations > Resend

What it is / why we use it

Resend is the transactional email provider for all three ChurchWiseAI properties. It handles every system-triggered email: magic links, welcome emails, payment failure alerts, trial ending reminders, ops alerts (WatchTower), and contact form notifications. Unlike MailerLite (which handles marketing and subscriber management), Resend is for one-to-one triggered emails. Each property uses Resend directly with its own RESEND_API_KEY env var. Email templates are inline HTML — no React Email or external template service. All templates follow the ChurchWiseAI brand: navy header gradient, cream background, Sacred Gold CTAs.

Account Info

  • Platform: Resend (resend.com)
  • Account: churchwiseai@gmail.com (assumed; same primary account)
  • Key location: RESEND_API_KEY env var in all three codebases
  • Agent access: Full API access via the resend npm package. Verify delivery by checking Resend dashboard logs or querying email logs if stored.

Sender Addresses By Property

PropertyFrom AddressUsed For
ChurchWiseAIhello@churchwiseai.comWelcome emails, magic links, trial reminders, payment failed, contact confirmations
ChurchWiseAI (WatchTower)hello@churchwiseai.com (display: WatchTower)P0 operational alerts to founder
PewSearchhello@pewsearch.comMagic links, premium welcome, claim notifications, contact form forwarding
IllustrateTheWordhello@illustratetheword.comAccount emails, subscription notifications
ShareWiseAIhello@churchwiseai.comSocial post notifications (Coming Soon; shared sender)

Email Types Per Product

ChurchWiseAI (churchwiseai-web/src/lib/email.ts)

FunctionSubject PatternTrigger
sendPremiumWelcomeEmail"Your ChurchWiseAI dashboard is ready — {church}"Stripe checkout completed, or onboard provision
sendPaymentFailedEmail"Payment Failed — Action Required"Stripe invoice.payment_failed
sendTrialEndingEmail"Your ChurchWiseAI Trial Ends Soon"Cron (daily audit) near trial end
sendVoiceSetupAlertEmailVoice setup notificationNew voice/bundle subscription (internal alert to founder)
sendStarterKitDeliveryEmailStarter Kit deliveryOne-time Starter Kit purchase

WatchTower alerts (/api/ops/alert/route.ts):

  • Subject: [WatchTower P0] {source} — {message}
  • Sent to: ALERT_EMAIL env var (defaults to support@churchwiseai.com)
  • Triggered by the ops collection cron when a P0 error is detected

Magic link resend (/api/onboard/resend-link/route.ts):

  • Same sendPremiumWelcomeEmail template
  • Rate limited to 3/hour per IP
  • Returns 200 regardless of whether the email exists (prevents enumeration)

PewSearch (pewsearch/web/src/lib/email.ts, notifications.ts)

UseTrigger
Magic link / dashboard accessAdmin token lookup request
Premium welcomePewSearch checkout completed
Contact form forwardingChurch website contact form submission (Pro Website feature)
Claim notificationNew church claim submitted
Care broadcastPro Website care messaging (sent as {church} via PewSearch)

IllustrateTheWord (sermon-illustrations/src/lib/email.ts)

UseTrigger
Welcome / account confirmationSupabase Auth signup
Subscription notificationStripe ITW Premium checkout

Key Environment Variables

VariableUsed InPurpose
RESEND_API_KEYAll three codebasesBearer token for Resend API
ALERT_EMAILchurchwiseai-webDestination for WatchTower P0 alerts (defaults to support@churchwiseai.com)
NEXT_PUBLIC_SITE_URLchurchwiseai-webBase URL for magic links (defaults to https://churchwiseai.com)

CLI / API Patterns & Gotchas

Lazy singleton pattern: All three codebases use a lazy singleton for the Resend client to avoid instantiating it outside request scope:

let _resend: Resend | null = null;
function getResend(): Resend {
if (!_resend) _resend = new Resend(process.env.RESEND_API_KEY!);
return _resend;
}

This is safe for Vercel serverless (each invocation reuses the module-level instance within the same warm container).

Magic link format: CWA magic links use the pattern /auth/magic?t={encoded_token} to set an HttpOnly cookie rather than exposing the admin token in the URL bar. Do not change this pattern without updating the auth flow.

Inline HTML templates only: No React Email, no MJML, no external template service. All templates are inline HTML strings in email.ts. Pros: simple, no build step, no import issues. Cons: editing is verbose. When modifying templates, test across Gmail, Apple Mail, and Outlook (or use Litmus/Email on Acid).

PewSearch care broadcast uses raw fetch: PewSearch's care broadcast route (/api/care/broadcast/route.ts) calls the Resend API via raw fetch() rather than the npm package. This is intentional for minimal dependencies on the broadcast route. The pattern is: Authorization: Bearer ${process.env.RESEND_API_KEY} against https://api.resend.com/emails.

FA-007 pending: Agents do not currently have access to john@churchwiseai.com inbox to verify email delivery. Use Resend's dashboard or API logs to confirm deliverability.

Failure Modes & Recovery

FailureBehaviorRecovery
RESEND_API_KEY not setRuntime crash (Resend constructor throws on first send)Set env var immediately; no silent fail unlike MailerLite
Send fails (Resend error)Error logged to console; user flow continues (errors caught)Check Resend dashboard for suppressed addresses or domain issues
Welcome email not receivedUser can request resend via /onboard/resend-linkConfirm email not in spam; check Resend logs for bounces
Magic link expired or reusedUser re-requests via resend endpoint; same welcome email sentToken is permanent until revoked — link doesn't expire by design
WatchTower alert not deliveredOperational alert missedCheck ALERT_EMAIL env var; verify Resend domain DNS (SPF/DKIM)
Domain not verified in ResendEmails go to spam or are rejectedVerify DNS records for churchwiseai.com, pewsearch.com, illustratetheword.com in Resend dashboard

Resend vs. MailerLite — When to Use Which

ScenarioUse
System-triggered, one-to-one email (magic link, payment alert)Resend
Marketing campaign, newsletter blastMailerLite
Subscriber lifecycle automation (onboarding drips, win-back, cross-promo)Resend (lifecycle email system via lifecycle-emails.ts + daily cron)
Operational alert to founderResend (WatchTower)
Care message to congregation memberResend (PewSearch care broadcast)

Cost Model / Usage Limits

  • Free tier: 3,000 emails/month, 100/day
  • Pro tier: Starts at $20/month for 50,000 emails
  • Current volume: Very low (pre-launch; 4 test accounts). Free tier is sufficient until customer scale.
  • Domain verification: Required for custom from addresses. All three property domains must be verified in the Resend account.

See Also

  • MailerLite Integration — subscriber CRM, newsletter management, audience segmentation
  • Stripe Integration — checkout events that trigger welcome and alert emails
  • churchwiseai-web/src/lib/email.ts — all CWA email functions