Context
Context steps allow you to create and update one or more variables for a user as they move through a Canvas. For example, if you have a Canvas that manages seasonal discounts, you can use a context variable to store a different discount code each time a user enters the Canvas.
Context steps are currently in early access. Contact your Braze account manager if you’re interested in participating in this early access.
Note that opting into the Canvas Context step early access will make changes to how timestamps are handled across all your Canvases. To learn more about this, refer to Time zone consistency standardization.
How it works

Context steps allow you to create and use temporary data during a user’s journey through a specific Canvas. This data exists only within that Canvas journey and doesn’t persist across different Canvases or outside the session.
Within this framework, each Context step can define multiple context variables—temporary pieces of data that enable you to personalize delays, segment users dynamically, and enrich messaging without permanently altering a user’s profile information.
For example, if you’re managing flight bookings, you could create a context variable for each user’s scheduled flight time. You could then set delays relative to each user’s flight time and send personalized reminders from the same Canvas.
You can set context variables in two ways:
- At Canvas entry: When users enter a Canvas, data from the event or API trigger can automatically populate context variables.
- In a Context step: You can define or update context variables manually inside the Canvas by adding a Context step.
Each context variable includes:
- A name (such as
flight_timeorsubscription_renewal_date) - A data type (such as number, string, time, or array)
- A value you assign using Liquid or through the Add Personalization tool.
When defined, you can use a context variable throughout the Canvas by referencing it in this format: {{context.${example_variable_name}}}.
For example, {{context.${flight_time}}} could return the user’s scheduled flight time.
Each time a user enters the Canvas—even if they have entered it before—the context variables will be redefined based on the latest entry data and Canvas setup. This stateful approach allows each Canvas entry to maintain its own independent context, allowing users to have multiple active states within the same journey while retaining the specific context for each state.
For example, if a customer has two upcoming flights, they’ll have two separate journey states running simultaneously—each with its own flight-specific context variables like departure time and destination. This allows you to send personalized reminders about their 2 pm flight to New York while sending different updates about their 8 am flight to Los Angeles tomorrow, so that each message stays relevant to the specific booking.
Considerations
- You can have up to 10 context variables per Context step.
- Each context variable name can be up to 100 characters.
- Context variable names must be valid identifiers (letters, numbers, underscores only).
- Context variable definitions can be up to 10,240 characters.
- Context variables passed into an API-triggered Canvas share the same namespaces as context variables created in a Context step in a Canvas. This means if you send a variable
purchased_itemin the/canvas/trigger/sendendpoint context object, it can be referenced as{context.${purchased_item}}, and re-declaring that variable in a Context step in the Canvas will override what was previously sent. - You can store up to 50 KB per context step, distributed up to 10 variables per step. Variable sizes that sum up to over 50 KB in one step won’t be evaluated or stored for the user. These sizes are calculated in sequence. For example, if you have 3 variables in a Context step:
- Variable 1: 30 KB
- Variable 2: 19 KB
- Variable 3: 2 KB
- This means Variable 3 won’t be evaluated or stored because the sum of all other context variables exceeds 50 KB.
Creating a Context step
Step 1: Add a step
Add a step to your Canvas, then drag and drop the component from the sidebar, or select the plus button and select Context.
Step 2: Define the variables
You can define up to 10 context variables for each Context step.
To define a context variable:
- Give your context variable a name.
- Select a data type.
- Write a Liquid expression manually or use Add Personalization to create a Liquid snippet from pre-existing attributes.
- Select Preview to check the value of your context variable.
- (Optional) To additional variables, select Add Context variable and repeat steps 1–4.
- When you’re finished, select Done.
Now you can use your context variable anywhere you use Liquid, such as in Message and User Update steps, by selecting Add Personalization. For a full walkthrough, see Using context variables.
Context variable data types
Context variables that are created or updated in the step can be assigned the following data types.
Context variables have the same expected formats for data types as custom events.
For nested objects and array of objects, use the as_json_string Liquid filter. If you’re creating the same object in a Context step, you’ll need to render the object using as_json_string, such as {{context.${object_array} | as_json_string }}
| Data type | Example variable name | Example value |
|---|---|---|
| Boolean | loyalty_program | true |
| Number | credit_score | 740 |
| String | product_name | green_tea |
| Array | favorite_products | ["wireless_headphones", "smart_homehub", "fitness_tracker_swatch"] |
| Time (in UTC) | last_purchase_date | 2025-12-25T08:15:30:250-0800 |
| Object (flattened) | user_profile | { |
By default, the time data type is in UTC. If you use a string data type to store a time value, you can define the time as a different time zone like PST.
For example, if you’re sending a message to a user the day before their birthday, you would save the context variable as a time data type because there’s Liquid logic associated with sending the day before. However, if you’re sending a holiday message on Christmas Day (December 25), you wouldn’t need to reference the time as a dynamic variable, so using a string data type would be preferable.
Using context variables
For example, let’s say you want to notify passengers about their VIP lounge access before their upcoming flight. This message should only be sent to passengers who purchased a first-class ticket. A context variable is a flexible way to track this information.
Users will enter the Canvas when they purchase a plane ticket. To determine lounge access eligibility, we’ll create a context variable called lounge_access_granted in a Context step, then reference that context variable in subsequent steps of the user journey.

In this Context step, we’ll use {{custom_attribute.${purchased_flight}}} to determine if the type of flight they’ve purchased is first_class.
Next, we’ll create a Message step to target users where {{context.${lounge_access_granted}}} is true. This message will be a a push notification that includes personalized lounge information. Based on this context variable, the eligible passengers will receive the relevant messages before their flight.
- First-class ticket passengers will receive: “Enjoy exclusive VIP lounge access!”
- Business and economy ticket passengers will receive: “Upgrade your flight for exclusive VIP lounge access.”

You can add personalized delay options with the information from the Context step, meaning you can select the variable that delays users.
For Action Paths and exit criteria
You can leverage comparing property filters with either context variables or custom attributes in these trigger actions: Perform Custom Event and Make Purchase. These action triggers also support property filters for both basic and nested properties.
- When comparing against basic properties, the available comparisons will match the type of the property defined by the custom event. For example, string properties will have exactly equal, regex matches. Boolean properties will be true or false.
- When comparing against nested properties, types are not pre-defined, so you can select comparisons across multiple data types for booleans, numbers, strings, time, and day of year, similar to the comparisons for nested custom attributes. If you select a data type that doesn’t match the actual data type of the nested property at the time of comparison, the user will not match the Action Path or exit criteria.
Action Path examples
For custom attribute comparisons, we’ll use the custom attribute value at the time the action is performed. This means a user won’t match the Action Path group if a user doesn’t have this custom attribute populated at the time of comparison, or if the custom attribute value doesn’t match the defined property comparisons. This is the case even if the user would have matched when they entered the Action Path step.
The following Action Path is set up to sort users who performed the custom event Account_Created with the basic property source to the context variable app_source_variable.

The following Action Path is set up to match the basic property brand for the specific product name shoes to a context variable promoted_shoe_brand.

Exit criteria examples
The exit criteria state that at any point in a user’s journey in the Canvas, they’ll exit the Canvas if:
- They perform the custom event Abandon Cart, and
- The basic property Item in Cart matches the string value of the context variable
cart_item_threshold.

The exit criteria state that at any point in a user’s journey in the Canvas, they’ll exit the Canvas if:
- They make a specific purchase for the “book” product name, and
- That purchase’s nested property “loyalty_program” is equal to the user’s custom attribute “VIP”.

Context variable filters
You can create filters that use previously declared context variables in Audience Paths and Decision Split steps.
Context variable filters are only available for Audience Paths and Decision Split steps.
Context variables are declared and only accessible in the scope of a Canvas, meaning they can’t be referenced in segments. Context variable filters function similarly in Audience Paths and Decision Split steps—Audience Path steps represent multiple groups, while Decision Split steps represent binary decisions.

Similar to how Canvas context variables have pre-defined types, the comparisons between context variables and static values must have matching data types. The context variable filter allows comparisons across multiple data types for booleans, numbers, strings, time, and day of year, similar to the comparisons for nested custom attributes.
Use the same data type for your context variable and comparison. For example, if your context variable is a time data type, use time comparisons (such as “before” or “after”). Using mismatching data types (such as string comparisons with a time context variable) may cause unexpected behavior.
Here is an example of a context variable filter comparing the context variable product_name to the regex /braze/.

Comparing to context variables or custom attributes
By selecting the Compare to a context variable or custom attribute toggle, you can construct context variable filters that compare against previously-defined context variables or user custom attributes. This can be useful for performing comparisons that are dynamic per user, like API-triggered context, or to condense complex comparison logic defined across context variables.
Let’s say you want to send a personalized reminder to users after a dynamic period of inactivity, which includes anyone who hasn’t logged into your app in the last three days, should receive a message.
You have a context variable re_engagement_date that is defined as {{now | minus: 3 | append: ' days'}}. Note that 3 days can be a variable amount that is also stored as a user’s custom attribute. So if the re_engagement_date is after the last_login_date (stored as a custom attribute on the user profile), they’ll be sent a message.

The following filter compares the context variable reminder_date to be before the context variable appointment_deadline. This can help group users in an Audience Paths step to determine whether they should receive additional reminders before their appointment deadline.

Previewing user paths
We recommend testing and previewing your user paths to make sure your messages are sent to the right audience and context variables are evaluated to the expected outcomes.
If you’re previewing your Canvas in the Preview & Test Send section of the editor, the timestamp in the test message preview will not be standardized to UTC because this panel generates previews as strings. This means if a Canvas is set up to accept a time object, the message preview won’t accurately preview what occurs when the Canvas is live. To test your Canvas most accurately, we recommend previewing user paths instead.
Be sure to observe any common scenarios that create invalid context variables. When previewing your user path, you can view the outcomes of personalized Delay steps using context variables, and any audience, decision, or Action Path step comparisons that match users to any context variables.
If the context variable is valid, you can reference the variable throughout your Canvas. However, if the context variable wasn’t created correctly, future steps in your Canvas won’t perform correctly either. For example, if you create a Context step to assign users an appointment time but set the appointment time’s value to a past date, the reminder email in your Message step will never be sent.
Converting Connected Content strings to JSON
When making a Connected Content call in a Context step, JSON returned from the call will be evaluated as a string data type for consistency and error prevention. If you want to convert this string into JSON, convert it by using as_json_string. For example:
1
2
{% connected_content http://example.com :save product %}
{{ product | as_json_string }}
Time zone consistency standardization
While most event properties using the timestamp type are already in UTC in Canvas, there are some exceptions. With the addition of Canvas Context, all default timestamp event properties in action-based Canvases will consistently be in UTC. This change is part of a broader effort to ensure a more predictable and consistent experience when editing Canvas steps and messages. Note that this change will impact all action-based Canvases, whether the specific Canvas is using a Context step or not.
In all circumstances, we strongly recommend using Liquid time_zone filters for timestamps to be represented in the desired time zone. You can reference this frequently asked question for an example.
Troubleshooting
Invalid context variables
A context variable is considered invalid when:
- A call to an embedded Connected Content fails.
- The Liquid expression at runtime returns a value that doesn’t match the data type or is empty (null).
For example, if the context variable data type is Number but the Liquid expression returns a string, it is invalid.
In these circumstances:
- The user will advance to the next step.
- The Canvas step analytics will count this as Not Updated.
When troubleshooting, monitor the Not Updated metric to check that your context variable is updating correctly. If the context variable is invalid, your users can continue in your Canvas past the Context step, but may not qualify for later steps.
Refer to Context variable data types for the example setups for each data type.
Frequently asked questions
What will be changing when Canvas Context becomes generally available?
When Canvas Context becomes generally available, the following details will apply:
- All timestamps with a datetime type from trigger event properties in action-based Canvases will always be in UTC.
- This change will impact all action-based Canvases, whether the specific Canvas is using a Context step or not.
What is the reason for this change?
This change is part of a broader effort to create a more predictable and consistent experience when editing Canvas steps and messages.
When is this change taking effect?
- If you’re participating in the Canvas Context early access, this change has already been applied.
- If you’re not participatig in the Canvas Context early access, this change will apply when you join the early access or when Canvas Context becomes generally available.
Are API-triggered or scheduled Canvases impacted by this change?
No.
Will this change impact Canvas entry properties?
Yes, this will impact canvas_entry_properties if the canvas_entry_property is being used in an action-based Canvas and the property type is time. In all circumstances, we recommend using Liquid time_zone filters for timestamps to be represented in the desired timezone.
Here is an example on how to do this:
| Liquid in Message step | Output | Is this the way to represent time zones correctly in Liquid? |
|---|---|---|
{{canvas_entry_properties.${timestamp_property}}} |
2025-08-05T08:15:30:250-0800 |
No |
{{canvas_entry_properties.${timestamp_property} | date: "%Y-%m-%d %l:%M %p"}} |
2025-08-05 4:15pm |
No |
{{canvas_entry_properties.${timestamp_property} | time_zone: "America/Los_Angeles" | date: "%Y-%m-%d %l:%M %p"}} |
2025-08-05 8:15am |
Yes |
What is a practical example of how the new timestamp behavior might affect my messages?
Let’s say we have an action-based Canvas that has the following content in a Message step:
1
Your appointment is scheduled for {{canvas_entry_properties.${appointment_time} | date: "%Y-%m-%d %l:%M %p"}}, we'll see you then!
This will result in the following message:
1
Your appointment is scheduled for 2025-08-05 4:15pm, we’ll see you then!
Because no time zone is specified using Liquid, the timestamp here is in UTC.
To specify a time zone clearly, we can use Liquid time_zone filters like this:
1
Your appointment is scheduled for {{canvas_entry_properties.${appointment_time} | time_zone: "America/Los_Angeles" | date: "%Y-%m-%d %l:%M %p"}}, we'll see you then!
This will result in the following message:
1
Your appointment is scheduled for 2025-08-05 8:15am, we'll see you then!
Because the America/Los Angeles time zone is specified using Liquid, the timestamp here is in PST.
The preferred time zone can also be sent in the event properties payload like this and used in Liquid logic:
1
2
3
4
{
"appointment_time": "2025-08-05T08:15:30:250-0800"
"user_timezone": "America/Los_Angeles"
}
How do context variables differ from Canvas entry properties?
If you’re participating in the Context step early access, Canvas entry properties are now included as Canvas context variables. This means you can send Canvas entry properties using the Braze API and reference them in other steps, similar to using a context variable with the Liquid snippet.
Can variables reference each other in a singular Context step?
Yes. All variables in a Context step are evaluated in a sequence, meaning you could have the following context variables setup:
| Context variable | Value | Description |
|---|---|---|
favorite_cuisine |
{{custom_attribute.${Favorite Cuisine}}} |
A user’s favorite type of cuisine. |
promo_code |
EATFRESH |
The available discount code for a user. |
personalized_message |
"Enjoy a discount of" {{context.promo_code}} "on delivery from your favorite" {{context.favorite_cuisine}} restaurants!" |
A personalized message that combines the previous variables. In a Message step, you could use the Liquid snippet {{context.${personalized_message}}} to reference the context variable to deliver a personalized message to each user. You could also use a Context step to save the promo code value and template it in other steps throughout a Canvas. |
This also applies across multiple Context steps. For example, imagine this sequence:
- An initial Context step creates a variable called
JobInfowith the valuejob_title. - A Message step references
{{context.${JobInfo}}}and displaysjob_titleto the user. - Later, a Context step updates the context variable, changing the value of
JobInfotojob_description. - All subsequent steps that reference
JobInfowill now use the updated valuejob_description.
Context variables use their most recent value throughout the Canvas, with each update affecting all following steps that reference that variable.
Edit this page on GitHub