Dynamic Content
Learn how to use OneSignal Dynamic Content to personalize Push Notifications, SMS, and Emails at scale using CSV uploads and Liquid syntax.
Overview
Dynamic Content lets you personalize messages at scale—without creating separate versions for each audience. Whether you’re sending multi-language messages or tailoring content by region or campaign, Dynamic Content allows you to define one message that automatically adjusts for each user.
You do this by uploading a CSV file or programatically using our Template APIs with data containing content variations and referencing those values in your message using Liquid Syntax. When a message is sent, OneSignal pulls the appropriate content for each user based on their Data Tags.
Dynamic Content works across Push, Email, and SMS, making it ideal for:
- Multi-language onboarding or marketing flows
- Region or segment-specific promotions
- Personalization driven by external campaign data
Key benefits:
- Personalization at scale – Deliver custom experiences without creating and managing dozens of message variants.
- Multi-language support – Write one message that automatically displays in each user’s preferred language.
- Dynamic segmentation – Change message content based on user properties like language, region, plan, or custom tags such as campaign_id.
- Collaboration without friction – Let translators or non-technical teams create and edit message content directly in CSV files—no OneSignal login needed.
- Cross-channel compatibility – Use the same CSV logic across Push, Email, and SMS campaigns.
Common use cases:
- Event announcements per country or city
- Personalized push notifications based on campaign ID or purchase history
- Testing multiple subject lines or messages across user groups
See Message Personalization for more options on personalizing your messages.
Dynamic Content setup
Create a new message or template.
From the dashboard: Select Dynamic Content.
- Upload a CSV file that maps message content to Data Tags.
From the Templates APIs: Use the dynamic_content
property.
- Great solution if your dynamic content changes frequently.

Dynamic Content button found in the push create editor.
Format your content
You can start with a blank file or choose one of the provided templates:
- Multi-language
- Content personalization

CSV template options provided by OneSignal.
For API details, see:
CSV requirements
- File size must be under
200 KB
- Column headers:
- Alphanumeric only
- Use underscores (
_
) instead of spaces - Avoid special characters
- Ensure UTF-8 encoding in your spreadsheet editor
Map the subscription.language
property to different translations per section.

Similar to a VLOOKUP formula in Excel, we match user attributes with the corresponding content from the CSV.
Map the subscription.language
property to different translations per section.

Similar to a VLOOKUP formula in Excel, we match user attributes with the corresponding content from the CSV.
Use a tag like campaign_id
to dynamically render content for that user.

Example personalization based on tags.
Important: Remove spaces and non-alphanumeric characters from CSV headers or use hash notation in Liquid.

Example shows a more detailed CSV using additional liquid syntax to reference the user's tag.
Once complete, upload the file.

The Upload CSV step in the dashboard.

Example showing a fully uploaded CSV. Press Close and continue.
Reference Dynamic Content in messages
To display personalized content from dynamic_content
, use this Liquid syntax.
Replace:
file_name
: CSV file name (without.csv
).section_name
: Value in the first column of the rowdata_tag_or_property
: Column header matching a Data Tag or subscription property
Fallback content
Adding fallback content will prevent users receiving blank content. It ensures your message renders when:
- a user does not have a matching tag or property.
- a user has a tag or property that is not available in
dynamic_content
.
User does not have a matching tag or property
If subscription.language
doesn’t exist, reference the default column from dynamic_content
instead.
User has a tag or property that is not available in dynamic_content
If subscription.language
exists on a subscription, but not in dynamic_content
reference the default column instead.
Examples
Multi-language email
Use translations.csv
to localize your email:
{{dynamic_content.translations.section_1[subscription.language]}}
{{dynamic_content.translations.section_2[subscription.language]}}

Example shows how to add the liquid syntax for the multi-language example.
Update subject lines, preheaders, button labels, and URLs using Liquid.
Personalized push message
Use content_personalization_template.csv
for user-specific push messages:
{{dynamic_content.content_personalization_template[campaign_id].title}}
{{dynamic_content.content_personalization_template[campaign_id].message}}
{{dynamic_content.content_personalization_template[campaign_id].url}}

Example shows how to add the liquid syntax for the content personalization example.
Test and preview
Create a test CSV
Multi-language test:
- Columns:
email
,language
Personalization test:
- Columns:
external_id
,campaign_id

Example CSV to upload and create segment of email testers.
Use +
addressing in emails to test multiple variations: username+test@example.com

Example CSV to upload and create segment of testers with external_id and the tag campaign_id.
Upload your test segment
Go to Subscriptions or Segments > Upload/Import Users.
Set the first column as the identifier. All other columns are treated as user properties or Data Tags.

Create a segment of your testers to repeat as needed.
See Import for more on uploading user data.
View the message
After sending your test messages, check your inboxes or devices to verify display.
dynamic_content
isn’t rendering, reference Fallback content
Example shows the email sent with Dynamic Content.

Example shows the push sent with Dynamic Content.
You can now scale personalized messaging using these templates and CSVs.
Usage considerations
When to use Dynamic Content vs. Custom Data
- Use Dynamic Content for diverse languages or personalized message blocks.
- Use Custom Data for simple, inline personalization in a single language.
Editing templates
Re-upload CSVs or use the dynamic_content
property of the Update Template API to update.
Special characters in keys
Use hash notation if keys contain non-alphanumeric characters:
Use dot notation for standard alphanumeric keys: