Skip to content

Send transactional email on an event

Send a welcome message, a receipt, or an alert. Email is its own subsystem, not a generic HTTP call: it delivers over SMTP through a per-application sender, and the from address must be on a verified domain. SendGrid, Mailtrap, Amazon SES, or any SMTP relay works.

The from address’s domain must be a domain the tenant has verified, or the send is rejected. Register the domain, add the DNS TXT record it returns, then confirm:

POST /api/v1/applications/{application_id}/domains # register -> pending
POST .../domains/{id}/verify/start # returns the TXT record to add
POST .../domains/{id}/verify/check # marks it verified

Point the application at your SMTP relay. The password is write-only and encrypted at rest; tls_mode is none, starttls, or ssl:

PUT /api/v1/applications/{application_id}/outbound-sender
{
"smtp_host": "smtp.sendgrid.net",
"smtp_port": 587,
"tls_mode": "starttls",
"smtp_username": "apikey",
"smtp_password": "<smtp-password>",
"from_address": "hello@yourdomain.com",
"is_active": true
}

The from_address domain must match the verified domain from step 1. (This path requires the deployment’s outbound-sender encryption keyring to be configured.)

A notification is an email template with a recipient rule. {{dotted.path}} placeholders resolve against the send context; recipients are static addresses or a field on the context:

POST /api/v1/applications/{application_id}/notifications
{
"name": "New Contact Alert",
"channel": "email",
"subject_template": "New contact: {{first_name}} {{last_name}}",
"body_template": "A new contact {{first_name}} ({{email}}) was just added.",
"recipient_config": {"type": "static", "addresses": ["ops@yourdomain.com"]},
"settings": {"from_address": "hello@yourdomain.com"}
}

Use {"type": "field", "field": "email"} to send to an address carried in the context instead.

The same notification resource also sends push notifications to your app’s users. With "channel": "push", the subject template is the title, the body template is the message, settings carries the in-app path a tap opens (with an optional collapse_key and badge), and recipients are identity records ({"type": "static", "record_ids": [...]} or a context field holding record ids) instead of addresses. Push needs no SMTP sender, verified domain or email quota; it needs the mobile_distribution capability, your own APNs key and FCM service account, and the app shell. See Push notifications in the app store guide.

Sending is explicit — trigger_events is metadata and does not auto-dispatch. Send from your flow (or a scheduled job) with the template context:

POST /api/v1/notifications/{notification_id}/send
{"context": {"first_name": "Nadia", "last_name": "Okafor", "email": "nadia@example.com"}}

The context supplies both the template values and, for a field recipient, the destination address. The send resolves the application’s sender, enforces the verified-domain gate and per-tenant quota, and delivers over SMTP.