Your approach is passing a Liquid template (liquidBody) dynamically through the event payload, expecting Braze to evaluate it at runtime. However, Braze does not support nested Liquid evaluation—meaning if a Liquid template is stored as a string in a property (e.g., liquidBody), it will not be reprocessed dynamically when used inside another Liquid expression.
Instead of rendering the evaluated Liquid template, Braze treats it as a static string, which is why you're seeing the raw {% catalog_items ... %} appear in the notification rather than its resolved value.
Here are a few potential ways to solve this:
- Move the Dynamic Processing Logic to Braze Itself (Recommended)
Since Braze does not support Liquid within Liquid, you can reconstruct the logic directly in Braze instead of passing a pre-formed Liquid template in liquidBody.
Updated Liquid Logic in Braze
Modify your Liquid logic to dynamically generate the content directly inside Braze using the event properties:
{% if canvas_entry_properties.milestoneType == "upgrade" %}
Call {% catalog_items Purchase_PushNotifications {{canvas_entry_properties.organizationId}} %}
{{ items[0].PN_name | default: 'your representative' }} for a free upgrade.
{% else %}
{{ canvas_entry_properties.body }}
{% endif %}
Instead of passing a Liquid template in liquidBody, you pass structured event properties and let Braze generate the final message.