---
name: railway-email-configuration
description: Configure Railway email settings for multi-client deployments using Resend. Use when setting up email configuration, verifying Resend domains, or updating Railway environment variables for email functionality.
---

# Railway Email Configuration

## Overview

Resend SMTP for API services across **yeshuman**, **bookedai**, **talentco**, **lumie**, **recruitrtech**, **lortsmith**. Cross-service **`${{ }}`** rules: [`.cursor/rules/railway.mdc`](../../.cursor/rules/railway.mdc).

## Required variables (API service)

**SMTP**

- `EMAIL_HOST`: `smtp.resend.com`
- `EMAIL_PORT`: `587`
- `EMAIL_USE_TLS`: `True`
- `EMAIL_HOST_USER`: `resend`
- `EMAIL_HOST_PASSWORD`: `'${{RESEND_API_KEY}}'` (same service; avoids duplicating the secret)
- `DEFAULT_FROM_EMAIL`: `noreply@<verified-domain>`
- `RESEND_API_KEY`: set once on the service

**Frontend URL templates (interpolation)**

- `FRONTEND_EMAIL_VERIFY_URL`: `https://${{<client>-ui.RAILWAY_PUBLIC_DOMAIN}}/auth/verify-email/{key}`
- `FRONTEND_PASSWORD_RESET_URL`: `https://${{<client>-ui.RAILWAY_PUBLIC_DOMAIN}}/auth/reset-password/{key}`
- `FRONTEND_SIGNUP_URL`: `https://${{<client>-ui.RAILWAY_PUBLIC_DOMAIN}}/auth/signup`
- `FRONTEND_INVITE_URL`: `https://${{<client>-ui.RAILWAY_PUBLIC_DOMAIN}}/auth/invite/{key}`

**Service name in `${{ }}`** must match the Railway graph exactly (e.g. `lumie-ui`, not a guess).

## Client domain mappings

| Client | Domain | From email |
|--------|--------|------------|
| yeshuman | yeshuman.io | noreply@yeshuman.io |
| bookedai | booked.ai | noreply@booked.ai |
| talentco | app.talentco.io | noreply@app.talentco.io |
| lumie | lumie.health | noreply@lumie.health |
| recruitrtech | recruitr.tech | noreply@recruitr.tech |
| lortsmith | lortsmith.cc | noreply@lortsmith.cc |

## CLI: link and set (canonical)

From **`api/`** with **`RAILWAY_API_TOKEN`** exported (see [railway-cli-local-auth](../railway-cli-local-auth/SKILL.md)):

```bash
railway link --project <slug> --environment production --service <client>-api
railway variable set \
  EMAIL_HOST=smtp.resend.com \
  EMAIL_PORT=587 \
  EMAIL_USE_TLS=True \
  EMAIL_HOST_USER=resend \
  EMAIL_HOST_PASSWORD='${{RESEND_API_KEY}}' \
  DEFAULT_FROM_EMAIL='noreply@<client-domain>' \
  FRONTEND_EMAIL_VERIFY_URL='https://${{<client>-ui.RAILWAY_PUBLIC_DOMAIN}}/auth/verify-email/{key}' \
  FRONTEND_PASSWORD_RESET_URL='https://${{<client>-ui.RAILWAY_PUBLIC_DOMAIN}}/auth/reset-password/{key}' \
  FRONTEND_SIGNUP_URL='https://${{<client>-ui.RAILWAY_PUBLIC_DOMAIN}}/auth/signup' \
  FRONTEND_INVITE_URL='https://${{<client>-ui.RAILWAY_PUBLIC_DOMAIN}}/auth/invite/{key}'
```

Use **`railway variable`** (`list` / `set` / `delete`). Avoid **`variable list --json`** in shared or agent logs (secrets).

## Resend domain verification

Before using a domain for `DEFAULT_FROM_EMAIL`, verify it in Resend (SPF/DKIM/DMARC per Resend dashboard). Snapshot audits: [`docs/RAILWAY_EMAIL_CONFIG_AUDIT.md`](../../docs/RAILWAY_EMAIL_CONFIG_AUDIT.md), [`docs/RESEND_DOMAIN_VERIFICATION_AUDIT.md`](../../docs/RESEND_DOMAIN_VERIFICATION_AUDIT.md) — **procedures live here +** [`api/env.example`](../../api/env.example).

## Verification (local)

```bash
cd api
uv run python manage.py check_resend_domains --all-env-files
```

Per-client: `uv run python manage.py check_resend_domains --client yeshuman --api-key <key>`

## Common issues

- **Onboarding Resend domain in `DEFAULT_FROM_EMAIL`:** switch to a verified domain.
- **Raw key in `EMAIL_HOST_PASSWORD`:** use `'${{RESEND_API_KEY}}'`.
- **Broken email links:** ensure full `https://` and correct `<client>-ui` name in `${{ }}`.

## Reference

- Command implementation: `api/apps/accounts/management/commands/check_resend_domains.py`
