Skip to content

Notifications

Wire each realm to your own SMS, email and push providers, and craft the templates that carry one-time codes, magic links and alerts.

What it is

HelixIAM delivers messages — OTP codes, magic links, push challenges and account notices — through per-realm messaging providers that you configure from the console. Nothing is hard-wired to a single vendor: pick the driver that fits each channel.

Channel Drivers
SMS Twilio, generic HTTP
Email SMTP, HTTP
Push FCM (Android), APNs (Apple)

SMTP relays and push hosts are restricted

An SMTP relay — a realm's provider, and the server-wide fallback helix.notification.smtp.* — passes the egress guard: a relay on a private or loopback address must be listed by the deployment in HELIX_EGRESS_ALLOWED_PRIVATE_HOSTS (preferably as host:port, e.g. mailer.mail.svc.cluster.local:587), and ports other than 25, 465, 587 and 2525 in HELIX_MESSAGING_SMTP_ALLOWED_PORTS (e.g. 1025,8025-8030). Otherwise a send fails with result CONFIGURATION. SMTPS and STARTTLS still verify the certificate against the configured host name. APNs push goes only to api.push.apple.com or api.sandbox.push.apple.com; any other host is a configuration error.

These providers power the OTP, magic-link and push delivery used by multi-factor authentication. Configure them per realm so each tenant sends from its own accounts and sender identities.

Templates

Message bodies are templates you author and manage in the console:

  • User-claim passthrough — interpolate any user attribute with {{user.*}} variables (for example {{user.firstName}} or {{user.email}}).
  • HTML email — rich, branded email bodies.
  • Magic-link templating — inject the one-click sign-in link into the message.

Every template can be previewed with sample data and test-sent to a real address or device before you rely on it in production.

In the console

  1. Open Manage → Realms → Notifications.
  2. Under Providers, choose a channel and driver and enter its credentials.
  3. Test the provider to confirm delivery.
  4. Under Templates, edit each message, preview it, and test-send.

Over the API

Messaging config lives under /admin/realms/{realm}/messaging. The examples below assume you have set $HELIX_URL / $REALM and logged in — see Authenticating to the API.

List providers

A freshly seeded realm has no providers configured — delivery is inert until you add one:

curl -s -b cookies.txt "$HELIX_URL/admin/realms/$REALM/messaging/providers"
[]

Configure a provider

PUT /messaging/providers upserts the whole provider record for a channel/driver. channel and driver are required; the secret is write-only (the read side reports secretSet instead):

# Refresh CSRF after any GET, then PUT (see the auth guide for the helper)
curl -s -b cookies.txt -c cookies.txt "$HELIX_URL/admin/realms/$REALM/messaging/providers" >/dev/null
CSRF=$(awk '($6=="__Host-XSRF-TOKEN"||$6=="XSRF-TOKEN")&&$7~/^r1\./{t=$7} END{print t}' cookies.txt)

curl -s -b cookies.txt -X PUT \
  -H "Content-Type: application/json" \
  -H "X-XSRF-TOKEN: $CSRF" \
  -d '{
        "channel": "EMAIL",
        "driver": "smtp",
        "enabled": true,
        "fromAddress": "[email protected]",
        "fromName": "Acme",
        "config": { "host": "smtp.acme.example", "port": 587, "username": "acme" },
        "secret": "smtp-password"
      }' \
  "$HELIX_URL/admin/realms/$REALM/messaging/providers"
{
  "id": "b2f1c0a4-2c1d-4e9a-9f3b-7a10c5d6e8f2",
  "realmId": "acme",
  "channel": "EMAIL",
  "driver": "smtp",
  "enabled": true,
  "fromAddress": "[email protected]",
  "fromName": "Acme",
  "config": { "host": "smtp.acme.example", "port": 587, "username": "acme" },
  "secretSet": true
}

Send a provider test to confirm delivery (does not persist anything):

curl -s -b cookies.txt -X POST -H "Content-Type: application/json" -H "X-XSRF-TOKEN: $CSRF" \
  -d '{"to":"[email protected]"}' \
  "$HELIX_URL/admin/realms/$REALM/messaging/providers/EMAIL/test"

Manage templates

The realm ships with seeded templates for OTP, magic-link and push. {{…}} placeholders interpolate runtime values and user attributes:

curl -s -b cookies.txt "$HELIX_URL/admin/realms/$REALM/messaging/templates"
[
  { "id": "7d3d015e-7d3c-4277-babd-44966ad861e6", "realmId": "acme", "templateKey": "otp-sms",         "channel": "SMS",   "subject": null,                             "body": "{{realm}} verification code: {{code}} (valid {{ttl}}).", "enabled": true, "html": false },
  { "id": "e99a4b98-641f-4c14-b61c-ef410514b9fa", "realmId": "acme", "templateKey": "otp-email",       "channel": "EMAIL", "subject": "Your {{realm}} verification code","body": "<p>Hi {{user}},</p>…",                                 "enabled": true, "html": true },
  { "id": "8a02ced3-5a8e-4663-aac6-2aa3df73e66c", "realmId": "acme", "templateKey": "magic-link-email","channel": "EMAIL", "subject": "Sign in to {{realm}}",            "body": "<p><a href=\"{{link}}\">Click here…</a></p>",         "enabled": true, "html": true }
]

Edit a template with PUT /messaging/templates, and render a preview without sending:

# Preview a template with sample data (returns the rendered subject/body)
curl -s -b cookies.txt -X POST -H "Content-Type: application/json" -H "X-XSRF-TOKEN: $CSRF" \
  -d '{"templateKey":"otp-email","sample":{"user":"Alice","code":"123456","ttl":"5 minutes"}}' \
  "$HELIX_URL/admin/realms/$REALM/messaging/templates/preview"

Full endpoint set

Method & path (under /admin/realms/{realm}) Purpose
GET /messaging/providers · PUT /messaging/providers List / upsert a channel provider
DELETE /messaging/providers/{channel}/{driver} Remove a provider (console: the provider's Remove, confirmed; the dialog says when it is the provider in use)
POST /messaging/providers/{channel}/test Send a provider delivery test
GET /messaging/templates · PUT /messaging/templates List / edit templates
POST /messaging/templates/preview Render a template without sending

See the API reference.

See also