Look-Ups

Lookups in applications are used to represent a set of codes and their translated meanings. Let’s have a look at the available lookup tags within ZML:
Resource Lookups
To add details from specific resources to your content instead of relying on recommendations, you can use the resource look-up merge tags. Resources can be retrieved with either a single resource lookup or by querying for multiple resources.
Resource Filters
Resources are defined at the site level using custom schema, so this documentation will rely on sample concepts that you can apply to your account’s actual data set.
There are two ways to apply filters to resources:
ZML tags (
{% recommendation %},{% resources %}) — written on the fly inside campaigns, templates, and snippets by ZMP users. Filters are expressed inline as simplename, operator, valuetriplets.Resource Groups UI — where users visually build filter rules in the ZMP. These saved groups can then be referenced by uid inside specialized ZML tags.
When a ZML tag runs, inline filters are sent to the API as simple JSON arrays ([{name, operator, values}]). Resource Groups created through the UI are stored as structured filter expressions on the backend and referenced by their unique ID.
Group filters created in the UI can be referenced inside ZML tags via the group_filters: option, bridging both approaches.
ZML Tag: {% resources %}
The full syntax of the {% resources %} tag can be used in various permutations to fetch resources (content items) directly, without personalization. It is recommended to add the resource type as an additional parameter for faster lookup performance during campaign delivery.
{% resources <variable_name>
| count: <number>
| filter: '<field_name>', '<operator>', '<value1>|<value2>|...' --cannot be mixed
| sort_field: '<field_name>'
| sort_order: '<asc|desc>'
| group_filters: '<group_filter_uid1>', '<group_filter_uid2>', ... --cannot be mixed
| expression: (OR, (AND, '<group_filter_uid1>', '<group_filter_uid2>'), '<group_filter_uid3>') --cannot be mixed, given top priority if other filter types are also used in a single tag
%}
Options:
A {% resources %} tag can only filter on one of the following types at a time: expression, group_filters, filter. If all are present, only the expression will be used to return resources.
Option | Required | Multiple | Description |
|---|---|---|---|
| Yes | — | Variable name to store results in. |
| No | Last wins | Number of items to return. Max 10 (best practice). |
| No | Append | Inline filters using Filters are case-sensitive and should be in ALL CAPS. Multiple |
| No | Last wins | Field to sort by. Special values: |
| No | Last wins |
|
| No | Append | Named filter UIDs. Multiple group filters can be named with an implicit OR operator. |
| No | Last wins. Use operators to call more than one resource group.
CODE
| Complex logical combination of group filter UIDs. Accepts AND/OR operators at the beginning of the expression. |
In this example, the user is pulling the 3 resources where the resource type is an article or product that was published in the last 1 day. You can then print the resources using the adrec variable, including data that’s nested inside the resource.
{% resources adrec
| count: 3
| filter: 'resource-type', '=', 'article|product'
| filter: 'pubDate', 'AFTER', '-P1D'
| sort_field: 'pubDate'
| sort_order: 'desc'
%}
Filter Syntax
Each filter: option follows a pattern of three parts, comma-separated:
filter: '<field_name>', '<operator>', '<value1>|<value2>|...'
Position | Name | Required | Description |
|---|---|---|---|
1st | Field name | Yes | Schema field name (e.g. |
2nd | Operator | No | Can be omitted entirely (see examples below). |
3rd | Value(s) | Yes | One or more values. Multiple values separated by pipe |
Parsing details:
Quotes (
'or") around field names, operators, and values are stripped during parsing.Values are always split on pipe (
|) into an array.
How the operator position works:
There are three cases — with an operator, without an operator, and with an explicitly empty operator. They behave differently:
With an operator (3 comma-separated parts):
| filter: 'category', '=', 'shoes|boots'
All three parts are present: field name category, operator =, values shoes and boots.
Without an operator (2 comma-separated parts):
| filter: 'category', 'shoes|boots'
Only two parts: field name category and values shoes and boots. No operator is sent in the payload.
With an explicitly empty operator (3 parts, the middle one is ''):
| filter: 'category', '', 'shoes|boots'
Three parts, but the middle one is an empty string. In {% resources %}, this is normalized to =. In {% recommendation %}, no operator is sent.
Important:
filter: 'resource-type', 'article'has two comma-separated parts —resource-typeis the field name andarticleis the value. This is the "without an operator" case, not the "empty operator" case.
More examples:
| filter: 'pubDate', 'AFTER', '-P7D' → operator: AFTER, values: ["-P7D"]
| filter: 'price', 'BETWEEN', '10|99.99' → operator: BETWEEN, values: ["10", "99.99"]
| filter: 'title', 'CONTAINS', 'sale|clearance' → operator: CONTAINS, values: ["sale", "clearance"]
| filter: 'title', 'NOT', 'draft|archived' → operator: NOT, values: ["draft", "archived"]
| filter: 'featured', '=', 'true' → operator: =, values: ["true"]
Resources vs Recommendations ZML Tag Comparison
There are some slight differences in the ZML tag syntax for resources and recommendations, specifically around operator case.
Operator |
|
| Notes |
|---|---|---|---|
| Yes | Yes (any string passes) | — |
| No (not in allowlist) | Yes (passed through) | Use |
| No (not in allowlist) | Yes (passed through) | Not in the |
| Yes | Yes | — |
| Yes | Yes | — |
| Yes | Yes | — |
| Yes | Yes | — |
| No (not in allowlist) | Yes (passed through) | Silently dropped in |
| Yes | Yes (passed through) | — |
Case-sensitivity | Operator must be UPPERCASE to pass validation: | No validation — any string passes through. The API is similarly case-insensitive. |
|
Specific Resource Lookup
To return an individual resource, use the resource ID. It is recommended to add the resource type as an additional parameter for faster lookup performance during campaign delivery.
CODE
|
This tag creates the object {{product}}and assigns the contents of the resource object to it.
If you want to populate the title of the resource in the content, use {{product.title}}.
Resource Query Parameters
Parameters | Description |
|---|---|
id | Specify the resource ID you’re trying to retrieve. |
resource_type | Specify the resource type. |
Multiple Resource Query
Retrieving multiple resources without the personalization help of our Recommendations engine is done with a resource query. Here is an example of a resources tag:
CODE
|
Resources Query Parameters
To evaluate a parameter, the value must be part of the resources schema and not a property passed by the user.
Parameters | Description |
|---|---|
count | Specify the number of resources to be returned in your query. |
filter | The one or more resource fields to query against. |
sort_field | The timestamp field to sort the returned array on. No other data type is supported.
CODE
|
sort_order | The order in which the array of resources will be returned. |
Points to Remember
CODE
|
Operator names should be in uppercase. In this example, use 'CONTAINS' instead of 'contains.'
Variable names should be unique and differentiated from other variables and values within the tag. In this example, since ‘product’ is used as a value, do not use that as a variable name elsewhere.
v=Variable names should not conflict with property names that may be available on the profile.
Filters have very specific formats that must be respected when building your query. For example,
sku_last_updated GREATER THAN 13 hours agowon’t return any results because it’s not a valid format; instead, use'sku_last_updated', 'BEFORE', '-PT13H'.Filters for
bt_created_atandbt_updated_atare only supported for resources uploaded after .
Resources | Resources, also known as feeds/catalogs, are product listings of a client’s domain like e-commerce, arts, banking, and more. This list is synced to ZMP daily. | |
|---|---|---|
Variants | Variants are sub-products, or child nodes, of the same product. | |
Default Product ![]() | Variant Product: (Blue Highlight) ![]() | |
ZMP will result in only very few products in the resources' graphical UI. So, to identify and analyze all the data available in resources, we are using the following liquid syntax as a solution:
Results in Resources UI ![]() Resource Lookup Syntax
CODE
Resource with Variant Lookup Syntax
CODE
|
Event Lookups
Trigger Event Object
For content being sent from a triggered campaign, an event object is available to populate information in content from the event that triggered the campaign. The properties available in the event are the same properties passed in the payload of the event. Take the following purchased event as an example:
Purchased Event Payload
|
To populate the productname information from the first item in this purchased event, we can use the following event object:
Input
|
Output
|
Event Lookup Tag
Multiple past events can also be used in content using an event lookup tag.
The following example creates a variable called purchases as an array of the last three purchase events for the given user_id the message is being created for. The full contents of the array can be viewed in content using {{purchases}} or a for loop to iterate over the array to find the details you need.
Input
CODE
|
The event_type parameter can be changed to retrieve events of the specified name. The count parameter sets the limit on the number of past events to be retrieved.
Event Lookup Tag Query Parameters
Parameters | Description |
|---|---|
event_type | The exact name of the account event to look up. |
count | Specify the number of past events to be retrieved. |


