Skip to content

Defining dynamic segments

When using the the Engage API to create Dynamic Segments, You will have to provide your segment in the Engage Segment expression language.

There are many functions you can use to define your segment. Below you can find:

  • The different functions and expressions available
  • Information on special tabels with customer information
  • Examples

The basics

First, some general basics on expressions:

  • The SCOPE is the context in which you are looking at fields. This can be your audience list or related lists.
  • To filter on fields on your main list, use MASTER as a scope for that list.
  • To filter on a field in a specific scope,like the USER_NAME field on your MASTER list, use the [<LIST>.<FIELD>] syntax. Example: [MASTER.USER_NAME]
  • To filter on fields from related list, use the name of the related list and specified in the relation section of your list, inside engage. For example, if the 1-1 list PREFERENCES is linked to your list with the name USER_PREFERENCE, use [USER_PREFERENCE.NEWSLETTERS]

Logical operations

These logical operations can be used inside fiters. They can be used in many variations and are often combined.

Logical Operator Expression Example Description
Equal eq(<FIELD>,<VALUE>) eq([MASTER.ID], toint(5)) ID is equal to 5
Not equal ne(<FIELD>,<VALUE>) ne([MASTER.ID], toint(5)) ID is not equal to 5
Greater than gt(<FIELD>,<VALUE>) gt([MASTER.AGE], toint(18)) Older than 18
Greater than or equal ge(<FIELD>,<VALUE>) ge([MASTER.AGE], toint(18)) 18 or older
Less than lt(<FIELD>,<VALUE>) lt([MASTER.AGE], toint(18)) Younger than 18
Less than or equal le(<FIELD>,<VALUE>) le([MASTER.AGE], toint(18)) 18 or younger
And all(<EXPRESSION>,<EXPRESSION>,...) all(gt([MASTER.AGE], toint(18)),lt([MASTER.AGE], toint(25))) Older than 18 and younger than 25
Or any(<EXPRESSION>,<EXPRESSION>,...) any(lt([MASTER.AGE], toint(18)),gt([MASTER.AGE], toint(25))) younger than 18 or older than 25
One off in(<FIELD>,<VALUES>,<SEPARATOR>) all(in([MASTER.AGE],'18|20','|') 18 or 20 years old
Ends with endswith(<FIELD>,<VALUE>) endswith([MASTER.MAIL], 'gmail.com') email ends with "gmail.com"
Starts with startswith(<FIELD>,<VALUE>) startswith([MASTER.MAIL], 'bob') email starts with "bob"
Contains contains(<FIELD>,<VALUE>) contains([MASTER.NAME], 'Marigold') Name contains "Marigold
Field is empty or null isempty(<FIELD>) isempty([MASTER.AGE]) Age is known
Field is not empty or null isnotempty(<FIELD>) isnotempty([MASTER.AGE]) Age is not known

Date & time operations

The following functions are operations you can use throughout your constraints, to identify Absolute or Relative dates and times.

Note

When using relative, this is always compared to the timezone of your server, usually UTC.

Relative datetimes

Logical Operator Expression Example Description
Current datetime subtract relative datetime subrelativetonow(<WEEKS>,<DAYS>,<HOURS>,<MINUTES>) subrelativetonow(0,24,0,0) Now minus 24 days
Current datetime add relative datetime addrelativetonow(<WEEKS>,<DAYS>,<HOURS>,<MINUTES>) addrelativetonow(1,0,0,0) One week from now
Current datetime add relative date addrelativedateparttonow(<YEARS>,<MONTHS>,<DAYS>,<HOURS>) addrelativedateparttonow(1,0,0,0) One year from now
Current date subtract relative datetime subrelativetotoday(<WEEKS>,<DAYS>,<HOURS>,<MINUTES>) subrelativetotoday(0,3,0,0) Today (00:00:00) minus 3 days
Current date add relative datetime addrelativetotoday(<WEEKS>,<DAYS>,<HOURS>,<MINUTES>) addrelativetotoday(0,3,0,0) Today (00:00:00) plus 3 days

Date comparisons

Logical Operator Expression Example Description
Date of field is equal date datepartisequal(<FIELD>,<DATE>,'') datepartisequal([MASTER.BIRTHDAY], todatetime('2024-01-22 00:00:00', 'yyyy-MM-dd HH:mm:ss'),'') Birthday is on 22st jan 2024
Date of field is not equal to date datepartisnotequal(<FIELD>,<DATE>,'') datepartisnotequal([MASTER.BIRTHDAY], todatetime('2024-01-22 00:00:00', 'yyyy-MM-dd HH:mm:ss'),'') Birthday is not on 22st jan 2024
Date of field is after or equal date datepartisbefore(<FIELD>,<DATE>,'') datepartisbefore([MASTER.BIRTHDAY], todatetime('2024-01-22 00:00:00', 'yyyy-MM-dd HH:mm:ss'),'') Birthday is before 22st jan 2024
Date of field is equal date datepartisbeforeorequal (<FIELD>,<DATE>,'') datepartisbeforeorequal([MASTER.BIRTHDAY], todatetime('2024-01-22 00:00:00', 'yyyy-MM-dd HH:mm:ss'),'') Birthday is on, or before 22st jan 2024
Date of field is after or equal date datepartisafter(<FIELD>,<DATE>,'') datepartisafter([MASTER.BIRTHDAY], todatetime('2024-01-22 00:00:00', 'yyyy-MM-dd HH:mm:ss'),'') Birthday is after 22st jan 2024
Date of field is after or equal date datepartisafterorequal(<FIELD>,<DATE>,'') datepartisafterorequal([MASTER.BIRTHDAY], todatetime('2024-01-22 00:00:00', 'yyyy-MM-dd HH:mm:ss'),'') Birthday is on, or after 22st jan 2024
Date of field is between 2 dates datepartisbetween(<FIELD>,<DATE>,<DATE>,'') datepartisbetween([MASTER.BIRTHDAY], todatetime('2024-01-22 00:00:00', 'yyyy-MM-dd HH:mm:ss'), todatetime('2024-01-28 00:00:00', 'yyyy-MM-dd HH:mm:ss'), 'day') Birthday is between 22st of jan 2024 and 28 of jan 2024

Date comparisons on part of a date

These operations allow you to compare to specific pieces of a date. the <DATE_FIELD> can have the following values:

  • hour
  • day
  • monthday
  • month
  • year
Logical Operator Expression Example Description
Date of field is equal date field datepartisequal(<FIELD>,<DATE>,<DATE_FIELD>) datepartisequal([MASTER.BIRTHDAY], todatetime('2024-01-22 00:00:00', 'yyyy-MM-dd HH:mm:ss'),'day') Birthday is on the first of any month
Date of field is not equal to date field datepartisnotequal(<FIELD>,<DATE>,<DATE_FIELD>) datepartisnotequal([MASTER.BIRTHDAY], todatetime('2024-01-22 00:00:00', 'yyyy-MM-dd HH:mm:ss'),'month') Birthday is not in Jan
Date of field is after or equal date field datepartisbefore(<FIELD>,<DATE>,<DATE_FIELD>) datepartisbefore([MASTER.BIRTHDAY], todatetime('2024-03-22 00:00:00', 'yyyy-MM-dd HH:mm:ss'),'month') Birthday is before March
Date of field is equal date field datepartisbeforeorequal (<FIELD>,<DATE>,<DATE_FIELD>) datepartisbeforeorequal([MASTER.BIRTHDAY], todatetime('2024-01-22 00:00:00', 'yyyy-MM-dd HH:mm:ss'),'year') Birthday is in, or before 2024
Date of field is after or equal date field datepartisafter(<FIELD>,<DATE>,<DATE_FIELD>) datepartisafter([MASTER.BIRTHDAY], todatetime('2024-02-22 00:00:00', 'yyyy-MM-dd HH:mm:ss'),'monthday') Birthday is after 22nd of Feb
Date of field is after or equal date field datepartisafterorequal(<FIELD>,<DATE>,<DATE_FIELD>) datepartisafterorequal([MASTER.BIRTHDAY], todatetime('2024-10-22 00:00:00', 'yyyy-MM-dd HH:mm:ss'),'month') Birthday is in, or afterNnov 2024
Date of field is between 2 hours / days / months / month-day / years datepartisbetween(<FIELD>,<DATE>,<DATE>,<DATE_FIELD>) datepartisbetween([MASTER.BIRTHDAY], todatetime('2024-01-22 00:00:00', 'yyyy-MM-dd HH:mm:ss'), todatetime('2024-01-28 00:00:00', 'yyyy-MM-dd HH:mm:ss'), 'day') Birthday is between day 22 and 28 of any month

Casting

It is always important to use the correct types when doing comparisons on your tabels. For this, type conversion (casting) might be needed.

Logical Operator Expression Example
as Decimal todecimal(<VALUE>) todecimal('50')
as Integer toint(<VALUE>) toint('5')
As Boolean tobool(<VALUE>) tobool('true')
as Datetime todatetime(<VALUE>,<FORMAT>) todatetime('2024-05-04 10:03:22','yyyy-MM-dd HH:mm:ss')

Special operations

There are special operations available to do specific filtering, both on the main list and related lists.

Lookup

Lookup is used to find records on your main list, that have matching records in a related list. the syntax is as follows: lookup(<SCOPE>,<EXPRESSION>)

  • SCOPE is the name of the relation
  • EXPRESSION can be any valid expression build up of other expressions. When references fields on your SCOPE

For example, if you have a related list HOBBIES, containing details about the hobbies of the user, you can do the following:

lookup([HOBBIES],eq([HOBBY],'Runner'))

this will select all users that have a hobby Runner.

You can also use lookup to create a one of filter. Like so:

lookup([HOBBIES],all(in([HOBBY],'Runner|Swimmer')))

This will return all users with hobby either Runner or Swimmer.

Note

You might have noticed the all function in the above expression. This is required for your segment to render correctly in the Engage segment editor. If a (valid) constraint is provided that is not available in the Segment Builder, the expression will be shown in plain text and will not be editable from the UI.

Content interactions

For adding engagment filters, a few similar operations exist. they generally follow the syntax: <operator>(<JOURNEY_ID>,<CONTENT_ID>,<LINK_ID>,...)

where JOURNEY_ID is the id of the journey, which you can find in the properties panel of any journey.

Journey id location

the CONTENT_ID can be found by selecting the configuration dropdown in a custom journey and highlighting the ID's of the different components.

content id location

Note

For recurring batch and Single batch journeys, the CONTENT_ID will always be 1. for A/B test journeys, they correspond to the letters of the alphabet. meaning A=1, B=2, etc..

the LINK_ID can be found in the link section of your content, and is always relative to the selected content.

content id location

Logical Operator Expression Example Description
Content delivered contentdelivered(<JOURNEY_ID>,<CONTENT_ID>) contentdelivered('1924','5') Received email 5 from journey 1924
Content delivered before time contentdeliveredbefore(<JOURNEY_ID>,<CONTENT_ID>,<DATE_EXPRESSION>) contentdeliveredbefore('1924','5',subrelativetonow(0,5,0,0)) Received email 5 from journey 1924 more than 5 days ago
Content delivered after time contentdeliveredafter(<JOURNEY_ID>,<CONTENT_ID>,<DATE_EXPRESSION>) contentdeliveredafter('1924','5',subrelativetonow(0,5,0,0)) Received email 5 from journey 1924 less than 5 days ago
Content delivered between time contentdeliveredbetween(<JOURNEY_ID>,<CONTENT_ID>,<DATE_EXPRESSION>,<DATE_EXPRESSION>) contentdeliveredbetween('1924','5',subrelativetonow(0,5,0,0),subrelativetonow(0,1,0,0)) Received email 5 from journey 1924 between 5 and 1 day ago
Content sent contentsent(<JOURNEY_ID>,<CONTENT_ID>) contentsent('1924','5') Sent email 5 from journey 1924
Content sent before time contentsentbefore(<JOURNEY_ID>,<CONTENT_ID>,<DATE_EXPRESSION>) contentsentbefore('1924','5',subrelativetonow(0,5,0,0)) Sent email 5 from journey 1924 more than 5 days ago
Content sent after time contentsentafter(<JOURNEY_ID>,<CONTENT_ID>,<DATE_EXPRESSION>) contentsentafter('1924','5',subrelativetonow(0,5,0,0)) Sent email 5 from journey 1924 less than 5 days ago
Content sent between time contentsentbetween(<JOURNEY_ID>,<CONTENT_ID>,<DATE_EXPRESSION>,<DATE_EXPRESSION>) contentsentbetween('1924','5',subrelativetonow(0,5,0,0),subrelativetonow(0,1,0,0)) Sent email 5 from journey 1924 between 5 and 1 day ago
Content viewed contentviewed(<JOURNEY_ID>,<CONTENT_ID>) contentviewed('1924','5') Viewed email 5 from journey 1924
Content viewed before time contentviewedbefore(<JOURNEY_ID>,<CONTENT_ID>,<DATE_EXPRESSION>) contentviewedbefore('1924','5',subrelativetonow(0,5,0,0)) Viewed email 5 from journey 1924 more than 5 days ago
Content viewed after time contentviewedafter(<JOURNEY_ID>,<CONTENT_ID>,<DATE_EXPRESSION>) contentviewedafter('1924','5',subrelativetonow(0,5,0,0)) Viewed email 5 from journey 1924 less than 5 days ago
Content viewed between time contentviewedbetween(<JOURNEY_ID>,<CONTENT_ID>,<DATE_EXPRESSION>,<DATE_EXPRESSION>) contentviewedbetween('1924','5',subrelativetonow(0,5,0,0),subrelativetonow(0,1,0,0)) viewed email 5 from journey 1924 between 5 and 1 day ago
Content clicked contentlinkclicked(<JOURNEY_ID>,<CONTENT_ID>,<LINK_ID>) contentlinkclicked('1924','5','100') Clicked link 100 in email 5 from journey 1924
Content clicked before time contentlinkclickedbefore(<JOURNEY_ID>,<CONTENT_ID>,<LINK_ID>,<DATE_EXPRESSION>) contentlinkclickedbefore('1924','5','100',subrelativetonow(0,5,0,0)) Clicked link 100 in email 5 from journey 1924 more than 5 days ago
Content clicked after time contentlinkclickedafter(<JOURNEY_ID>,<CONTENT_ID>,<LINK_ID>,<DATE_EXPRESSION>) contentlinkclickedafter('1924','5','100',subrelativetonow(0,5,0,0)) Clicked link 100 in email 5 from journey 1924 less than 5 days ago
Content clicked between time contentlinkclickedbetween(<JOURNEY_ID>,<CONTENT_ID>,<LINK_ID>,<DATE_EXPRESSION>,<DATE_EXPRESSION>) contentlinkclickedbetween('1924','5','100',subrelativetonow(0,5,0,0),subrelativetonow(0,1,0,0)) Clicked link 100 in email 5 from journey 1924 between 5 and 1 day ago

Filter on other segments

You can filter inside a Segment, based on the users present in another segment.

you can retrieve the SEGMENT_ID from the link, when opening your segment:

segment id location

Logical Operator Expression Example
Include segment includesegments(<SEGMENT_ID>) includesegments(50)
Exclude segment excludesegments(<SEGMENT_ID>) excludesegments(50)

STO (send time optimization) filters

You can filter on the existance of an STO profile for users.

This information is available through the SYS_AI_STO_DATA scope.

Logical Operator Expression
Users with STO profile isnotsempty([SYS_AI_STO_DATA.ID])
Users without STO profile isempty([SYS_AI_STO_DATA.ID])

Filter engagment profile

The engagement Profile, which contains overall information on the user, can be accessed via the SYS_EMAIL_ENGAGEMENT scope. If you want to learn more about Engagement Metrics, visit our Knowledge portal This allows all of the operators that are listed here, and have a number of interesting fields you can use to segment your users.

Field name Field description Example Description
CLICK_RATE_CTR % of emails clicked lt([SYS_EMAIL_ENGAGEMENT.CLICK_RATE_CTR], todecimal('10')) Percentage emails clicked is less than 10 %
CTO_RATE (Unique) Click to open rate (overall) gt([SYS_EMAIL_ENGAGEMENT.CTO_RATE], todecimal('10')) Click to open rate is greater than 10%
CLICK_RATE_EVOLUTION If the click rate of the user is better(1), the same(0) or worse(-1) in the last 5 mails, compaired to the 5 mails before that eq([SYS_EMAIL_ENGAGEMENT.CLICK_RATE_EVOLUTION], '1') Click rate has improved
CLICKED Number of emails clicked gt([SYS_EMAIL_ENGAGEMENT.CLICKED], todecimal('10')) Number of emails clicked is greater than 10
CLICKED_FIRSTDT Date of first email clicked datepartisafter([SYS_EMAIL_ENGAGEMENT.CLICKED_FIRSTDT],subrelativetonow(0,5,0,0),'') First email click was less than 5 days ago
CLICKED_LASTDT Date of last email clicked datepartisbefore([SYS_EMAIL_ENGAGEMENT.CLICKED_FIRSTDT],subrelativetonow(3,0,0,0),'') Last email click was more than 3 weeks ago
DELIVERED Number of emails delivered gt([SYS_EMAIL_ENGAGEMENT.DELIVERED], todecimal('10')) Number of emails delivered is greater than 10
DELIVERED_FIRSTDT Date of first email delivered datepartisequal([SYS_EMAIL_ENGAGEMENT.DELIVERED_FIRSTDT], subrelativedateparttonow(0,0,0,0), 'year') First delivered email was this year
DELIVERED_LASTDT Date of last email delivered datepartisbefore([SYS_EMAIL_ENGAGEMENT.DELIVERED_LASTDT], subrelativedateparttonow(0,0,0,0), 'year') First delivered email was not this year
DELIVERY_FREQUENCY Average number of emails delivered per week lt([SYS_EMAIL_ENGAGEMENT.DELIVERY_FREQUENCY], todecimal('3')) Less than 3 emails delivered per week, on average
DELIVERY_FREQUENCY_EVOLUTION The delivery rate of the user is better(1), the same(0) or worse(-1) in the last 5 mails, compaired to the 5 mails before that eq([SYS_EMAIL_ENGAGEMENT.DELIVERY_FREQUENCY_EVOLUTION], '-1') Number of emails received per week on average has decreased
DELIVERY_RATE % of emails delivered ge([SYS_EMAIL_ENGAGEMENT.DELIVERY_RATE], todecimal('95')) Delivery rate is higher than 95%
LAST_SERIES_UNOPENED Longests streak of unopened emails le([SYS_EMAIL_ENGAGEMENT.LAST_SERIES_UNOPENED], toint('5')) Unopened streak is smaller than 5
DESKTOP_ENGAGEMENTS Number of email views and clicks on desktop le([SYS_EMAIL_ENGAGEMENT.DESKTOP_ENGAGEMENTS], toint('100')) Total Desktop views/clicks is less than 100
MOBILE_ENGAGEMENTS Number of email views and clicks on mobile ge([SYS_EMAIL_ENGAGEMENT.MOBILE_ENGAGEMENTS], [SYS_EMAIL_ENGAGEMENT.DESKTOP_ENGAGEMENTS]) Total mobile views/clicks is greater than the number of desktop views/clicks
TABLET_ENGAGEMENTS Number of email views and clicks on tablet le([SYS_EMAIL_ENGAGEMENT.TABLET_ENGAGEMENTS], toint('100')) Total Tablet views is less than 100
MOBILE_USAGE_RATE Number of email views and clicks on mobile compaired to the total gt([SYS_EMAIL_ENGAGEMENT.MOBILE_USAGE_RATE], todecimal('10')) Mobile views are more than 10% of total
TABLET_USAGE_RATE Number of email views and clicks on tablet compaired to the total le([SYS_EMAIL_ENGAGEMENT.TABLET_USAGE_RATE], todecimal('10')) Tablet views are less than or equal to 10% of total
OPEN_RATE (Unique) Email open to delivered rate (overall) gt([SYS_EMAIL_ENGAGEMENT.OPEN_RATE], todecimal('50')) Email open to delivered rate is great than 50%
OPEN_RATE_EVOLUTION The open rate of the user is better(1), the same(0) or worse(-1) in the last 5 mails, compaired to the 5 mails before that eq([SYS_EMAIL_ENGAGEMENT.OPEN_RATE_EVOLUTION], '1') Open rate has improved
OPENED Number of email opened gt([SYS_EMAIL_ENGAGEMENT.OPENED], toint('1')) Opened at least 1 email
OPENED_FIRSTDT Date of first opened email datepartisequal([SYS_EMAIL_ENGAGEMENT.OPENED_FIRSTDT], subrelativedateparttonow(0,0,0,0), 'year') First opened email was this year
OPENED_LASTDT Date of last opened email datepartisbefore([SYS_EMAIL_ENGAGEMENT.OPENED_LASTDT], subrelativedateparttonow(0,0,0,0), 'year') Last delivered email was not this year
SENT Number of email sent eq([SYS_EMAIL_ENGAGEMENT.SENT], toint('0')) No email was sent
VIEW_RATE Rate of emails viewed gt([SYS_EMAIL_ENGAGEMENT.VIEW_RATE], todecimal('50')) Email view rate is great than 50%
VIEWED Total number of emails viewed eq([SYS_EMAIL_ENGAGEMENT.VIEWED], toint('0')) No email was viewed
VIEWED_LASTDT datepartisbefore([SYS_EMAIL_ENGAGEMENT.OPENED_LASTDT], subrelativedateparttonow(0,0,0,0), 'year') last viewed email was not this year

Examples

A few (complex) examples to help you understand how to structure your constraints.

All users that speak English or French

any(eq([MASTER.LANGUAGE], 'EN'), eq([MASTER.LANGUAGE], 'FR'))

All users that speak either English or French and that have a hobby that is either 'BEEKEEPER' or 'RUNNER'

all(in([MASTER.LANGUAGE], 'EN|FR', '|'), lookup([HOBBIES],all(in([HOBBY], 'BEEKEEPER|RUNNER', '|'))))

All users that have a male sibling

lookup([SIBLINGS],all(eq([GENDER], 'Male')))

Every user that has an ID greater than 1 and is named 'Tom' OR Every user for whom the email open rate evolution is going up

any(all(gt([MASTER.ID], toint('1')), eq([MASTER.NAME], 'Tom')), all(eq([SYS_EMAIL_ENGAGEMENT.OPEN_RATE_EVOLUTION], '1')))

All users that have a an STO profile, AND who want to receive the Monthly Newsletter, AND who joined after 1 of june 2024, AND live in Belgium AND Who have opened 50% of the received emails OR who have a click to open rate greater than 50%.

all(isnotempty([SYS_AI_STO_DATA.ID]), eq([PREFERENCES.MONTHLY_NEWSLETTER], tobool('true')), eq([MASTER.COUNTRY], 'BE'), datepartisbefore([MASTER.CREATED_DT], todatetime('2024-06-01 00:00:00', 'yyyy-MM-dd HH:mm:ss'), ''), any(gt([SYS_EMAIL_ENGAGEMENT.OPEN_RATE], todecimal('50')), gt([SYS_EMAIL_ENGAGEMENT.CTO_RATE], todecimal('50'))))

Back to top