Templates

A publisher never sends a subject line or a body. It sends a template identifier and a data object; NovaBell owns the wording, the branding and the translation. That is what keeps one platform voice across every notification a person receives.

Identifier

A template identifier is <namespace>/<name>:

Namespace

Owner and subject matter

iam

Identity lifecycle — account, user, group, policy, access-key and app-registration events.

org

Organization lifecycle — organization and organizational-unit changes, member removal.

quota

Quota lifecycle — increase requested, approved, denied.

system

Platform-wide messages such as the welcome notification.

Adding a namespace or a template is a change in the NovaBell repository, because the rendered wording and its translations ship with the service. Publishers pick from the registered set; they do not supply markup.

Data

Each template declares the variables its subject, in-app title and email body interpolate. Send them in data using the names below; a variable a template does not use is ignored, and a variable it does use but you omit renders empty.

Family

Variables you supply

App registration

appName, clientId, developerEmail, reason

Account lifecycle

accountName, accountId, newStatus, reason, cancellationWindowDays

User lifecycle

username, userId, email, realm

Group and policy

groupName, policyName, targetName, targetType

Access keys

accessKeyId, expiresAt, windowDays, earliestExpiresAt

Organization

orgName, ouName, parentOuName

Quota

quotaName, requestedValue, currentValue, newValue, reason

Security events

sourceIp, userAgent, occurredAt, attemptedAction, violationType

actionUrl is not part of data — it is a top-level field of the publish request, and it is what the email button and the in-app row link to.

What the recipient sees

  • Email — the template’s MJML body rendered inside the shared FlexGalaxy.AI layout, with the subject interpolated from data.

  • In-app — the template’s title and short body, filed under the publishing service’s category, filterable by severity, and linking to actionUrl.

A few notification types are in-app only by design and have no email body. Request only the in_app channel for those: asking for email as well fails the whole request, and the in-app copy is not written either.

Publish an identifier that carries no email body and the email channel returns 500. The in_app channel is more forgiving and will store the row with the raw identifier as its title — a visible defect rather than a silent one, so treat a notification titled iam/something as a missing registration to fix, not as normal output.