Learn how to build audiences in the Loyalty Engine using the expression editor, based on complex criteria across a range of data points.
Using the expression editor to build audiences gives you greater flexibility than the query builder, allowing you to define complex criteria across a wide range of data points.
It supports advanced logic, including grouping conditions in custom ways and referencing calculated values across multiple events — for example, total spend over a specific time period.
Background data structure
The expression editor evaluates a JSON payload containing multiple data points related to the user. When an audience is refreshed, the Loyalty Engine checks each user against the defined criteria — if they match, they are added to the audience.
This payload includes seven arrays, each representing a different category of user data.
activityData
The activityData array contains all events reported against the user. Each item in the array represents a single event.
Key data points
reportedAtISOString – The date and time the event was received by the Loyalty Engine, formatted as an ISO string (e.g. 2025-01-01T00:00:00.00Z).
occurredAtISOString – The actual date and time the event occurred, as reported, also in ISO format.
payload – An object containing the payload data submitted with the event.
type – An object containing information about the event type.
type.name – The name of the event (e.g. PURCHASED_REWARD).
consentData
The consentData array contains information about each consent in your loyalty program, as it relates to the individual user.
Key data points
type – An object containing details about the specific consent.
type.name – The name of the consent.
type.id – The unique ID of the consent.
status – The current status of the consent: GIVEN, REVOKED, or UNDEFINED.
pointsExpiryPredictionData
The pointsExpiryPredictionData array provides insight into how many points the user is predicted to have expire within a specified time period. It does not account for other points liability types, such as earning caps.
Key data points
eventIds – An array of event IDs that originally awarded the points set to expire.
pointsDueToExpire – The total number of points predicted to expire during the specified period.
timePeriod – The number of days until expiry. Possible values are 1, 7, 30, 90, or 365.
productPurchasesData
The productPurchasesData array provides a summary of product purchases extracted from the productDetails object inside each lineItem in the transactionData array. See the transactionData section for more information about its structure.
If multiple line items in the same event share the same SKU, their quantities and values are aggregated into a single product entry.
Key data points
serviceDate – The date the transaction occurred.
name – The name of the product purchased.
sku – The SKU of the product.
quantity – The total quantity of the product purchased in the transaction.
unitPrice – The price per unit of the product, as defined in the Products module at the time of purchase.
lineItemTotalPrice – The total amount reported for the product in the transaction (as originally received in the payload).
calculatedTotal – The product of unitPrice × quantity, calculated at the time of the event being reported.
rewardData
The rewardData array includes information related to the user's wallet, tier status, and reward activity. It always has a length of 1, so expressions should reference values using rewardData[0].
Key data points
points – The user's current points balance.
tier – An object containing details about the user's current tier.
tier.name – The name of the user's current tier.
vouchers – An array of rewards the user has purchased, including those fulfilled by third-party partners.
redeemedVouchers – An array of rewards the user has redeemed, including those fulfilled by third-party partners.
loyaltyCost – The total loyalty cost of the user, calculated as the sum of the value of all rewards purchased.
transactionData
The transactionData array contains a filtered subset of events from activityData, specifically including only authorized transaction events.
An authorized transaction event is defined as either:
a CLAIMED_RECEIPT event with status AUTHORIZED, or
a RECEIPT_CLAIM_STATUS_CHANGED event with the status AUTHORIZED and the previous status as either PENDING or REJECTED.
Currently, transactionData does not include data from RECEIPT_AUTHORIZED or ORDER_PLACED events.
user
The user array contains information related to the user's profile. It always has a length of 1, so expressions should reference values using user[0].
Key data points
accountNumber – The WLL account number for the user (e.g. 1000177).
profile – An object containing the user's profile information.
profile.attributes – An object with custom attributes added to the user's profile.
profile.age – The users age, calculated from their date of birth.
flags – An array of flags that have been assigned to the user.
Writing expressions
The expression editor allows you to write JSONata expressions to query user data with advanced logic. You can learn more about JSONata here.
Each expression must return a true or false value. If the expression evaluates to true, the user will join the audience. If it evaluates to false, they will not.
You can find an example of the data structure and a sample expression here. You can adjust the data and expression to see how it affects the result.
Date criteria: within a specified time period
To check whether an event occurred within a certain number of days, calculate the time since the event and compare it to the time window you’re interested in.
The expression has two parts:
(activityData[$toMillis($now()) - $toMillis(reportedAtISOString)
Calculates how long ago the event occurred, in milliseconds.
($days * 24 * 60 * 60 * 1000)
Converts your desired time period (in days) into milliseconds.
By comparing these values, you can determine if the event occurred within the specified time frame.
This expression checks whether the user has any events reported in the past 30 days. You can combine it with additional conditions (e.g. specific event types or payload values) to refine your criteria.
Date criteria: before or after a specific date
If you want to check whether an event occurred before or after a certain date, you can compare the ISO date string directly using comparison operators.
Example – Check for events before January 1st, 2025