Skip to content

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.

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"]
}
FieldMeaning
smtp_hostSMTP hostname. Resolved at validate time; private-network IPs are blocked unless the channel explicitly opts into them.
smtp_portOne of the allow-listed SMTP ports (25, 465, 587, 2525).
smtp_userUsername.
smtp_passPassword.
smtp_tlstrue for STARTTLS on 587 / implicit TLS on 465.
from_addrFrom: header. RFC 5322 mailbox or display <addr@host> format.
to_addrsDefault 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.

{
"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>"
}
{
"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>"
}
{
"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.

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.