- A user’s current rewards balance
- Latest order status
- Personalized product recommendations
How Data Feeds work
- Create a Data Feed – Configure how OneSignal connects to your API.
- Attach the Data Feed to a message template.
- Insert response fields in your message using Liquid syntax.
- At send time, OneSignal makes an API call for each recipient, parses the response, and injects the data into your message.
Example: Display reward points
Suppose you want to show each customer their rewards balance:Creating and using a Data Feed
1. Set up your Data Feed configuration
Navigate to Data > Data Feeds in the sidebar to see the list of existing Data Feeds and create a new one. Each Data Feed must have:- Name: A descriptive name like “Customer Rewards API” to help you distinguish feeds. Unique names are recommended but not required.
- Alias: A short identifier like
rewardsused in Liquid syntax (e.g.,{{ data_feed.rewards.points }}). Must be unique, lowercase, alphanumeric, with no spaces or special characters. - Method: The HTTP method OneSignal uses to contact your API. Usually
GET, butPOSTis also supported. - URL: Your API endpoint. Supports Liquid syntax so OneSignal can fetch user-specific data.
external_id (stored in OneSignal) as a URL parameter:
- Headers: Key-value pairs required by your API (e.g., authentication tokens). Supports Liquid syntax.
- Body: Optional JSON request body. Supports Liquid syntax, the same as Journey webhooks.

Data Feed configuration example
2. Attach the Data Feed to your message template
Attach your Data Feed to your message template so that OneSignal knows to use it.- Navigate to Messages > Templates
- In the Message section, select the Personalization button

Personalization button options
- Toggle on Data Feeds and select your feed

