HelloJohn / docs
Self-Hosting

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 | none

Provider 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
  1. Sign up at resend.com
  2. Add and verify your domain
  3. Create an API key under API Keys
  4. 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.com

With Postmark, both SMTP_USER and SMTP_PASSWORD are 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.com

Amazon 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.com

Generate 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.com

Testing Your SMTP Configuration

Use the HelloJohn CLI to send a test email:

hj email test --to you@example.com

Or 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

TemplateTrigger
verificationUser signs up with email
magic_linkUser requests passwordless sign-in
password_resetUser requests password reset
mfa_otpEmail OTP MFA is triggered
invitationUser is invited to an organization
welcomeAfter 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

VariableDescription
{{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_HOST and HELLOJOHN_SMTP_PORT are 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) vs tls (port 465)
  • Set HELLOJOHN_SMTP_TLS=none only for trusted internal SMTP servers

On this page