SMTP presets
z4j sends invitation and password-reset emails through the project’s notification channels, not through global env vars. Each email channel is a record in the brain’s notification_channels table with the SMTP config inline. Create one per project and z4j picks the first active email channel when it needs to send.
Channel config schema
Section titled “Channel config schema”An email channel’s config JSON looks like this:
{ "smtp_host": "smtp.gmail.com", "smtp_port": 587, "smtp_user": "you@gmail.com", "smtp_pass": "xxxx-xxxx-xxxx-xxxx", "smtp_tls": true, "from_addr": "z4j <you@gmail.com>", "to_addrs": ["ops@example.com"]}| Field | Meaning |
|---|---|
smtp_host | SMTP hostname. Resolved at validate time; private-network IPs are blocked unless the channel explicitly opts into them. |
smtp_port | One of the allow-listed SMTP ports (25, 465, 587, 2525). |
smtp_user | Username. |
smtp_pass | Password. |
smtp_tls | true for STARTTLS on 587 / implicit TLS on 465. |
from_addr | From: header. RFC 5322 mailbox or display <addr@host> format. |
to_addrs | Default recipient list. For invitation and reset emails the brain overrides this with the recipient address. |
Create the channel via API (POST /api/v1/projects/{slug}/notifications/channels) or via the dashboard’s Notifications page.
Gmail requires an app password (not your account password). Enable 2FA, mint an app password at myaccount.google.com/apppasswords, then create an email channel with:
{ "smtp_host": "smtp.gmail.com", "smtp_port": 587, "smtp_user": "you@gmail.com", "smtp_pass": "xxxx-xxxx-xxxx-xxxx", "smtp_tls": true, "from_addr": "z4j <you@gmail.com>"}OAuth2 against Gmail is not supported; SMTP + app password only.
Mailgun
Section titled “Mailgun”{ "smtp_host": "smtp.mailgun.org", "smtp_port": 587, "smtp_user": "postmaster@mg.yourdomain", "smtp_pass": "<mailgun smtp password>", "smtp_tls": true, "from_addr": "z4j <noreply@yourdomain>"}Brevo (formerly Sendinblue)
Section titled “Brevo (formerly Sendinblue)”{ "smtp_host": "smtp-relay.brevo.com", "smtp_port": 587, "smtp_user": "<your brevo smtp login>", "smtp_pass": "<your smtp key>", "smtp_tls": true, "from_addr": "z4j <noreply@yourdomain>"}AWS SES
Section titled “AWS SES”{ "smtp_host": "email-smtp.us-east-1.amazonaws.com", "smtp_port": 587, "smtp_user": "<SES SMTP username>", "smtp_pass": "<SES SMTP password>", "smtp_tls": true, "from_addr": "z4j <noreply@verified-domain>"}SES requires a verified sender domain.
No-email fallback
Section titled “No-email fallback”Without any active email channel on a project, invite and reset flows still work: the dashboard / CLI surfaces the single-use URL directly so the operator can deliver it out-of-band. Everything functions; just less automated.