Resend Email

Transactional email delivery via the Resend API. Handles all outbound email communication including password resets, magic links, portal invitations, document reminders, and billing emails.

Architecture

ComponentPath
Email configbackend/src/lib/email/config.ts (env loading, catch-all parsing)
Email clientbackend/src/lib/email/index.ts
Email servicebackend/src/lib/services/email.ts
Email templatesbackend/src/lib/email-templates/
Intent-based notification servicebackend/src/lib/notifications/notification-service.ts
Queue processorsbackend/src/lib/jobs/processors/notifications.ts, document-reminder.ts, billing-email.ts
Admin template tabledocumentObtainingEmailTemplates (document_obtaining_email_templates)

Configuration

VariablePurpose
RESEND_API_KEYResend API authentication
EMAIL_FROM_ADDRESSSender (default: noreply@notifications.renewa.de)
EMAIL_CATCH_ALL_ADDRESSESComma-separated redirect targets (max 10, validated)
EMAIL_ALLOW_REAL_DELIVERYtrue enables delivery to actual recipients

Secrets live in Infisical (EU) and sync natively to Fly.io. See Deployment Pipeline.

Delivery Safety

Like MessageBird SMS, delivery is flag-gated: unless EMAIL_ALLOW_REAL_DELIVERY=true, every email is redirected to the catch-all addresses (resolveRecipient in lib/email/config.ts). Each environment has a default catch-all mailbox renewa-one-<env>@renewa.de (local, test, preview, development, staging, production).

Email Types

Templates in backend/src/lib/email-templates/ (shared layout in base.ts):

TemplateTrigger
password-resetUser requests reset
magic-linkUser requests magic link login
email-verificationEmail address verification
welcome-emailPortal invitation / account creation
document-reminderAutomated document follow-up
new-document-requestsNew document collection request
escalation-urgent / escalation-lastReminder escalation steps
rejection-bundleBundled document rejection notice
help-responseHelp/support response

Billing emails (invoices etc.) go through backend/src/services/billing/billing-email-service-impl.ts and the billing-email job processor.

Admin-Configurable Templates

The documentObtainingEmailTemplates table allows admins to customize email content for Document Obtaining workflows without code changes. Managed via Admin Dashboard.

Background Processing

Emails are sent asynchronously via the BullMQ notification queue to avoid blocking request handlers:

  1. Caller enqueues an email job (directly or via the intent-based NotificationServiceImpl)
  2. Background Jobs processor (processors/notifications.ts, channel === 'email') picks up the job
  3. Resend API is called with the rendered template
  4. Success/failure is logged; failed sends are retried by the job processor

Template Rendering

Templates use bilingual content following the Internationalization pattern. The recipient’s preferred language determines which version is sent.

Error Handling

  • Failed sends are retried by the job processor
  • Permanent failures are logged and reported to Sentry