docs
Documentation menu

Notification templates

Reusable push copy with variables.

#What a notification template is

A notification template is a single push title + body pair drawn from a curated corpus of real push notifications documented from growth-stage apps. Templates give you a starting point — tested copy patterns you can adapt to your brand — without writing from scratch.

The corpus contains 180 entries spanning habit-forming, win-back, trial conversion, social, and transactional patterns. Each entry carries attribution (the real app it was documented from), a verbatim flag, and links to the public sources used to verify the copy.

#Categories

Templates are organised into ten categories:

CategoryWhat it covers
habitDaily reminders and routine-building nudges.
streakStreak protection, milestone celebration, and loss-aversion warnings.
winbackRe-engagement after extended inactivity — escalating emotional tone.
reactivationReturn prompts for recently lapsed users (shorter lapse than win-back).
trialTrial start, midpoint, expiry warning, and post-expiry upgrade prompts.
promoTime-limited offers, discount codes, and event-based promotions.
socialFriend activity, kudos, league standings, and community events.
progressMilestone completions, goal achievements, and metric summaries.
transactionalConfirmations, payment receipts, and status updates.
onboardingFirst-session, feature discovery, and account setup prompts.

#Variables and personalisation

Notification title and body text can contain personalisation tokens. The flow engine resolves them against the receiving user's stored attributes at send time — not at flow-activation time. Any attribute name you have written via the SDK or the HTTP API is valid.

SyntaxMeaning
{{ name }}Resolves to the user's current value for attribute name. If the attribute is not set and no fallback is written, the send is suppressed (see Honesty policy below).
{{ name | fallback }}Same resolution, but uses fallback text when the attribute is unset. The fallback is trimmed. {{ name | }} is an explicit empty-string fallback.
[bracket text]Literal placeholder — rendered exactly as written. Replace it with your own copy before activating (e.g. [product_name], [Feature X]).
Examples
// Fallback — sends even when first_name is not yet set
"Hey {{ first_name | friend }}, your streak ends tonight."

// No fallback — the send is skipped when plan is unset (see Honesty policy)
"Your {{ plan }} plan renews tomorrow."

// Bracket placeholder — static copy you fill in before activating
"Unlock [Feature X] with a plan upgrade."
Heads up
Honesty policy: a token without a matching attribute value AND without a fallback causes the send to be skipped and logged — a suppress entry appears in the decision_log with suppress_reason="missing_variable" and the missing attribute names. Literal {{ … }} braces are never delivered to a device and a value is never invented. Add an inline fallback ({{ first_name | friend }}) to any token where the attribute may not yet be populated.

Resolution sources — at send time the engine looks up tokens against:

  • User attributes written via Pushlane.setAttributes (SDK / drop-ins) or POST /v1/attributes (HTTP). Most-recent value wins.
  • Four auto-populated system attributes: app_version, os_version, install_env, and locale — projected from every event context automatically, no SDK call required. Treat these names as reserved: writing them via setAttributes overwrites the auto-populated value (for locale that is a supported override — see Localization — but never reuse them for unrelated data).
  • external_id — the user's own identifier, always available once identified.
Note
Event properties are not personalisation variables. The properties of the trigger event (e.g. placement on a paywall_viewed) are not available as tokens. Only user attributes survive deferred sends — delays, schedule windows, STO waits — because the engine does not persist event properties in the Durable Object. To use a value that was present at trigger time, write it as an attribute first (e.g. Pushlane.setAttributes({ last_paywall: 'home' })).

Four ways to feed a variable:

  1. SDK / drop-in — call Pushlane.setAttributes({ first_name: user.firstName }) after Pushlane.identify on any platform. See the quickstart for your platform.
  2. HTTP API POST /v1/attributes from your server for attributes you know server-side (plan, LTV, subscription status…). See the HTTP API reference.
  3. Flow Update node — an Update attributes step inside a flow sets attributes mid-journey (e.g. stamp onboarding_completed_at when the user reaches that node).
  4. Auto-populated app_version, os_version, install_env, and locale are written automatically from every event context.

#Localization

A template gives you copy in one language. To reach users in their own language, translate the message: a flow can carry a title and body per language, and each user receives the one that matches their device locale — with an honest fallback to the default language when a locale is not covered. The same personalisation tokens work in every language.

See Localization for the Localization table, auto-translate, and how the language is picked at send time.

#Verbatim vs. reconstructed

Each template carries a verbatim flag:

FlagMeaning
verbatim: trueThe copy was confirmed word-for-word by at least one public source (linked in the sources field). Use as-is or adapt.
verbatim: falseThe copy was reconstructed from a documented notification pattern. The tone and structure are accurate but the exact wording may differ from the original.

The sourceApp field names the real app the template was documented from. This is attribution only — no app logos are displayed.

#Using a template

Notification templates surface in two places in the product:

  1. Message editor — "Use as template": Open a Message node in the flow builder and click the template library icon. Browse by category, select a template, and its title and body are loaded into the editor. Edit the copy before saving.
  2. New flow seed — "Start from this notification": From the template library, start a new single-step flow pre-populated with the chosen notification. Add delays, branches, or additional messages around it.
Note
Templates set the message channel to push. Pushlane is a push-only platform — in-app and SMS channels are not available.

Some templates carry a deeplink hint — a URL scheme or universal link to a specific screen in your app. When present it populates the deeplink field of the message variant. Replace the hint with your own scheme before activating.

Message variant — deeplink field
{
  "content": {
    "title": "Your streak ends in 10 minutes",
    "body": "One lesson saves your {{ days_left }}-day streak.",
    "deeplink": "myapp://lesson/daily"
  }
}

The deeplink is passed through to the APNs payload as-is. Your app must register the scheme or associated domain and handle the URL in your notification delegate.

Next: Audiences — build the segment of users a flow targets.