SMTP Configuration
Configure transactional email for self-hosted HelloJohn — SMTP settings, provider recommendations, and email template setup.
SMTP Configuration
HelloJohn sends transactional emails for verification, magic links, MFA codes, and invitations. You must configure an email provider before enabling these features.
Environment Variables
Set these variables in your environment or .env file:
# SMTP connection
HELLOJOHN_SMTP_HOST=smtp.resend.com
HELLOJOHN_SMTP_PORT=587
HELLOJOHN_SMTP_USER=resend
HELLOJOHN_SMTP_PASSWORD=re_your_api_key
# From address
HELLOJOHN_EMAIL_FROM=noreply@example.com
HELLOJOHN_EMAIL_FROM_NAME=Example App
# TLS (recommended)
HELLOJOHN_SMTP_TLS=starttls # Options: starttls | tls | noneProvider Configuration
Resend
HELLOJOHN_SMTP_HOST=smtp.resend.com
HELLOJOHN_SMTP_PORT=587
HELLOJOHN_SMTP_USER=resend
HELLOJOHN_SMTP_PASSWORD=re_your_api_key_here
HELLOJOHN_SMTP_TLS=starttls
HELLOJOHN_EMAIL_FROM=noreply@yourdomain.com- Sign up at resend.com
- Add and verify your domain
- Create an API key under API Keys
- Use the API key as
HELLOJOHN_SMTP_PASSWORD
Postmark
HELLOJOHN_SMTP_HOST=smtp.postmarkapp.com
HELLOJOHN_SMTP_PORT=587
HELLOJOHN_SMTP_USER=your_server_api_token
HELLOJOHN_SMTP_PASSWORD=your_server_api_token
HELLOJOHN_SMTP_TLS=starttls
HELLOJOHN_EMAIL_FROM=noreply@yourdomain.comWith Postmark, both
SMTP_USERandSMTP_PASSWORDare set to the same Server API Token.
SendGrid
HELLOJOHN_SMTP_HOST=smtp.sendgrid.net
HELLOJOHN_SMTP_PORT=587
HELLOJOHN_SMTP_USER=apikey
HELLOJOHN_SMTP_PASSWORD=SG.your_api_key_here
HELLOJOHN_SMTP_TLS=starttls
HELLOJOHN_EMAIL_FROM=noreply@yourdomain.comAmazon SES
HELLOJOHN_SMTP_HOST=email-smtp.us-east-1.amazonaws.com
HELLOJOHN_SMTP_PORT=587
HELLOJOHN_SMTP_USER=AKIAIOSFODNN7EXAMPLE
HELLOJOHN_SMTP_PASSWORD=your_smtp_password_from_ses_console
HELLOJOHN_SMTP_TLS=starttls
HELLOJOHN_EMAIL_FROM=noreply@yourdomain.comGenerate SMTP credentials in the SES console under Account → SMTP settings.
Mailgun
HELLOJOHN_SMTP_HOST=smtp.mailgun.org
HELLOJOHN_SMTP_PORT=587
HELLOJOHN_SMTP_USER=postmaster@mg.yourdomain.com
HELLOJOHN_SMTP_PASSWORD=your_mailgun_smtp_password
HELLOJOHN_SMTP_TLS=starttls
HELLOJOHN_EMAIL_FROM=noreply@yourdomain.comTesting Your SMTP Configuration
Use the HelloJohn CLI to send a test email:
hj email test --to you@example.comOr via the Admin API:
curl -X POST "https://api.hellojohn.dev/v1/admin/email/test" \
-H "Authorization: Bearer sk_live_abc123" \
-H "X-Tenant-ID: tnt_01HABCDEF654321" \
-H "Content-Type: application/json" \
-d '{"to": "you@example.com"}'A test email is sent to the specified address. If delivery fails, check the error field in the response for connection details.
Emails Sent by HelloJohn
| Template | Trigger |
|---|---|
verification | User signs up with email |
magic_link | User requests passwordless sign-in |
password_reset | User requests password reset |
mfa_otp | Email OTP MFA is triggered |
invitation | User is invited to an organization |
welcome | After first sign-in (optional) |
Customizing Email Templates
Override the default templates via the Admin API or dashboard.
List Available Templates
curl "https://api.hellojohn.dev/v1/admin/email/templates" \
-H "Authorization: Bearer sk_live_abc123" \
-H "X-Tenant-ID: tnt_01HABCDEF654321"Update a Template
curl -X PUT "https://api.hellojohn.dev/v1/admin/email/templates/verification" \
-H "Authorization: Bearer sk_live_abc123" \
-H "X-Tenant-ID: tnt_01HABCDEF654321" \
-H "Content-Type: application/json" \
-d '{
"subject": "Verify your {{app_name}} account",
"html": "<h1>Hello {{user.first_name}}</h1><p>Click <a href=\"{{url}}\">here</a> to verify.</p>",
"text": "Hello {{user.first_name}},\n\nVerify here: {{url}}"
}'Available Template Variables
| Variable | Description |
|---|---|
{{url}} | The action link (verification, reset, etc.) |
{{user.email}} | Recipient email address |
{{user.first_name}} | User's first name |
{{user.last_name}} | User's last name |
{{app_name}} | Your tenant's display name |
{{otp}} | One-time passcode (MFA OTP template only) |
{{expires_in}} | Link expiry (e.g., "24 hours") |
{{inviter_name}} | Who sent the invitation (invitation template only) |
{{org_name}} | Organization name (invitation template only) |
Templates use Handlebars-style {{variable}} syntax.
Domain Authentication
For good deliverability, authenticate your sending domain:
SPF Record
Add to your DNS:
TXT @ "v=spf1 include:youresp.com ~all"Replace youresp.com with your ESP's SPF include value (e.g., _spf.google.com for Google Workspace, amazonses.com for SES).
DKIM
Your ESP provides a DKIM DNS record to add. Example (Resend):
TXT resend._domainkey "v=DKIM1; k=rsa; p=YOUR_PUBLIC_KEY"DMARC
TXT _dmarc "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com"Start with p=none during testing, then move to quarantine or reject.
Troubleshooting
Connection refused
- Check that
HELLOJOHN_SMTP_HOSTandHELLOJOHN_SMTP_PORTare correct - Verify firewall allows outbound TCP on port 587 (or 465 for TLS)
- Some cloud providers block port 25 — use 587 (STARTTLS) instead
Authentication failed
- Double-check username and password
- For Gmail: enable "App passwords" (not your Google account password)
- For SES: use SMTP credentials (not your AWS IAM credentials)
Emails going to spam
- Verify SPF, DKIM, and DMARC records
- Ensure your sending domain is warmed up
- Check your ESP's reputation dashboard
TLS errors
- Try
HELLOJOHN_SMTP_TLS=starttls(port 587) vstls(port 465) - Set
HELLOJOHN_SMTP_TLS=noneonly for trusted internal SMTP servers