- Where your data lives
- Whether it should persist
- How the message is triggered
How personalization works
Personalization in OneSignal has two parts:- Liquid syntax – defines how values render in your message
- A data source – determines where the value comes from
Liquid controls formatting and logic (variables, loops, conditionals). The data source determines what values are available.
Liquid
user.tags.first_nameis a stored propertymessage.custom_data.otpis passed via the APIcustom_datafield
Data source comparison
If you need to…- Reuse stored user data → Properties
- Personalize inside a Journey based on behavior → Custom Events
- Send one-time or sensitive values → API
custom_data - Fetch live backend data at delivery → Data Feeds
- Upload bulk personalization via dashboard → Dynamic Content CSV
Data sources
Data feeds
Data Feeds call your API at send time and inject the response into your message. When to use Data Feeds:- You need the latest value at delivery
- The data lives in your backend
- The value may change between sends
Data feeds
Pull real-time backend data into messages at send time.
Custom Events
Custom Events can personalize messages inside Journeys using event properties. When an event starts a Journey or matches a Wait Until condition, OneSignal stores that event so its properties can be referenced in message templates using Liquid. When to use Custom Events:- Event triggered messages with Journeys
- The message should reflect event-specific data
Custom Event personalization
Complete guide to using event properties to personalize Journeys.
Properties
Properties include user tags, External ID, subscription data, and app-level fields. They are:- Persistent
- Reusable
- Available across messages, templates, Journey webhooks, and Event Streams.
- The value exists in OneSignal
- The value is persistent
- You reuse it across campaigns
Personalize with Properties
Learn how to reference stored persistent property data.
API custom_data
The custom_data field in the Create Message API lets you send message-specific values from your backend.
This data:
- Exists only for the current request
- Is not stored in OneSignal
- Is not available in Journeys
custom_data when:
- Sending one-time or sensitive values (OTP, secure links)
- Passing arrays (cart items, order lines, leaderboard scores)
- Sending transactional or API-triggered messages
Personalize with API custom_data
Learn how to pass transient personalization data.
Dynamic Content CSV
Upload a CSV file into the OneSignal dashboard and reference its values using Liquid. Use CSV when:- Customizing differnt sections of a bulk campaign for each recipient
- Translations or custom data for each recipient is exportable to a CSV file
- You do not want to use the API
Dynamic Content CSV
Personalize dashboard campaigns using CSV uploads.
Detailed guides
Use the guides below for step-by-step implementation details and advanced examples.Using Liquid syntax
Learn how to insert dynamic data into messages using Liquid. Covers variables, conditionals, loops, filters, formatting, and common personalization patterns.
Data feeds
Pull real-time data from your own APIs at send time. Use Data Feeds when message content depends on live backend values like balances, availability, or pricing.
Custom Events personalization
Personalize Journey messages using event properties captured when users enter or progress through a Journey. Ideal for behavioral and event-driven workflows.
Properties & Tags
Use stored user, subscription, message, and app properties to personalize content across messages, templates, Journey webhooks, and Event Streams.
API custom_data
Pass per-message and transient data from your backend using the Create Message API. Best for OTPs, carts, arrays, and bulk transactional personalization.
Dynamic Content CSV
Upload CSV files in the dashboard to personalize campaigns at scale. Each row maps to a recipient and can be referenced using Liquid.
Tutorials
These guides show how to implement personalization in practice.Verification, Magic Link, & OTP
Send secure verification messages using one-time passwords, magic links, or custom URLs with API-driven personalization.
Abandoned cart Journey
Build an automated Journey that detects cart activity, waits for inactivity, sends a personalized reminder, and exits users immediately after purchase.
Booking confirmations
Send booking confirmation and recovery messages using Custom Events, Journeys, and Data Feeds based on real-time reservation status.
Transactional messages
Learn how to send receipts, alerts, confirmations, and other transactional messages across channels using APIs and automation.
In-app personalization examples
See practical examples of using tags and properties to personalize in-app messages for different users and segments.