Data Feeds section in the message composer
- Save your template
3. Use the data in your message
Use Liquid syntax to insert response data anywhere in your message. Continuing the rewards example, the API response for Sarah (whoseexternal_id is a1-b2c3) might look like this:
- Use a Data Feed
- Use the
rewardsData Feed- Recall: the
rewardsfeed knows to call the API with theexternal_idof the recipient
- Recall: the
- From the response, insert the value of the
pointsitem (193) and thestatus_levelitem (Gold)
Requirements and limits
Your API needs to:- Accept single-step authentication with auth tokens in headers
- Respond quickly. Under 250ms recommended (this directly affects send speed)
- Return JSON. Other formats are not supported at this time.
- If you need a different format, share your use case.
- Handle your send volume. A low rate limit on your API slows message delivery.
- Return reasonably-sized payloads. Keep responses under 50 KB for best performance.
- One Data Feed per template. Fetch everything you need in a single API response.
- One API call per Data Feed per message.
- Journeys only. Not yet available for other sending methods.
- No chaining calls. The payload from one Data Feed cannot be used to call another.
Setting up your API
Before creating a Data Feed, ensure your API can handle these requirements:Authentication
Your API should accept authentication via headers:Disallowed headers
The following headers are restricted and cannot be set:content-lengthreferermetadata-flavorx-google-metadata-requesthostx-onesignal*
JSON request body
If you need to include a body in the request, your API should accept JSON. This may mean your headers need to includeContent-Type: application/json.
JSON response
Your API should return a JSON object. Typically this means your headers will includeAccept: application/json.
Personalization parameters
You’ll typically pass user identifiers in the URL like this:Rate limits
Consider your API’s rate limits. Sending to 10,000 users means 10,000 API calls in rapid succession. Ensure your API can handle this volume.Error handling
If your API returns an error or doesn’t have data for a user, the message won’t be sent to that recipient. Make sure your API returns data for all expected users.Getting started checklist
Before implementing Data Feeds, answer these questions:- What data do I want to show in my message? Working backwards from a simple outline with the items to be populated from your API identified will help you organize your thinking.
- Is this data available via a single API endpoint?
- How will I authenticate API requests?
- What identifier or other data item will I use to fetch personalized data?
- Is that identifier already stored in OneSignal? If not, how will it be populated?
- Can my API handle the volume of requests I’ll generate?
- What happens if my API doesn’t have data for a user?
Examples and advanced use cases
Data Feeds can be used with Liquid syntax or in combination with other features in creative ways to produce more complex personalization.Iterating with loops: abandoned cart
Iterating with loops: abandoned cart
Custom events properties
Custom events properties
cart_abandoned custom event, where the properties includes a cart_id. In this example that event is being sent to OneSignal via API:
Custom event for Journey entry
user_12345 enters the journey when this event is fired, then reaches a node sending an email. That email template is set up with the cart Data Feed, where the URL is set to retrieve the contents of a particular cart like so:- The
cart_idvalue of98765will be stored to the Journey - When the email step is reached, the
cartData Feed will reference thatcart_idvalue and use it to call the cart API - The returned JSON properties will be parsed and inserted into the email as in the previous example above
Conditional display: order status
Conditional display: order status
if statement to do so:tracking_number exists.Automation without personalization
Automation without personalization
banner Data Feed that points to an endpoint without any variables in the URL like so:{{ data_feed.banner.banner_url }} as the image source URL, automating this process going forward.Personalized coupon codes
Personalized coupon codes
Goal
Send an email such as:Hi George, Complete your booking in the next 2 hours and save 10% with your personal code: XYZ123ABCEach user receives a unique coupon code, generated live via an external API call when the email is sent, valid for the given time window, and scoped to that user.
Prerequisites
- Email channel configured in OneSignal (your app has email capability enabled)
- An external API that accepts a user identifier (for example,
external_id) and campaign identifier, and returns JSON with the coupon code, discount, and expiration - A unique identifier (such as
external_id) for each user that your API can use to generate coupons - A segment or trigger (for example, “abandoned search in last 24h”) used to send the email through a OneSignal Journey
Step 1: Create the Data Feed
Navigate to Data Feeds
Configure the Data Feed
- Data Feed Name:
coupon_code_generator - Alias:
coupon - Method:
GET - URL:
https://api.example.com/generate-coupon?userId={{ external_id }}&campaign=AbandonedBooking10 - Headers:
Reference the API response
{{ data_feed.coupon.code }}{{ data_feed.coupon.discount_percent }}{{ data_feed.coupon.expires_in_hours }}
Test and activate the Data Feed
Step 2: Create the email template
- In OneSignal, go to Messages > Email > New Template
- Use the Data Feed alias and fields within your message body. For example:
- Use Liquid syntax in the form
{{ data_feed.<alias>.<field> }} - Make sure the Data Feed is attached to the template
- If using the drag-and-drop editor with custom Liquid logic, use an HTML block
Step 3: Attach the Data Feed and trigger the email
- In the template composer, under Personalization > Data Feeds, toggle the feed on and select
coupon_code_generator - This ensures OneSignal makes the API call at send time for each recipient, populates the data, and injects it into the email
- Set up a Journey to automate the message:
- Entry condition: Segment such as “abandoned search in last 24 hours”
- Wait until: Create a
booking_completedcustom event. Configure the wait to exit the Journey if this event fires, or continue after 1 hour. If they complete a booking, they exit without receiving the email; otherwise, they continue to receive the coupon. - Send email: Use the personalized coupon email template
- Ensure the Journey uses the email channel and that recipients are subscribed to email
Step 4: Manage coupon redemption and tracking
Your backend should:- Record each generated code along with
userId,code,campaign,expiration_time, and aredeemedflag - Validate and mark codes as redeemed upon checkout
- Log the redemption data (user, campaign, and time) for ROI analysis
Complete workflow example
Testing
- Test with a user who has a known
external_id - Call your API manually to confirm correct JSON responses
- Use Preview in the OneSignal template editor to verify that data feed coupon fields populate
- Check API logs for latency and errors
- If a Data Feed call fails, OneSignal will skip sending the message to that recipient
Google Sheets: no-code data feed
Google Sheets: no-code data feed
How it works
- You maintain a Google Sheet with your content (one row per item)
- A small Apps Script converts the sheet into a JSON endpoint
- OneSignal fetches that JSON at send time via a Data Feed
- Liquid tags in your email template populate with the sheet data
Step 1: Set up your Google Sheet
Create a new Google Sheet with your content. Use the first row as column headers — these become your Liquid variable names.Example structure:Step 2: Add the Apps Script
In your Google Sheet, go to Extensions > Apps Script and paste the following code:Step 3: Deploy the script as a web app
Open the Deploy menu
Configure the deployment
Deploy and copy the URL
Step 4: Create a Data Feed in OneSignal
Navigate to Data Feeds
Configure the feed
Weekly Content) and an Alias you’ll reference in Liquid tags (e.g. weekly_content). Set the URL to your Apps Script web app URL.Activate
Step 5: Use Liquid tags in your email template
Reference your sheet data in any email template using the following syntax:Step 6: Attach the Data Feed to your message
When creating a new email message or template, attach the Data Feed under Personalization > Data Feeds before sending. OneSignal fetches the latest data from your sheet at send time.Updating content
To update your email content for the next send, open your Google Sheet and update the rows. No script changes or redeployment needed — the URL always serves the current sheet data.Tips
- Add or remove rows freely. Just make sure your Liquid tags in the template match the number of rows in your sheet.
- Column headers are your variable names. Renaming a column means updating the Liquid tags in your template to match.
- Test your endpoint first. Paste your Apps Script URL directly in a browser to verify the JSON output before connecting it to OneSignal.
- Format numbers as text. If you include currency or other formatted values, set those cells to Plain Text in Google Sheets to prevent formatting from being stripped.
- The script is reusable. The same Apps Script works for any sheet structure — no modifications needed.
FAQ
My Data Feed values are not appearing in the message. What should I check?
Verify these in order:- The Data Feed is attached to the template (under Personalization > Data Feeds).
- Your Liquid syntax matches the JSON response structure exactly —
{{ data_feed.<alias>.<field> }}. - The API endpoint returns valid JSON when called manually with the same identifiers.
- The recipient has the required identifier (e.g.,
external_id) stored in OneSignal.