Skip to main content
Personalization lets you send messages that include dynamic data — such as a user’s name, cart items, account balance, booking details, or a one-time password. This guide helps you choose the right personalization method based on:
  • Where your data lives
  • Whether it should persist
  • How the message is triggered

How personalization works

Personalization in OneSignal has two parts:
  1. Liquid syntax – defines how values render in your message
  2. A data source – determines where the value comes from
At send time, OneSignal resolves your Liquid variables using the selected data source.
Liquid controls formatting and logic (variables, loops, conditionals). The data source determines what values are available.
Example:
Liquid
Hi {{ user.tags.first_name }},

Your verification code is {{ message.custom_data.otp }}.
  • user.tags.first_name is a stored property
  • message.custom_data.otp is passed via the API custom_data field

Data source comparison

If you need to…
Common mistakes to avoid
  • Using Properties (Tags) for one-time values like OTPs or verification codes
  • Expecting custom_data to be available in Journeys or future messages
  • Assuming Custom Event properties are available outside of the event triggered Journey entry or a Wait Until step
  • Using Data Feeds for static data that rarely changes

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
Only events that trigger Journey entry or a Wait Until step are stored for personalization. Events sent outside those moments are not available to Journey messages.

Custom Event personalization

Complete guide to using event properties to personalize Journeys.

Properties

Properties include Tags, External ID, subscription data, and app-level fields. They are: Use Properties when:
  • 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
Use 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.