Skip to main content

Brands and variables

Brands hold the visual identity that templates reuse (logo, colours, footer text); variables hold the dynamic content that renders per message (user name, order id, amount). Both are dashboard-managed and feed into the same template editor.

TL;DR

  • Brand is a top-level dashboard concept (/org/:org/app/brand). One per organisation, sometimes per environment.
  • Organisation variables are global — defined once, reusable across every campaign.
  • Environment variables (Notifizz’s, distinct from your runtime env vars) are scoped per environment, edited inline from the campaign flow.
  • Variables are referenced as {{var:<id>}} tokens; the catalog resolves names at render time.

Brand

A brand groups visual identity tokens that every campaign template inherits:
TokenExample
Primary colour#C923A6
Secondary colour#1A1A1A
Logo (light)https://cdn.example.com/logo-light.svg
Logo (dark)https://cdn.example.com/logo-dark.svg
Default fontInter, system-ui, sans-serif
Footer text© Example Corp — Privacy · Terms · Unsubscribe
Sender nameExample Notifications
Edit once, applies everywhere. Templates reference brand tokens via the editor’s brand-aware controls — switching the brand re-renders every message that hasn’t been sent yet. The brand is one record per organisation (with the dashboard exposing optional per-environment overrides for staged rollouts). Templates that want to differ per campaign override at the template level.

Variables — two scopes

The variable system supports two scopes:

Organisation variables

Defined once at the organisation level, reusable across every campaign. Edited from organisation settings. Common patterns:
VariableWhy org-wide
support_emailSame support address across every notification.
app_nameBranded name used in subject lines.
cta_url_baseCommon URL prefix for in-app CTAs.
unsubscribe_url_templateSame unsubscribe pattern across marketing campaigns.
Reference as {{var:org.support_email}} (or via the editor’s variable picker). Resolution happens at message render time.

Environment variables (Notifizz’s)

Scoped per environment, edited inline from the campaign flow. Useful for environment-specific values that shouldn’t pollute the organisation-wide list:
VariableWhy per-env
dashboard_urldev.example.com vs app.example.com
support_phoneTest number on dev, real number on prod
region_specific_legal_textEU vs US compliance footer
Reference as {{var:env.dashboard_url}}. The render-time resolution picks the value for the environment where the message is being delivered.
Don’t confuse Notifizz’s “environment variables” (template tokens scoped to a Notifizz environment) with your application’s runtime env vars (process.env.X). They live in different worlds — Notifizz variables don’t interpolate from your shell, and your shell vars never leak into Notifizz templates.

Variable resolution

At message creation time:
1

Extract variable IDs from the template

The system walks the rendered config tree and collects every {{var:<id>}} token.
2

Build the variable catalog

For each id, look up the variable definition (org or env scope). Bundle into a small catalog object — only the variables actually used in this template, not the whole org’s catalog.
3

Snapshot with the message

The catalog is stored alongside the rendered template on the message document. The widget resolves {{var:<id>}} to the runtime value without an extra API call.
This snapshot pattern means renaming a variable doesn’t rewrite past messages — sent messages keep the value as it was at creation time. Only future messages pick up the new value.

Name collisions

Org and env scopes can both define a variable with the same name. Resolution rules:
  • IDs are serialised with their scope prefix (org.foo vs env.foo), so the variable picker never produces a collision.
  • The editor warns if a template references a variable id that doesn’t exist in either scope.
If you reference an undefined variable, the rendered message shows the literal token ({{var:env.missing}}) — easy to spot and fix.

Usage count

Each variable tracks how many templates reference it. The count auto-increments when a template is saved with the variable referenced and decrements when a template removes the reference. Use it to find dead variables (usageCount === 0) before retiring. The diff is best-effort — if the count gets out of sync (rare), the dashboard exposes a “recompute usage counts” maintenance action.

Recipient fields vs variables

Don’t confuse:
  • Recipient custom fields ({{ recipient.displayName }}) — produced by the orchestrator, vary per recipient within a single workflow instance.
  • Variables ({{var:org.app_name}}) — defined in the dashboard, same value for every recipient of a given template.
The template can use both. A subject line like Hi {{ recipient.displayName }}, your {{ var:org.app_name }} order shipped resolves the displayName per recipient and the app_name from the org variable catalog.

FAQ

Three causes: (1) the variable is defined but its value is empty (check the dashboard); (2) the template references a variable id that doesn’t exist (the rendered output shows the literal {{var:...}} token in that case); (3) the variable was renamed after the template was saved — re-save the template to pick up the new id.
Not directly — variables are org-wide or env-wide. For per-campaign data, use recipient custom fields (set in the orchestrator) or event properties (in {{ event.foo }} references). If you find yourself wanting many per-campaign variables, the right layer is probably the orchestrator’s recipient list.
The dashboard’s template editor exposes a preview pane with editable sample values for every referenced variable + a sample recipient object. Render the preview to see the rendered output before promoting to Live.
Neither — they have distinct serialised IDs (org.foo vs env.foo). The editor’s variable picker never produces an ambiguous reference. If you’re hand-editing the template HTML and use {{var:foo}} without scope, the editor will flag it as invalid.
No. Variables are part of the message snapshot — anyone with access to delivery history can read them. Use them for non-sensitive values (URLs, copy, branding); never API keys or PII beyond what your privacy policy already covers.
Nothing — the variable name and value were snapshot on the message at creation time. Past messages render the same way they always did. Future messages pick up the new variable name and value.

See also

Channels (detail)

Where templates dispatch to.

Recipients

Recipient custom fields vs variables.

Link routes

Variables inside tracked URLs.

Activity log

Audit trail of variable edits.