Personalization Using Jinja

Many features in Bloomreach Engagement allow the use of personalization via jinja. This enables you to personalize texts in various campaigns by calling customer attributes, catalog items, etc. Full jinja documentation can be found at and this guide summarizes some of the common examples. Some of the examples can also be found in personalization e.g. email templates.


Jinja can be used for different Use Cases, including:

  • calling user attributes and inserting these values into text. This enables you to easily start the emails, etc. with the customer's first name.
  • referencing catalogs, aggregates, reports, or other features of Bloomreach Engagement in e.g. weblayers
  • creating scripts including conditions, cycles, filters, changing the format of displayed data, etc.


In Bloomreach Engagement, the most common Jinja uses include Jinja expressions, which are called using {{ .... }} tags, and statements, which are called using {% ... %} tags

Global variables in Jinja

Campaigns and Projects have variables. Variables such as ID and name can be used for personalization in campaigns.

Project variables are accessible through all campaigns (Scenario, Banner, Experiments, Tags)
{{ project['id'] }} - id of the project
{{ project['name'] }} - name of the project
Scenario, Email Campaign
{{ scenario['id'] }} - id of the scenario or email campaign
{{ scenario['name'] }} - name of the scenario or email campaign
Scenario Node
{{ action['id'] }} - id of the action node in Scenario where the Jinja was executed
{{ action['name'] }} - the name of the action node in Scenario where the Jinja was executed or the name of the email campaign
{{ banner['id'] }} - id of the banner
{{ banner['name'] }} - name of the banner
{{ banner['variant']['id'] }} - id of the variant
{{ banner['variant']['name'] }} - name of the variant
{{ experiment['id'] }} - id of the experiment
{{ experiment['name'] }} - name of the experiment
{{ experiment['variant']['id'] }} - variant id of the experiment
{{ experiment['variant']['name'] }} - variant name of experiment
Tag manager
{{ tag['id'] }} - id of the tag
{{ tag['name'] }} - name of the tag


Expressions are used when referencing some personalization in Bloomreach Engagement. The basic syntax is usually {{ reference.attribute }}, however, when the attribute or name consists of more words, the syntax has to be {{ reference["reference attribute"] }}. See the full list of available expressions below:

  • Customer attributes - Customer attributes will return the value that is stored in the customer profile for the specified attribute. Basic syntax is {{ customer['attribute'] }}
  • Event trigger attributes - When a scenario is triggered by an event, you can refer to its attributes using {{ event['attribute'] }}. Please note that always the keyword "event." has to be used, not the actual name of the event. To get the type/name of the trigger event such as cart_update, you can use {{ event.event_type }}.
  • Webhook response - Basic syntax is {{ webhook['data'] }} or {{ webhook["JSON object key"] }}. For accessing specific webhook responses, it is also possible to use its node action id by {{ webhook.by_action_id(x).data }}.
  • Metrics - Referenced by {{ metrics["metric ID"] }}
  • Reports - It is possible to return a value from a report based on rows and columns. The syntax is {{ report_value_by_key("Report ID", "row value", "column value", metric order) }}. If you don't have columns or rows, you can skip the value. Metrics start counting from 0, and when you don't input any value, it will get the first metric by default.
  • Fetching a report - For fetching a report as a nested array instead of a dictionary returned by report_value_by_key, the syntax is {{ reports('Report ID').rows }}.
  • Catalog - A product from catalog can be retrieved by {{ catalogs["catalog name"].item_by_id(product_id) }}. To retrieve multiple products at once use {{ catalogs["catalog name"].items_by_id(list_of_ids) }}. Product attributes are then referenced by {{ item["catalog attribute]" }}. Please note that for this to work, you need to define the item first e.g {{ set item = catalogs["Products"].item_by_id(1) }}. Currently, you can provide a maximum of 100 IDs in a single call when retrieving the products, otherwise, you'll experience the Too many ids in items_by_id for catalog products error.
  • Catalog item - Product attributes are referenced by {{ item["catalog attribute]" }}. Please note that for this to work, you need to define the item first e.g {{ set item = catalogs["catalog name"].item_by_id(product_id) }} or see below in statements.
  • Recommendation - Recommendations can be referenced by {{ recommendations("recommendation ID", number_of _products ) }} which will return list of products.
    To display recommended items you can loop through the returned array. Example: {%- set items = recommendations('0a1b2c3d4e5f6g7h8i9j0k', 5) %}
  • Recommendation items - Referenced by {{ item["catalog attribute]" }}. Please note that for this to work, you need to define "item" first, please see below in statements
  • Surveys -Referenced by {{ survey["survey name"] }}. This will generate a hyperlink
  • Unsubscribe link - Is generated by {{ }}. This will bring customers to the unsubscribe page where they can unsubscribe from separate campaign groups. In case the consent framework is not turned on, the link is referenced by {{ email.unsubscribe }}.
  • View in browser - The link that will display the email in the browser is generated by {{ email.view }}. Further details are described in Creating Email Campaigns article.
  • Other than that, it is possible to output some variables that were defined previously {{ variable }}
  • It is possible to use Math operators as well, such as +,-,*,/, however, the expression has to be within one tag, such as {{ 1+1 }}


Jinja expressions for the event object, such as {{ event['attribute'] }}, return data only when you use the event-triggered scenario.

It works similarly for webhook expressions, such as {{ webhook['data'] }}, too. The expressions return data only when the preceding scenario webhook was enabled to process webhook response.

In the case of not fulfilling scenario requirements, both expressions return an empty string.


Jinja references for metrics and reports are cached for 5 minutes before recalculated again by different customers.


Statements in Jinja are operators that can work with data in multiple ways. It allows you to, for example:

  • use conditions with the following syntax (If, else if, else) {% if condition %}value{% elif condition2 %}value2{% else %}value3{% endif %} This will enable you to have e.g. call back values if someone has an empty attribute.
  • use cycles, enabling you to repeat an action several times. This is useful when working with list attributes or JSONs. Syntax is {% for variable in array %} action {% endfor %}
  • using variables using {% set variable = value %}, which is used when referencing a catalog item.

It is also possible to modify the output of the statement using filters that are defined after the pipe | separator. Below are possible uses of the  filters

  • first, last, length
  • lower, upper
  • trim
  • json, from_json
  • from_timestamp('%y-%m-%d')
  • hash
  • b64encode, b64decode, urldecode, urlencode, hexencode, hexdecode
  • round(value, precision=0, method='common')
    • common rounds either up or down
    • ceil always rounds up
    • floor always rounds down

These filters enable you to e.g. set an ID to lowercase email every time, ensuring that you will not generate multiple IDs (which are case sensitive) when the customer decides to identify once with lowercase email and once with uppercase.

Technical Expressions

These expressions are more technical, however - they may still be useful when using Jinja.

  • sent_timestamp - unix timestamp of when the action was executed (eg email/SMS sent time) {{sent_timestamp | from_timestamp }}
  • api_base_url - returns a URL to a path in API
  • public_base_url - returns a URL to a public app-based resource
  • random_bytes - returns a randomly generated byte string with specifiable length (with a default of 16 bytes) - {{ random_bytes() | hexencode }} or {{ random_bytes(256) | b64encode }}

Use case examples

Visit our article Useful jinja snippets to learn about practical examples.