Personalized Messaging

Braze allows you to personalize your campaigns by inserting user-specific information, such as the user’s name, into messages. Campaign messages support templated messaging using the Liquid templating language. Detailed documentation of Liquid syntax and usage is available here.

Liquid templating language supports the use of objects, tags and filters.

Objects allow you to insert personalizable attributes into your messages.

Tags allow you to execute programming logic in your messages. For example, you can use tags to include intelligent logic, such as “if” statements, in your campaigns.

Filters allow you to reformat personalizable attributes and dynamic content. For example, you could convert a timestamp, such as 2016-09-07 08:43:50 UTC into a date such as September 7th, 2016.

Adding Personalizable Attributes (Objects)

Braze can automatically substitute values from a given user into your messages. Put your expression inside of two sets of curly brackets to notify Braze that you’ll be using an interpolated value. Inside of these brackets, any user values that you want to substitute must be surrounded by an additional set of brackets with a dollar sign in front of them. For example, if you include the following text in your message: {{${first_name}}}, the appropriate value from the user will be interpolated when the message is sent. If you would like to use the value of a custom attribute, you must add the namespace “custom_attribute” to the variable. For example, to use a custom attribute named “zip code”, you would include {{custom_attribute.${zip code}}} in your message.

The following user values can be substituted into a message:

You can also pull content directly from a web server via Braze’s Connected Content feature.

Supported Personalization Tag Summary

As a convenience, a summary of supported personalization tags are listed below. For more detail on each kind of tag and best practices, continue reading.

Personalization Tag Type Tags
Default Attributes {{${city}}}, {{${country}}}, {{${date_of_birth}}}, {{${email_address}}}, {{${first_name}}}, {{${gender}}}, {{${language}}}, {{${last_name}}}, {{${last_used_app_date}}}, {{${most_recent_app_version}}}, {{${most_recent_locale}}}, {{${most_recent_location}}}, {{${phone_number}}}, {{${time_zone}}}, {{${twitter_handle}}}, {{${user_id}}}, {{${braze_id}}}
Device Attributes {{most_recently_used_device.${carrier}}}, {{most_recently_used_device.${id}}}, {{most_recently_used_device.${idfa}}}, {{most_recently_used_device.${model}}}, {{most_recently_used_device.${os}}}, {{most_recently_used_device.${platform}}}
Email List Attributes (learn more here) {{${set_user_to_unsubscribed_url}}}, {{${set_user_to_subscribed_url}}}, {{${set_user_to_opted_in_url}}}
Campaign Attributes* {{campaign.${api_id}}}, {{campaign.${name}}}
Canvas Attributes* {{canvas.${name}}}, {{canvas.${api_id}}}, {{canvas.${variant_name}}}, {{canvas.${variant_api_id}}}
Card Attributes* {{card.${api_id}}}, {{card.${name}}}
Event Properties These are custom to your app group and in the format {{event_properties.${your_custom_event_property}}}.
Custom Attributes These are custom to your app group and in the format {{custom_attribute.${your_custom_attribute}}}.

* Campaign, Card, and Canvas attributes are only supported in their corresponding messaging templates.

Setting Default Values

We highly recommend that you use set default fallback values for any personalization attribute that you use in your messages. Default values can be added by specifying a Liquid Filter with the name “default.” If a default value is not provided and the field is missing or not set on the user, the field will be blank in the message.

The example below shows the correct syntax for adding a default value. In this case, the words “Valued User” will replace the attribute {{${first_name}}} if a user’s first_name field is blank or unavailable.

Hi {{${first_name} | default: 'Valued User' }}, thanks for using the App!

As a convenience, you may insert preformatted variables with defaults through the “Insert Personalization Attribute” modal located on the top-right of a templatable text field.

Modal buttons

The modal will insert Liquid with your specified default value at the point that your cursor was. The insertion point is also specified via the preview box, which has the before and after text. If a block of text is highlighted, the highlighted text will be replaced.


Most Recently Used Device Information

You can template in the following attributes for the user’s most recent device across all platforms. If a user has not used your application (e.g., you imported the user via REST API), then these values will all be null.

  • {{most_recently_used_device.${id}}} - This is Braze’s device identifier. On iOS, this is the Apple Identifier for Vendor (IDFV). For Android and other platforms, it is Braze’s device identifier, a randomly generated GUID.
  • {{most_recently_used_device.${carrier}}} - The most recently used device’s telephone service carrier, if available. Examples include “Verizon” and “Orange”.
  • {{most_recently_used_device.${idfa}}} - For iOS devices, this value will be the Identifier for Advertising (IDFA) if your application is configured with Braze’s optional IDFA collection. For non-iOS devices, this value will be null.
  • {{most_recently_used_device.${model}}} - The device’s model name, if available. Examples include “iPhone 6S” and “Nexus 6P” and “Firefox”.
  • {{most_recently_used_device.${os}}} - The device’s operating system, if available. Examples include “iOS 9.2.1” and “Android (Lollipop)” and “Windows”.
  • {{most_recently_used_device.${platform}}} - The device’s platform, if available. If set, the value will be one of ios, android, windows, windows8, kindle, android_china, web, or tvos.

Because there are such a wide range of device carriers, model names, and operating systems, we advise that you thoroughly test any logic that conditionally depends on any of those values. These values will be null if they are not available on a particular device.

Targeted Device Information

For push notification and in-app message channels, you can template in the following attributes for the device to which a message is being sent. That is, a push notification or in-app message can include device attributes of the device on which the message is being read.

  • {{targeted_device.${id}}} - This is Braze’s device identifier. On iOS, this is the Apple Identifier for Vendor (IDFV). For Android and other platforms, it is Braze’s device identifier, a randomly generated GUID.
  • {{targeted_device.${carrier}}} - The most recently used device’s telephone service carrier, if available. Examples include “Verizon” and “Orange”.
  • {{targeted_device.${idfa}}} - For iOS devices, this value will be the Identifier for Advertising (IDFA) if your application is configured with Braze’s optional IDFA collection. For non-iOS devices, this value will be null.
  • {{targeted_device.${model}}} - The device’s model name, if available. Examples include “iPhone 6S” and “Nexus 6P” and “Firefox”.
  • {{targeted_device.${os}}} - The device’s operating system, if available. Examples include “iOS 9.2.1” and “Android (Lollipop)” and “Windows”.
  • {{targeted_device.${platform}}} - The device’s platform, if available. If set, the value will be one of ios, android, windows, windows8, kindle, android_china, web, or tvos.

Because there are such a wide range of device carriers, model names, and operating systems, we advise that you thoroughly test any logic that conditionally depends on any of those values. These values will be null if they are not available on a particular device. Furthermore, for push notifications, it is possible that Braze may be unable to discern the device attached to the push notification under certain circumstances such as if the push token was imported via API, resulting in values being null for those messages.


In some circumstances, you may opt to use conditional logic instead of setting a default value. Conditional logic allows you to send messages that differ based on the value of a custom attribute.

Additionally, you can use conditional logic to abort messages to customers with null or blank attribute values.

For example, if you’re sending a rewards balance notification to customers, there isn’t a good way to account for customers with low and null balances using default values.

In this case, there are two options that may work better than setting a default value:

  1. Abort the message for customers with low, null and blank balances.


  2. Send a completely different message to these customers, perhaps something along the lines of:

{% if ${first_name} != blank and ${first_name} != null %}
Hello {{${first_name} | default: 'there'}}, thanks for downloading
{% else %}
Thanks for downloading
{% endif %}

In this example, a user with a blank or null first name will get the message “Thanks for downloading”. Note that as a best practice, you should still include a default value for first name.

Conditional Messaging Logic (Tags)

Tags allow you to include programming logic in your messaging campaigns.

A tag must be wrapped in {% %}.

Tags can be used for executing conditional statements as well as for advanced use cases, like assigning variables or iterating through a block of code.

Conditional Logic

You can include many types of intelligent logic within messages – one example is a conditional statement. See the following example which uses conditionals to internationalize a campaign:

{% if ${language} == 'en' %}
This is a message in English from Braze!
{% elsif ${language} == 'es' %}
Este es un mensaje en español de Braze !
{% elsif ${language} == 'zh' %}
{% else %}
This is a message from Braze! This is going to go to anyone who did not match the other specified languages!
{% endif %}

Conditional Logic: Step By Step

In this example, we use tags with “if”, “elsif” and “else” statements to deliver internationalized content.

{% if ${language} == 'en' %}
This is a message in English from Braze!

If the customer’s language is English, the first condition is met and the customer will receive a message in English.

{% elsif ${language} == 'es' %}
Este es un mensaje en español de Braze !
{% elsif ${language} == 'zh' %}

You can specify as many conditional statements as you’d like- subsequent conditions will be checked if the previous conditions are not met. In this example, if a customer’s device is not set to English this code will check to see if the customer’s device is set to Spanish or Chinese. If the customer’s device meets one of these conditions, the customer will receive a message in the relevant language.

{% else %}
This is a message from Braze! This is going to go to anyone who did not match the other specified languages!

You have the option to include an {% else %} statement in your conditional logic. If none of the conditions that you set are met, the {% else %} statement specifies the message that should send. In this case, we default to English if a customer’s language is not English, Spanish or Chinese.

{% endif %}

The {% endif %} tag signals that you’ve finished your conditional logic. You must include the {% endif %} tag in any message with conditional logic. If you do not include an {% endif %} tag in your conditional logic, you’ll get an error as Braze will be unable to parse your message.


Liquid supports many operators that can be used in your conditional statements.

Syntax Operator Description
== equals
!= does not equal
> greater than
< less than
>= greater than or equal to
<= less than or equal to
or condition A or condition B
and condition A and condition B
contains checks to see if a string or string array contains a string

Operator Examples

Here are some examples of how these operators could be helpful for your marketing campaigns:

Total Revenue - sending messages based on an integer custom attribute for “Total Revenue”:

total revenue

In this example, if a customer’s “Total Revenue” custom attribute is greater than zero, they will get the message:

We appreciate your business! Use our coupon SAVE10 for an extra 10% off your next purchase.

If a customer’s “Total Revenue” custom attribute does not exist or is equal to 0, they will get the following message:

Make your first purchase today! Use our coupon SAVE10 for an extra 10% off

Games Attended - sending messages that differ based on an integer attribute, “Number Games Attended”:

games liquid

In this example, if you have attended one game, you get the following message:

Loved that sport game? Get 10% off your second one with code SAVE10

If you have attended more than one game, you get:

Love sports games? Get 10% your next one with code SAVE10

If you haven’t attended any games, or that custom attribute doesn’t exist on your profile, you’d get the following message:

Attend your first game! 10% off with code SAVE10

Accounting For Null Attribute Values

Conditional logic is a useful way to account for null attribute values. A null value occurs when the value of a custom attribute has not been set. For example, a user who has not yet set their first name will not have a first name in Braze’s database.

In some circumstances, you may wish to send a completely different message to users who have a first name set and users who do not have a first name set.

The following tag allows you to specify a message for users with a null “first name” attribute:

{% if ${first_name} == null %}


Aborting Messages

Optionally, you can also now abort messages within conditionals. Here are some examples of how this feature can be used in marketing campaigns:

Aborting message if “Number Games Attended” = 0:

For example, let’s say that you did not want to send the above message to customers who had not attended a game:

liquid abort message

This message will only send to customers who are known to have attended a game.

Messaging English speaking customers only:

You can message English speaking customers only by creating an “if” statement that’ll match when a customer’s language is English and an else statement that’ll abort the message for anyone who does not speak English or does not have a language on their profile.

{% if ${language} == 'en' %}
Send this message in English!
{% else %}
{% abort_message() %}
{% endif %}

You can have the abort_message log something to your Developer Console log by including a string inside the parentheses:

{% abort_message('language was nil') %}


Manipulating Message Content (Filters)

Filters can be used to reformat static or dynamic content. For example, you can use a filter to reformat a string from uppercase to lowercase or to perform mathematical operations.

Filters should be placed within an output tag {{ }} and should be separated from the value that you’d like to reformat with a pipe character |.

For example, the output of {{"Big Sale" | upcase}} is “BIG SALE”.

Or, let’s say that you’re running a campaign where you’re offering customers 50 rewards points if they make a purchase and you’ve stored their current rewards balance as a custom attribute.

You can use the add filter to show customers what their rewards balance would be if they made an additional purchase:

Hey Marion, make a purchase today to earn 50 pts and bring your rewards balance to {{custom_attribute.${current_rewards_balance} | plus: 50}}.

Math Filters

Math filters allow you to complete basic mathematical operations in the message composer. For example, you can add or subtract static values or variables to and from numeric personalizable attributes, other static values and or other variables. In this example, let’s assume that the value of current_rewards_balance is 50.


Hey Marion, make a purchase today to earn 50 pts and bring your rewards balance to {{custom_attribute.${current_rewards_balance} | plus: 50}}.


Hey Marion, make a purchase today to earn 50 pts and bring your rewards balance to 100.

Note: you cannot perform mathematical operations with two custom attributes. You must first define one of the custom attributes as a variable and then perform the operation with the variable and the remaining attribute.

For example,

{{custom_attribute.${current_rewards_balance} | plus: {{custom_attribute.${giftcard_balance}}}}}

will not work. Instead, you should use a variable tag to capture the value of one of the custom attributes:

{% assign balance = {{custom_attribute.${current_rewards_balance}}} %}
{{custom_attribute.${giftcard_balance} | plus: balance}}

String Filters

String filters are used to manipulate the outputs and variables of strings. For example, you can capitalize a string.

Array Filters

Array filters can be used to manipulate the outputs of arrays. All array filters listed here are compatible with Braze’s message composer.

For example, the first filter can used to template the first value in an array into the message composer. Please note that the first value in an array custom attribute array is the most recently added value.

{{custom_attribute.${my_array} | first}} will yield the most recently added value. If “my_array” is a custom attribute array that consists of “apple, orange, banana” the output of {{custom_attribute.${my_array} | first}} will be “apple”.

Date Filters

Date filters can be used to convert a timestamp into a different date format. Let’s say that the value of “date_attribute” is the timestamp 2015-06-03 17:13:41 UTC.

{{custom_attribute.${date_attribute} | date: "%b","%d"}} will reformat this timestamp to “03 June”. There are many other date formatting options which you can find here.

In addition to these formatting options, we also support converting a timestamp to Unix time with the “%s” date filter.

For example, to get the “date_attribute” in Unix time, you’d input {{custom_attribute.${date_attribute} | date: "%s" }} and get the integer 1433351621 as an output.

In addition to the filters that you’ll find listed in Shopify’s documentation, we also support the “time_zone” filter.

The “Time_zone” filter takes a time, a time zone, and a date format and returns the time in that timezone in the specified date format. For example, let’s say that the value of {{custom_attribute.${date_attribute}}} is 2015-04-03 9:00:00 UTC.


{{custom_attribute.${date_attribute} | time_zone: 'America/Los_Angeles' | date: '%a %b %e %T' }}


Fri April 3 2:00:00

Additionally you can access the current time for manipulation by doing something like the following:

{{ 'now' | date: '%Y-%m-%d %H:%M:%S' }}

Which will return something like:

2016-08-22 18:13:13

Advanced Filters

Encoding Filters

filter name filter description example input example output
md5 returns md5 encoded string {{'hey' | md5}} 6057f13c496ecf7fd777ceb9e79ae285
sha1 returns sha1 encoded string {{'hey' | sha1}} 7f550a9f4c44173a37664d938f1355f0f92a47a7
sha2 returns sha2 encoded string {{'hey' | sha2}} fa690b82061edfd2852629aeba8a8977b57e40fcb77d1a7a28b26cba62591204
base64 encodes string into base64 {{'blah' | base64_encode}} YmxhaA==
hmac_sha1 returns hmac-sha1 encoded string {{'hey' | hmac_sha1: 'secret_key'}} 2a3969bed25bfeefb00aca4063eb9590b4df8f0e

URL Filters

filter name filter description example input example output
url_escape identifies all characters in a string that are not allowed in URLS, and replaces the characters with their escaped variants {{'hey<>hi' | url_escape}} hey%3C%3Ehi
url_param_escape replaces all characters in a string that are not allowed in URLs with their escaped variants, including the ampersand (&) {{'hey<&>hi' | url_param_escape} hey%3C%26%3Ehi
url_encode encodes a string that is url friendly {{ 'google search' | url_encode }} google+search

Property Accessor Filter

property_accessor takes a hash and hash key and returns the value in that hash at that key

Example hash : {“a” => 42, “b” => 0}

Example input: {{hash | property_accessor: 'a'}}

Example output: 42

Additionally, the property accessor filter allows you to template a custom attribute into a hash key to access a particular hash value.

Number formatting filters

filter name filter description example input example output
number_with_delimiter Formats a number with commas {{ 123456 | number_with_delimiter }} 123,456

JSON Escape / String Escape Filter

json_escape escapes any special characters in a string (i.e. double quote "" and backslash ‘').

This filter should always be used when personalizing a string in a JSON dictionary and is useful for webhooks in particular.

Advanced Use Cases

Variable Tags

You can use the assign tag to create a variable in the message composer. Once you create a variable, you can reference that variable in your messaging logic or message.

Let’s say that you allow your customers to cash in their rewards points for prizes once they accrue 100 rewards points. So, you only want to message customers who would have a points balance above or equal to 100 if they made that additional purchase:

{% assign new_points_balance = {{custom_attribute.${current_rewards_balance} | plus: 50}} %}
{% if new_points_balance >= 100 %}
Make a purchase to bring your rewards points to {{new_points_balance}} and cash in today!
{% else %}
{% abort_message('not enough points') %}
{% endif %}

This tag comes in handy when you want to reformat content that is returned from our connected content feature. You can read more about variable tags here.

Iteration Tags

Iteration tags can be used to run a block of code repeatedly. This example features the for tag.

Let’s say that you’re having a sale on Nike sneakers and want to message customers who’ve expressed interest in Nike. You have an array of product brands viewed on each customer’s profile. This array could contain up to 25 product brands, but you only want to message customers who viewed a Nike product as one of their 5 most recent product views.

{% for items in {{custom_attribute.${Brands Viewed}}} limit:5 %}
{% if {{items}} contains 'Converse' %}
{% assign converse_viewer = true %}
{% endif %}
{% endfor %}
{% if converse_viewer == true %}
Sale on Converse!
{% else %}
{% abort_message() %}
{% endif %}

In this example, we check the first five items in the sneaker brands viewed array. If one of those items is converse, we create the converse_viewer variable and set it to true.

Then, we send the sale message when converse_viewer is true. Otherwise, we abort the message.

This is a simple example of how iteration tags can be used in Braze’s message composer. You can find more information here.

HTTP Status Codes

You can utilize the HTTP status from a Connected Content call by first saving it as a local variable and then using the __http_status_code__ key. For example:

{% connected_content :save connected %}
{% if connected.__http_status_code__ != 200 %}
{% abort_message('Connected Content returned a non-200 status code') %}
{% endif %}

Note: Be aware that this key will only be automatically added to the Connected Content object if the endpoint returns a JSON object. If the endpoint returns an array or other type, then that key cannot be set automatically in the response.

Sending Messages Based on Language, Most Recent Locale, and Time Zone

In some situations you may wish to send messages that are specific to particular locales. For example, Brazilian Portuguese is typically different than European Portuguese.

Here’s an example of how you can use most recent locale to further localize an internationalized message.

{% if ${language} == 'en' %}
Message in English
{% elsif  ${language} == 'fr' %}
Message in French
{% elsif  ${language} == 'ja' %}
Message in Japanese
{% elsif  ${language} == 'ko' %}
Message in Korean
{% elsif  ${language} == 'ru' %}
Message in Russian
{% elsif ${most_recent_locale} == 'pt_BR' %}
Message in Brazilian Portuguese
{% elsif ${most_recent_locale} == 'pt_PT' %}
Message in European Portuguese
{% elsif  ${language} == 'pt' %}
Message in default Portuguese
{% else %}
Message in default language
{% endif %}

In this example, customers with a most recent locale of ‘pt_BR’ will get a message in Brazilian Portuguese, customers with a most recent locale of ‘pt_PT’ will get a message in European Portuguese and customers who don’t meet the first two conditions but have their language set to Portuguese will get a message in whatever you’d like the default Portuguese language type to be.

You can also target users based off of their time zone. For example, send one message if they are based in EST and another if they are PST. To do this, save the current time in UTC, and compare an if/else statement with the user’s current time to ensure you’re sending the right message for the right timezone. You should set the campaign to send in the user’s local time zone, to ensure they are getting the campaign at the right time. See below for an example of how to write a message that will go out between 2PM and 3PM and will have a specific message for each time zone.

{% assign hour_in_utc = 'now' | date: '%H' | plus:0 %}
{% if hour_in_utc >= 19 && hour_in_utc < 20 %}
It is between 2:00:00pm and 2:59:59pm ET!
{% elsif hour_in_utc >= 22 && hour_in_utc < 23 %}
It is between 2:00:00pm and 2:59:59pm PT!
{% abort_message %}
{% endif %}

Deep-Linking to In-App Content

What is Deep-Linking?

Deep linking is a way of launching a native app and providing additional information telling it to do some specific action or show specific content.

There are three parts to this:

  • Identify which app to launch
  • Instruct the app which action to perform
  • Provide the action with any additional data it will need

Deep links are custom URIs that link to a specific part of the app and contain all of the above parts. The key is defining a custom scheme. “http:” is the scheme with which almost everyone is familiar but schemes can begin with any word. A scheme must start with a letter, but can then contain letters, numbers, plus-signs, minus-signs or dots. Practically speaking, there is no central registry to prevent conflicts, so it is a best practice to include your domain name in the scheme. For example, “twitter://” is the iOS URI to launch Twitter’s mobile app.

Everything after the colon within a deep link is free-form text. It is up to you to define its structure and interpretation, however, a common convention is to model it after “http:” urls, including a leading “//” and query parameters (e.g. “?foo=1&bar=2”). For the Twitter example, “twitter://user?screen_name=[id]” would be utilized to launch a specific profile in the app.

These deep links are a powerful tool when used in tandem with the Braze News Feed. Providing deep links as the URI within News Feed items allows you to utilize the News Feed as an individualized navigation tool to direct users to content inside in your app. They can also be utilized to direct users from push notifications and in-app messages to relevant app sections and content.

Keep in mind that enabling these deep links requires some additional setup within your app. Please reference our documentation on deep links for iOS and on how to deep link to the News Feed for Android to understand the requirements for implementation.

UTM Tags and Campaign Attribution

What is a UTM Tag?

UTM (Urchin Traffic Manager) tags allow you to include campaign attribution details directly within links. UTM tags are used by Google Analytics to collect campaign attribution data, and can be used to track the following properties:

  • utm_source: the identifier for the source of the traffic (e.g. my_app)
  • utm_medium: the campaign medium (e.g. newsfeed)
  • utm_campaign: the identifier for the campaign (e.g. spring_2016_campaign)
  • utm_term: identifier for a paid search term that brought the user to your app or website (e.g. pizza)
  • utm_content: an identifier for the specific link/content that the user clicked on (e.g. toplink or android_iam_button2)

UTM tags can be embedded into both regular HTTP (web) links and deep links and tracked using Google Analytics.

Using UTM Tags with Braze

If you want to use UTM tags with regular HTTP (web) links, for example to do campaign attribution for your e-mail campaigns, and your organization already uses Google Analytics, you can simply use Google’s URL builder to generate UTM links. These links can be readily embedded into Braze campaign copy just like any other link.

In order to use UTM tags in deep links to your app, your app must have the relevant Google Analytics SDK integrated and correctly configured to handle deep links. Check with your developers if you’re unsure about this.

Once the Analytics SDK is integrated and configured, UTM tags can be used with deep links in Braze campaigns. To set up UTM tags for your campaign, simply include the necessary UTM tags in the destination URL or deep links. The examples below show how to use UTM tags in push notifications, News Feed cards and in-app messages.

Attributing Push Opens with UTM Tags

To include UTM tags in your deep links for push notifications, simply set the on click behavior of the push message to be a deep link, write the deep link address and include the desired UTM tags in the following fashion:


UTM Tags in Push Message

Attributing News Feed Clicks with UTM Tags

News Feed items deep linking into your app can be configured to use UTM tags as well. Note that you can use utm_content to separate between deep links on different OSes.

UTM Tags in News Feed

Attributing In-App Message Clicks with UTM Tags

Similarly to push notifications and news feed cards, you can include UTM tags in the deep links included within your in-app messages.

UTM Tags in In-App Message

Emoji Messaging

If you are using Chrome as your browser, we recommend using the EmojiOne extension to conveniently insert emojis. If not, emojis can be sent to your users via push notifications or email in a few easy steps.

Mac Users

Accessing Emojis on Your Computer

First open the dictionary application and select ‘Emoji & Symbols’ from the ‘Edit’ tab at the top of your screen.

Emoji Step One

Next, browse through and select the emoji/emojis that you would like to use in your message.

Emoji Step Two

Inserting Emojis Into Your Messages

To insert emojis into your message channels, select your desired symbol then copy and paste it directly into the body text of your message.

Push Emoji

Windows Users

Accessing Emojis on Your Computer

First follow this link to access the unicode native standards for emojis.

Inserting Emojis Into Your Messages

To insert emojis into your message channels, highlight, click and drag the native standard of your desired symbol into the body text of your message as demonstrated in the image below. You can also highlight the emoji then copy/paste it into the message composer.


Many of the available emojis are currently unviewable in the Chrome browser. This issue will not affect the sending of emojis across Braze messaging channels, and the emojis will still be successfully delivered to your users. Try using another browswer such as Safari or Firefox to accurately preview the emojis in your messages.

Conversion Events

In order to track engagement metrics and the necessary details regarding how messaging drives your KPIs, Braze allows you to set Conversion Events for each of your campaigns and Canvases. A Conversion Event is a type of success metric that tracks whether a recipient of your messaging performs a high-value action within a set amount of time after receiving your engagement. With this, you can begin to attribute these valuable actions to the different points of engagement reaching the user. For example, if you’re creating a personalized holiday campaign for active users, a Conversion Event of “Starts Session” within 2 or 3 days may be appropriate, as it will then allow you to gather a sense of the rate at which your engagement helped nudge users to come back upon receiving your message.

Along with “Make a Purchase,” events like “Start a Session,” “Upgrade App,” or any of your Custom Events can be selected as Conversion Events. Below are further details on the feature, as well as steps needed to implement them.

Primary Conversion Event

The Primary Conversion Event is the first event added during campaign or Canvas creation, and it is the one that has the most bearing on your engagement and reporting. It is used to:

  • Compute the winning message variation in multivariate campaigns or Canvases.
  • Determine the window in which revenue is calculated for the campaign or Canvas.
  • Adjust message distributions for campaigns and Canvases using Intelligent Selection.

Step 1: Create a Campaign with Conversion Tracking

Navigate to the Braze Campaigns page in your company dashboard and click “Create Campaign,” then select the type of campaign you’d like to create.

After setting up your campaign’s messages and—for non-API campaigns—schedule, you’ll have the option to add up to four Conversion Events for tracking. We highly recommend using as many as you feel is necessary, as the addition of a second (or third) Conversion Event can significantly enrich your reporting. For example, if you had a campaign or Canvas targeting lapsing users, although a retention-centric Conversion Event of “Starts Session” within 3 days is valuable, perhaps you also want to add a secondary Conversion Event of performing another high-value Custom Event. This way, you can dive back into the dashboard and understand not only the extent to which your campaign or Canvas is ushering users back into your application, but also how involved and active these sessions are.

Step 2: Add Conversion Events

For each conversion event you wish to track, select the event and conversion deadline:

  1. Select the general type of event you’d like to use.

    Conversion Event Selection

    • Opens App: A user is counted as having converted when they open any one of the apps that you specify (defaults to all apps in the app group).
    • Makes Purchase: A user is counted as having converted when they purchase the product you specify (defaults to any product).
    • Performs Custom Event: A user is counted as having converted when they perform one of your existing custom events (no default, you must specify the event).
    • Upgrade App: A user is counted as having converted when they upgrade the app version on any one of the apps that you specify (defaults to all apps in the app group). Braze will perform a best-efforts numerical comparison to determine if the version change was in fact an upgrade. For example, a user would convert if they upgrade from version 1.2.3 to 1.3.0 of the application, while Braze will not register a conversion if a user downgrades from 1.2.3 to 1.2.2. However, if the app’s version names contain strings, such as “1.2.3-beta2”, then Braze will not be able to determine if a version change was in fact an upgrade. In that situation, Braze will count it as a conversion when the user’s most recent app version changes.
  2. Set a “conversion deadline.” You have the option of allowing up to a 30 day window during which a conversion will be counted if the user takes the specified action.

Once you’ve selected your conversion events, continue the campaign creation process and begin sending your campaign.

Step 3: View Results

Navigate to the “Details” page to view details for each conversion event associated with the campaign you just created. Regardless of your selected conversion events, you can also see the total revenue that can be attributed to this specific campaign — as well as specific variants — during the window of the Primary Conversion Event (please note, if no conversion events were selected during campaign creation, the time period defaults to 3 days). Additionally, for multivariate messages, you can see the number of conversions and conversion percentage for your control group and each variant.

View Results

Conversion Tracking Rules

Conversion Events allow you to attribute user action back to a point of engagement. That said, there are a few things to note regarding how Braze handles conversions when there are multiple in play. Please find these scenarios outlined below.

  • A user can only convert once on each conversion event for a campaign or Canvas. For instance, assume a campaign has only one conversion event which is “makes any purchase.” If a user who receives this campaign makes 2 separate purchases within the conversion deadline, only one conversion will be counted.
  • If a user performs one conversion event within the conversion deadlines of two separate campaigns or Canvases that they received, the conversion will register on both.
  • A user will count as converted if they performed the specific conversion event in the window even if they did not open/click the message


Braze allows you to control marketing pressure by implementing two different types of rate-limiting for your campaigns. The first focuses on providing the best experience for the end user, while the second takes into consideration the bandwidth of your servers.

User Centric Rate-Limiting

As you create more segments, there are going to be cases where the membership of those segments overlaps. If you’re sending out campaigns to those segments, you want to be sure that you are not messaging your users too often. If a user receives too many messages within a short time period, they will feel over-encumbered and either turn off push notifications or uninstall your app.

Relevant Segment Filters

Braze provides the following filters in order to help you limit the rate at which your users receive messages:

  • Last Engaged With Message
  • Last Received Any Campaign
  • Last Received Push Campaign
  • Last Received Email Campaign
  • Last Viewed News Feed

Implementing Filters

Consider the following example segment:


This is a standard re-engagement segment. If you have other more targeted segments receiving notifications recently, you may not want your users to be targeted by more generic campaigns directed at this segment. Appending the “Last Received Push Campaign” filter to this campaign, the user has ensured that if they’ve received another notification in the past 24 hours, they will slide out of this campaign for the next 24 hours. If they still meet the other criteria of the segment 24 hours later and haven’t received any more notifications they will slide back into the segment.

Appending this filter to all segments targeted by campaigns would cause your users to receive a maximum of one push every 24 hours. You could then prioritize your messaging by ensuring that your most important messages are delivered before less important messages.

Setting A Max User Cap

Additionally, in the ‘Target Users’ section of your campaign composition, you can limit the total number of users that will receive your message. This feature serves as a check that is independent of your campaign filters, allowing you to freely segment users without needing to worry about over-spamming.

Total Limit Example

Using the filters in this way, you’ll be able to limit the rate at which your users receive notifications on a per channel basis or globally across all message types.

Setting a Max Impression Cap

For in-app messages, you can control marketing pressure by setting a maximum number of impressions that will be displayed to your user base, after which Braze will not send down more messages to your users. However, it is important to note that this cap is not exact. New in-app message rules are sent down to an app on session start, meaning that it is possible for Braze to send an in-app message down to the user before the cap is hit, but by the time the user triggers the message, the cap has now been hit. In this situation, the device will still display the message.

For example, let’s say you have a game with an in-app message that triggers when a user beats a level, and you cap it at 100 impressions. There have been 99 impressions so far. Alice and Bob both open the game and Braze tells their devices that they are eligible to receive the message when they beat a level. Alice beats a level first and gets the message. Bob beats the level next, but since his device has not communicated with Braze’s servers since his session start, his device is unaware that the message has met its cap and he will also receive the message. However, once an impression cap has been hit, the next time any device requests the list of eligible in-app messages, that message will not be sent down and will be removed from that device.

Delivery Speed Rate-Limiting

If you anticipate large campaigns driving a spike in user activity and overloading your servers, you can specify a per minute rate limit for sending messages. While targeting users during campaign creation, you can click into Advanced Options and select a rate limit (in various increments from 10K to 500K messages per minute).

Per Minute Rate Limit Example

For instance, if you are trying to send out 75K messages with a 10K per minute rate limit, the delivery will be spread out over 8 minutes. Your campaign will deliver 10k for each of the first 7 minutes, and 5K over the last minute. Be wary of delaying time sensitive messages, however, with this form of rate-limiting. If the segment contains 30M users but we set the rate limit to 10K per minute, a large portion of the user base won’t receive the message until the following day.

It is important to note that when sending a multi-channel campaign with a speed rate limit, each channel is sent independently of the others. The effect is that users could receive the different channels at different times, and it is not predictable which channel they will get first. For example, if you send a campaign that contains an email and a push notification, you may have 10K users with valid push tokens but 50K users with valid email addresses. If you set the campaign to send 100 messages per minute (a slow rate limit for the campaign size), a user could receive the push notification in the first batch of sends and the email in the last batch of sends, almost 9 hours later.

Rate Limiting and Connected Content Retries

+When the Connected Content Retry feature is enabled, Braze will retry call failures while respecting the rate limit you set for each resend. Let’s think again about the 75K messages with a 10K per minute rate limit. In the first minute, the call fails or is slow and only sends 4K messages. Instead of attempting to make up for the delay and send the remaining 4K messages in the second minute or add it to the 10K it is already set to send, Braze will move those 6K failed messages to the “back of the queue” and add an additional minute, if necessary, to the total minutes it would take to send your message.

Minute No Failure 6K Failure in Minute 1
1 10K 4K
2 10K 10K
3 10K 10K
4 10K 10K
5 10K 10K
6 10K 10K
7 10K 10K
8 5K 10K
9 0 1K

Multi-Channel Campaigns

Keep in mind that the per minute rate limit is adjusted on a per-campaign basis. If multiple channels are utilized within a campaign, the rate limit will apply to each of those channels. If your campaign utilizes email and in-app banners with a rate limit of 10K per minute, we will send 20K total messages each minute (10K email, 10K push).

Multi-Platform Push Campaigns

For push campaigns delivering on multiple platforms, the rate limit selected will be equally distributed across platforms. A push campaign leveraging Android, iOS and Windows with a 10K rate limit per minute will equally distribute the 10K messages across the 3 platforms.

Frequency Capping

As your user base continues to grow and your messaging scales to include life cycle, triggered, transactional and conversion campaigns, it’s important to prevent your notifications from appearing spammy or disruptive. By granting greater control over your users’ experience, Frequency Capping enables you to create the campaigns you desire without overwhelming your audience.

Feature Overview

Frequency Capping can be set up for each app group by selecting Global Campaign Settings found underneath the Campaigns tab. From here, you can choose:

  • What message channel you’d like to cap - push, email, webhook or any of those three
  • How many times each user should receive that channel within a certain time frame, which can be measured in minutes, days, weeks (7 days) and months

Each line of frequency caps will be connected using an “AND,” and you’re able to add as many as you wish. In addition, you may include multiple caps for the same message types. For instance, you can cap users to no more than 1 push per day and no more than 3 pushes per week.

Frequency Capping

Delivery Rules

There may be some campaigns - transactional messages, in particular - that you wish to always reach the user, even if she has already reached her frequency cap. For example, a delivery app may wish to send an email or push when an item is delivered regardless of how many campaigns the user has received. If you want a particular campaign to override Frequency Capping rules, you can set this up when scheduling that campaign’s delivery by checking the box next to “Ignore frequency capping settings for this campaign”. When sending API campaigns, which are often transactional, you’ll have the ability to specify that a campaign should ignore Frequency Capping rules within the API request by setting “override_messaging_limits” to “true.”

By default new Campaigns/Canvases that do not obey Frequency Caps will also not count towards them. This is configurable for each Campaign/Canvas. Please note that this behavior changes the default behavior when you turn off Frequency Capping for a Campaign/Canvas; the changes are backwards compatible and do not impact messages that are currently live right now.

Frequency Capping Update

  • Different channels within a multi-channel campaign will individually count towards the frequency cap. For instance, if you create a multi-channel campaign with, say, both push and email, and have Frequency Capping set up for both of those channels, then the push will count toward 1 push campaign and the email message will count toward 1 email message campaign. The campaign will also count toward 1 “campaign of any type.” If users are capped to 1 push and 1 email campaign per day and someone receives this multi-channel campaign, then she will no longer be eligible for push or email campaigns for the rest of the day (unless a campaign ignores Frequency Capping rules).

  • Triggered in-app messages will count towards global frequency cap, however they cannot be frequency capped. For instance, an in-app message confirming a purchase will appear after every purchase regardless of frequency capping.

  • Keep in mind that Frequency Capping applies to the campaigns a user receives, and not to individual messages. That is, if you have a recurring campaign that users are re-eligible to receive, each recurring message of each channel will be counted as just one campaign. For instance, if a user receives a recurring push campaign that delivers every day, and she is capped to 2 push campaigns per week, the recurring push messages will collectively count towards 1 push campaign for frequency capping purposes, and for that week, this user will still be eligible to receive a different campaign that contains push.

Multivariate Testing

Introduction to Multivariate Testing

What is Multivariate Testing?

A multivariate test is an experiment that compares users’ responses to multiple versions of the same marketing campaign. These versions share similar marketing goals, but differ in wording and style. The objective is to identify the version of the campaign that best accomplishes your marketing goals. This section walks through how to use multivariate testing to test out differences in content. If you’d like to evaluate differences in message scheduling or timing (for instance, sending an abandoned cart message after 1 hour of inactivity versus 1 day of inactivity), please refer to our section on setting up a Canvas.

As an example of a multivariate test, suppose you have two options for a push notification:

  • This deal expires tomorrow!
  • This deal expires in 24 hours!

Using a multivariate test, you can see which wording results in a higher conversion rate. The next time you send a push notification about a deal, you’ll know which type of wording is more effective.

The Benefits of Multivariate Testing

Multivariate testing gives you an easy, clear way to learn about your audience. You no longer have to guess what users will respond to - every campaign becomes an opportunity to try different variants of a message and gauge audience response.

Specific scenarios in which multivariate testing could come in handy include:

  • The first time you’re trying out a messaging type. Worried about getting in-app messaging right the first time? Multivariate testing allows you to experiment and learn what resonates with your users.
  • The creation of onboarding campaigns and other campaigns that are constantly being sent out. Since most of your users will encounter this campaign, why not ensure that it’s as effective as possible?
  • Cases in which you have multiple ideas for messages to send. If you are unsure of which to choose, run a multivariate test and then make a data-driven decision.
  • Investigating whether your users respond to “tried and true” marketing techniques. Marketers often stick to conventional tactics to engage with users, but every product’s user base is different. Sometimes, repeating your call to action and using social proof won’t get you the results you desired. Multivariate testing lets you step outside the box and discover unconventional tactics that work for your specific audience.

Five Rules for Multivariate Testing

Multivariate testing can unveil powerful insights regarding your users. To ensure that your test results are truly reflective of your users’ behaviors, you need to:

  1. Run the test on a large number of users. Large samples ensure that your results reflect the preferences of your average user and are less likely to be swayed by outliers. Larger sample sizes also allow you to identify winning variants that have smaller margins of victory.

  2. Randomly sort users into different test groups. Braze’s multivariate testing feature allows you to create up to eight randomly selected test groups. Randomizing is designed to remove bias in the test set and increase the odds of the test groups being similar in composition. This ensures that differing response rates are due to differences in your messages rather than your samples.

  3. Know what elements you are trying to test. Multivariate testing allows you to test differences between several versions of a message. In some cases, a simple test may be most effective, since isolating changes allows you to identify which elements had the greatest impact on response. Other times, presenting more differences between variants will let you examine outliers and compare different sets of elements. Neither method is necessarily wrong, provided you are clear from the beginning what you are trying to test for.

  4. Decide how long your test will run for before beginning the test, and don’t end your test early. Marketers are often tempted to stop tests after they see results that they like, biasing their findings. Resist the temptation to peek and never end your test early!

  5. Include a control group if possible. Including a control group lets you know whether your messages have a greater impact on user conversion than sending no message at all. Learn more about control groups here.

Creating Multivariate Tests with Braze

How To Create a Multivariate Test

Step 1: Create your campaign

On the Campaigns section of Braze’s dashboard, click “Create Campaign” and select a channel for the campaign.


Step 2: Compose your variants

Create up to 8 variants of your message. For some ideas on how to get started differentiating your variants, see here.


Step 3: Schedule your campaign

Test scheduling works the same as scheduling any other Braze campaign. All of Braze’s standard campaign scheduling options are available.

Step 4: Choose a segment to run your campaign on

Select a segment to send the campaign to. For best practices around choosing a segment to test with, see here.


Optional Step: Limit the number of users to test with

Sometimes, you’ll want to limit the number of users you send a test to, so that later, once you know which of your variants performs best, you will have users who haven’t received the campaign and can be sent the winner. This typically most useful if your test isn’t scheduled to recur and you won’t be using Intelligent Selection.

Limit Users

Step 5: Distribute users among your variants

Decide what percentage of your target segment should receive each of your variants. Or have Intelligent Selection handle the distribution for you.


Step 6: Designate a Conversion Event

Setting a conversion event for a campaign allows you to see how many of the recipients of that campaign performed a particular action after receiving it. Unlike other campaigns, multivariate tests must define a conversion event. You can read more about our Conversion Events feature here.

Step 7: Review and launch

On the confirmation page, review the details of your multivariate campaign and launch the test!

Step 8: View results

Once your campaign has launched, you can check how each variant is performing by selecting clicking on your campaign from the Campaigns section of the dashboard.


You will see a summary of the campaign and statistics on how the different variants are performing. If one variant is outperforming the others with better than 95% confidence, Braze will mark that variant with a banner indicating that it is best performing.

Messaging type Projected winner is selected based on…
Push conversion rate (if unavailable, open rate)
Email conversion rate (if unavailable, click rate)
In-app message conversion rate (if unavailable, click rate)

Step 9: Select a winner and continue sending

Once you are satisfied that one of your variants is the best performing, you can edit the campaign and adjust the distribution of users so that 100% of users receive the best performing variant. All users in the segment who have not yet received the campaign (including users who enter the segment at a future date) will then get the best performing variant, provided your campaign is scheduled to send again in the future. If you configured your campaign to only send to a limited number of users initially, this is typically when you would also remove that restriction, so that the best variant can reach as many of your segment users as possible.

Keep in mind that Braze recommends that you wait to select a winner like this until you have 95% confidence in a particular variant. If no variant did better than the others with 95% confidence, it’s possible that multiple variants received similar response rates, or your sample size of users was not large enough to yield 95% confidence. While you can still select a winner, the chances that your selection will not reflect users’ true preferences will be greater than 5%. Follow-up tests may yield more informative results.


Tips For Different Channels

Depending on which channel you select, you’ll be able to test different components of your message. Try to compose variants with an idea of what you want to test and what you hope to prove. What levers do you have to pull and what are the desired effects? While there are millions of possibilities that you can investigate using a multivariate test, we have some suggestions to get you started:

Channel Aspects of Message You Can Change Results To Look For
Push Wording, punctuation, use of images and emojis, deep links, presentation of numbers (e.g. “triple” vs. “increase by 200%”), presentation of time (e.g. “ends at midnight” vs. “ends in 6 hours”) Open and conversion rate
Email Subject, display name, salutation Open and conversion rate
- Use of images, organization of text (e.g. bulleted vs. numbered lists) Click and conversion rate
- Reply-to field, sign-off Unsubscribe and conversion rate
In-app Notification Aspects listed for “push,” message format Click and conversion rate

In addition, the ideal length of your test may also vary depending on channel. Keep in mind the average amount of time most users may need to engage with each channel. For instance, if you’re testing a push, you may achieve significant results faster than when testing email, since users see pushes immediately, but it may be days before they see or open an email. If you’re testing in-app messages, keep in mind that users must open the app in order to see the campaign, so you should wait longer in order to collect results from both your most active app openers as well as your more typical users.

If you’re unsure how long your test should run for, the Intelligent Selection feature can be useful for finding a winning variant efficiently.

Choosing a Segment

Since different segments of your users may respond differently to messaging, the success of a particular message says something about both the message itself and its target segment. Therefore, try to design a test with your target segment in mind. For instance, while active users may have equal response rates to “This deal expires tomorrow!” and “This deal expires in 24 hours!”, users who haven’t opened the app for a week may be more responsive toward the latter wording since it creates a greater sense of urgency.

Additionally, when choosing which segment to run your test on, be sure to consider whether the size of that segment will be large enough for your test. In general, multivariate tests with more variants require a larger test group to achieve statistically significant results. This is because more variants will result in fewer users seeing each individual variant. As a crude guide, you will likely need around 15,000 users per variant (including the control) to achieve 95% confidence in your test results. However, the exact number of users you need could be higher or lower than that depending on your particular case. For more exact guidance on variant sample sizes, consider referring to Optimizely’s Sample Size Calculator.

Intelligent Selection

Intelligent Selection is a feature that analyzes the performance of a campaign or Canvas twice a day and automatically adjusts the percentage of users that receive each message variant. A variant that appears to be performing better than others will go to more users, while variants that are underperforming will be targeted at fewer users. Each adjustment is made using a statistical algorithm that makes sure we are adjusting for real performance differences and not just random chance.

By looking at performance data in real-time and shifting campaign traffic toward winning variants gradually, Intelligent Selection ensures that more users receive your best performing variant, without any sacrifice in statistical confidence. Intelligent Selection will also rule out underperforming variants and identify high performing variants faster than a traditional A/B test. With Intelligent Selection, you can test more frequently and with greater confidence that your users will see your best message.

Intelligent Selection is ideal for campaigns that are scheduled to send multiple times. As Intelligent Selection needs initial results to begin adjusting your campaign, a campaign that sends only once will not benefit.


Including a Control Group

When you create a multivariate test, you can reserve a percentage of your target audience for a randomized control group. Users in the control group will not receive the test, but Braze will monitor their conversion rate for the duration of the campaign. When viewing your results, you’ll be able to compare the conversion rates of your variants against a baseline conversion rate provided by your control group. This lets you compare not only the effects of your variants, but also compare the effects of your variants against the conversion rate that would result if you didn’t send a message at all.

The size of the control group for a campaign with Intelligent Selection will be based on the number of variants. If each variant is being sent to more than 20% of users, then the control group will be 20% and the variants will be split evenly across the remaining 80%. However, if you have multiple variants such that each variant is being sent to less than 20% of users, then the control group will have to become smaller. Once Intelligent Selection starts analyzing the performance of your test, the control group will grow or shrink based on the results.

Understanding Your Multivariate Test Results

Congratulations on getting to this stage! Receiving your multivariate test results is, however, not the last step of the testing process. Now you need to understand what your results mean and apply these insights to your engagement strategy.

Understanding Confidence

An important part of your results is the confidence of your test. The confidence shows the reliability of your test results - the greater the confidence, the more reliable your findings. For instance, your results may show that “A” had a 20% click rate and “B” had a 25% click rate. This seems to indicate that “B” is the more effective message. Having a confidence of 95% means that the difference between the two click rates is likely due to an actual difference in users’ responses, and that there is only a 5% likelihood that the difference is due to chance.

In general, a confidence of at least 95% is necessary to show that your results are reflective of users’ actual preferences, and not due to chance. In rigorous scientific tests, 95% confidence is the common benchmark used to determine statistical significance. If you continually fail to achieve 95% confidence, try increasing your sample size or decreasing the number of variants.

Braze will mark any variants that have 95% confidence with a banner indicating that they are projected as best performing.

Statistically Insignificant Results — Now What?

A test that doesn’t have a confidence of 95% can still hold important insights. Here are a few things you can learn from a test with statistically insignificant results:

  • It’s possible that all of your variants had roughly the same effect. Knowing this saves you the time you would’ve spent making these changes. Sometimes, you may find that conventional marketing tactics, such as repeating your call to action, don’t necessarily work for your audience.
  • While your results may have been due to chance, they can inform the hypothesis for your next test. If multiple variants appear to have roughly the same results, run some of them again alongside new variants to see if you can find a more effective alternative. If one variant does better, but not by a significant amount, you can perform another test in which this variant’s difference is more exaggerated.
  • Keep testing! A test with insignificant results should lead to certain questions. Was there truly no difference between your variants? Should you have structured your test differently? You can answer these questions by running follow-up tests.

While multivariate testing is useful for discovering which type of messaging generates the most response from your audience, it’s also important to understand which alterations in messaging have only a negligible effect. This allows you to either continue testing for another more effective alternative, or save the time that may have been spent deciding between two alternate messages.

Whether or not your multivariate test has a clear winner, it can be helpful to run follow-up test to confirm your results or apply your findings to a slightly different scenario.

One multivariate test can (and should!) inspire ideas for future multivariate tests, as well as guide you toward changes in your messaging strategy. Possible follow-up actions include:

  • Changing your messaging strategy based on test results. Your multivariate results may lead you to change the way you word or format your messaging.

  • Changing the way you understand your users. Each multivariate test will shed light on your users’ behaviors, how users respond to different messaging channels, and the differences (and similarities) among your segments.

  • Improving the way you structure future multivariate tests. Was your sample size too small? Were the differences between your variants too subtle? Each multivariate test provides an opportunity to learn how to improve future tests. If your confidence is low, your sample size is too small and should be enlarged for future tests. If you find no clear difference between how your variants performed, it’s possible that their differences were too subtle to have a discernible effect on users’ responses.

  • Running a follow-up test with a larger sample size. Larger samples will increase the chances of detecting small differences between variants.

  • Running a follow-up test using a different messaging channel. If you find that a particular strategy is very effective in one channel, you may want to test that strategy in other channels. If one type of message is effective in one channel but not effective in another, you may be able to conclude that certain channels are more conducive to certain types of messages. Or, perhaps there is a difference between users who are more likely to enable push notifications and those who are more likely to pay attention to in-app messages. Ultimately, running this sort of test will help you learn about how your audience interacts with your different communication channels.

  • Running a follow-up test on a different segment of users. To do this, create another test with the same messaging channel and variants, but choose a different segment of users. For instance, if one type of messaging was extremely effective for engaged users, it may be useful to investigate its effect on lapsed users. It’s possible that the lapsed users will respond similarly, or they may prefer another one of the other variants. This sort of test will help you learn more about your different segments and how they respond to different sorts of messages. Why make assumptions about your segments when you can base your strategy on data?

  • Running a follow-up test based on insights from a previous test. Use the intuitions you gather from past tests to guide your future ones. Does a previous test hint at one messaging technique being more effective? Are you unsure about what specific aspect of a variant made it better? Running follow-up tests based on these questions will help you generate insightful findings about your users.

Creating a Webhook

Feature Overview

Creating a webhook campaign or including a webhook in a multichannel campaign allows you to trigger non-app actions. More specifically, webhooks can be used to provide other systems and applications with real-time information. You can use webhooks to send information to systems such as Salesforce or Marketo. You can also use webhooks to send information to your backend systems. For example, you might want to credit your customers account with a promotion once they’ve performed a custom event a certain number of times.

Creating a Webhook

Step 1: Set Up a Webhook

Add a new webhook message to a Campaign or Canvas. You can then choose to build a webhook from scratch or use one of our existing templates.

Step 2: Enter the URL for Your Webhook


Enter the HTTP URL. This HTTP URL specifies your endpoint. The endpoint is the place where you’ll be sending the information that you’re capturing in the webhook. If you’d like to send information to a vendor, the vendor should provide this URL in their API documentation. If you’re sending information to your own systems, check with your development or engineering team to ensure that you’re using the correct URL. Braze only allows URLs that communicate over standard ports 80 (HTTP) and 443 (HTTPS).


Personalization is supported in our HTTP URLs. At times, certain endpoints may require you to identify a user or provide user-specific information as part of your URL. You’ll want to be sure to include a default value for each piece of user specific information that you use in your URL.


Internationalization is supported in the URL and the request body. To internationalize your message, click ‘add languages’ and fill out the flyout.

Step 3: Create the Request Body

Create the body of your webhook request. This is the information that will be sent to the URL that you specified. There are two ways to create the body of your web hook request:

JSON Key-Value Pairs

JSON key-value pairs allow you to easily write a request for an endpoint that expects a JSON format. Do note that you can only use this feature with an endpoint that expects a JSON request. For example, if your key is “message_body,” the corresponding value might be “Your order just arrived.” Once you’ve entered your key-value pair, the composer will configure your request in JSON syntax and a preview of your JSON request will automatically populate.


Raw Text

The raw text option gives you the flexibility to write a request for an endpoint that expects a body of any format. For example, you might use this feature to write a request for an endpoint that expects your request to be in XML format.



Personalization is supported in both the JSON key-value pairs option and the raw text option. You can include any user attribute, custom attribute or event property in your request. For example, you can include a customer’s first name and email in your request. Don’t forget to include a default value for each attribute.


Internationalization is supported in raw text.

Step 4: Request Headers and HTTP Method

Certain endpoints may require that you include headers in your request. In the settings section of the composer, you can add as many headers as you’d like. Common use cases for request headers include a content type specification (e.g XML or JSON) and authorization headers that contain your credentials with your vendor or system. Content type specifications have the key “Content-Type” and common values are “application/json” or “application/x-www-form-urlencoded”.

The HTTP Method that you should use will vary depending on the endpoint to which you are sending information. The majority of the time, you’ll be using POST.


Step 5: Test Send Your Message

Before making your campaign go live, you may wish to test send the webhook to make sure the request is formatted properly. To do so, navigate to the preview tab and send the test webhook. You can test the webhook for a random user, a specific user (by entering their email address of external user ID), or a customized user of with attributes of your choosing. If the request is successful a small message will appear at the top of your screen. If the webhook request is unsuccessful a modal will appear with the error response message. The screenshot below is an example of the response of a webhook with an invalid webhook URL.

Webhook Test Feature

Step 6: Continue Campaign Creation

Continuing creating your campaign the way that you normally would. As with all of our message types, you can preview what your request will look like for a particular user, random user or user with specific attributes in the preview section of the webhook composer.

Errors, retry logic and timeouts

Webhooks rely on Braze’s servers making requests to an external endpoint, and syntax and other errors may arise. The first step to avoiding webhook errors is to test your webhook campaign for syntax errors and making sure that personalized variables have a default value. However, webhooks may still fail due to issues like expired API keys, rate limits or unexpected server errors. If your webhook fails to send, an error message gets logged to the Developer Console, under “Message Activity Log.” This description contains the time the error occurred, the app name and the error message:

Webhook error

If the message body is not clear enough regarding the source of the error, you should check the documentation of the API endpoint you’re using. These typically provide an explanation of the error codes the endpoint uses as well as what they’re typically caused by.

Like other campaigns, Braze tracks the delivery of your webhook campaigns and conversions resulting from them. When the webhook request is sent, the receiving server will return a response code indicating what happened with the request. The below table summarizes the different responses the server may send, how they impact campaign analytics and whether, in the case of errors, Braze will try to redeliver the campaign:

Response code Marked as received? Retries?
20x (success) Yes N/A
30x (redirection) No No
408 (request timeout) No Yes
429 (rate limited) No Yes
Other 4xx (client error) No No
5xx (server error) No Yes

When retrying, Braze will make 5 attempts using exponential backoff for a period of approximately 30 minutes before aborting the individual webhook call.

Each webhook, or batch of webhooks, is allowed 120 seconds before it times out.

Twilio SMS & MMS

For this example, we’ll configure the Braze webhook channel to send SMS and MMS to your users, via Twilio’s message sending API. For your convenience, a Twilio webhook template is included on the dashboard.


The Webhook URL is provided by Twilio in your dashboard. This URL is unique to your Twilio account, since it contains your Twilio account ID (TWILIO_ACCOUNT_SID).

In our Twilio example, the webhook URL is You can find this URL in the Getting Started section of the Twilio console.


Request Body

The Twilio API expects the request body to be URL-encoded, so we have to start by changing the request type in the Braze webhook composer to Raw Text. The required parameters for the body of the request are To, From and Body.

The screenshot below is an example of what your request might look like if you are sending an SMS to each user’s phone number, with the body “Hello from Braze!”.

  • You’ll need to have valid phone numbers on each user profile in your target audience.
  • In order to meet Twilio’s request format, use the url_param_escape Liquid filter on your message contents. This filter encodes a string so all the characters are allowed in an HTML request; for example, the plus character (+) in the phone number +12125551212 is forbidden in URL-encoded data, and will be converted to %2B12125551212.

Webhook Body

Request Headers and Method

Twilio requires two request headers, the request Content-Type and an HTTP Basic Authentication header. Add them to your webhook by clicking the gear icon on the right side of the webhook composer, then clicking Add New Pair twice.

Header Name Header Value
Content-Type application/x-www-form-urlencoded
Authentication Basic {{ 'TWILIO_ACCOUNT_SID:TWILIO_AUTH_TOKEN' | base64_encode }}

Be sure to replace TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN with values from your Twilio dashboard. Lastly, Twilio’s API endpoint is expecting an HTTP POST request, so choose that option in the dropdown for HTTP Method.

Webhook Method

Preview Your Request

Use the webhook composer to preview the request for a random user, or for a user with particular credentials, to ensure that the request is rendering properly.

Webhook Preview

Lob Direct Mail Integration is an online service which one can interact with through their API to send direct mail like letters, postcards, and checks through the mail. You can access Lob’s services through Braze’s webhook feature and send mail to your users. To get started, sign up for an account on and locate your API key in the settings section under your name in the dashboard.

Lob API Key


The HTTP URL to request in the webhook is different for each action you can make to Lob. In this example we will be sending a postcard so the url is, however the list of all the HTTP URL endpoints can be found in the Lob documentation.

Lob Endpoints

Request Body

To specify an address in the webhook body requires nested objects, and as such it must be entered as “Raw Text” in JSON format. If you are unfamiliar with the JSON format, an easy way to generate a sample request body is to copy the example CURL requests given on the documentation and run it in your terminal (replacing their test API key with yours). Once you run the code in terminal, go to the dashboard and check the “Logs” tab found under the “Requests” title. If the API request worked, you will be able to click on the request and copy the request body into the dashboard. You can then replace the data in the file to fit your desires.

Lob Success Response

Request Headers and Method

Lob’s documentation states that you must include your API key in the header to authorize the request. To do so, simply navigate to the setting section and add a new pair. For an authentication header, set the key to “Authorization”. Lob expects your API key to be base64 encoded, so use the Base64 filter in the header value: Basic APIkey:. You will need to add a “:” to the end of your API key when encoding as Lob expects the password to be left blank. Because the body of the request is in JSON format, you will also need to add a “Content-Type” key with the value “application/json”. The request method for this webhook is POST as specified on Lob’s documentation.

Lob Preview

Preview Your Request

At this point your campaign should be ready to send. If you run into errors, check the Lob dashboard and the developer console error message logs found in the Braze dashboard. Using these two resources you should be able to troubleshoot and debug your request. For example, the error below is caused by an incorrectly formatted authentication header.

Error Log Message

Facebook Messenger

Facebook Messenger is one of the world’s most popular instant messaging platforms, used by nearly one billion monthly active users. Brands are creating engaging Chatbots on the platform, and our Webhook interface helps you message your users on Facebook Messenger using the Messenger Platform APIs while taking full advantage of Braze’s advanced segmentation, personalization and triggering features. For your convenience, a Facebook Messenger webhook template is included on the dashboard.

In order to send messages, you’ll need a Facebook Messenger Page and App. We’ll assume you already have the requisites set up. If you need to do this, please see Facebook’s Messenger Platform Product Overview for help getting started. Braze also offers a full tutorial for creating a Messenger bot with example code in a GitHub repository!

Before starting, please note that Facebook does not allow usage of the Messenger Platform to send marketing messages. The platform is intended for “non-promotional messages that facilitate a pre-existing transaction, provide other customer support actions, or deliver content requested by a person.” To read more, see Facebook’s Platform Guidelines and Examples of Acceptable Use Cases. In addition, to send messages to users who are not test users of your Facebook App, your App will need to pass Facebook’s App Review.

Messenger IDs

In order to send messages on Facebook Messenger, you need to collect your users’ page-specific IDs (PSIDs). PSIDs are not the same as the user’s Facebook ID, and you’ll need the user’s explicit permission for messages from your page. To use PSIDs to send messages, embed a Send to Messenger or Message Us button in your web page or app and send the user’s PSID to Braze as a string custom attribute. You will also gain access to the user’s PSID in the back end if the user messages your page.

Facebook also supports the use of phone numbers to send messages on Messenger. Note that you’ll need to request the pages_messaging_phone_number permission separately in your App Review to use this feature. Additionally, all phone numbers need to be verified with Facebook by the user in order to receive messages on Messenger.

Setting up the Messenger Webhook

Every HTTP POST request to the Messenger Platform Send API needs to be accompanied by a page access token. If you don’t yet have one, please see Facebook’s documentation on obtaining one. Below is an example of the webhook settings, make sure to replace <ACCESS_TOKEN> with your access token. Also change the Request Body from key-value pairs to raw text to support multi-level JSON.

FBM webhook

You also need to set the Content-Type header to application/json in the webhook settings within Braze. To do this, click on the gear icon in the webhook configuration and add a key-value pair like this:

FBM Webhook headers

Formatting the Message

All requests to the Send API are sent in JSON according to a pre-specified format. The below examples are not exhaustive of all formats Facebook supports. Please see the Send API reference and its subsections for JSON definitions of all available message types and templates.

You can also use personalization and Connected Content in your webhook campaigns.

Text Messages

In order to send a text message to a user, use the following template, replacing the text with whatever message you wish to send:

    "text":"Hi {{${first_name} | default: 'there'}}! This is an example Facebook Messenger message."

This message appears in Messenger as follows:

Example FBM text message

Media Messages

You can also use Facebook Messenger to send media such as images (including GIFs), videos, audio and files. You’ll need to host this media in a publicly accessible location where it can be accessed by URL, typically your web site. Just replace <YOUR_URL> in the template with the URL to your file and set type as image, audio, video or file depending on the content type you want to send:

Structured Messages and Templates

In addition to text and files, Facebook Messenger can be used to send structured messages containing buttons or content previews as well as templates like receipts. See the Send API reference for thorough descriptions of the JSON for all available templates as well as character limits and other limitations for copy.

The below webhook body will send a scrollable preview of a few articles in the Braze blog:

          "payload": {
              "elements": [
                      "title": "The Rise and Rise of Emoji Marketing",
                      "subtitle":"Brands sent 800 million messages with emojis in June",
                            "title":"Read More"
                      "title": "What Emojis Really Mean to a Mobile Marketer",
                      "subtitle":"An infoposter to remember World Emoji Day",
                            "title":"Read More"

This is the sample message in Messenger:

Example FBM structured message

Previewing and Testing Your Webhook

Before you send your message, test your webhook. Make sure your Messenger ID is saved in Braze (or find it and test as a Customized User), and use the preview to send the test message:

Sending a message to yourself

If you receive the message successfully, you can continue on to configure its delivery settings.

Targeting Facebook Messenger Users

If you are not sending messages using users’ phone numbers and plan on sending Messenger messages repeatedly, you should create a segment for all users for whom the Messenger ID exists as a custom attribute and turn on Analytics Tracking to track your Messenger subscription rates over time. If you choose not to create a specific segment for Messenger subscribers, make sure to include a filter for Messenger ID existing to avoid errors:

Segment filter for Messenger IDs

You may also use other segmentation to target your Messenger campaigns, and the rest of the campaign creation process is as with any other campaign.

Remerge Retargeting Network

For this example, we’ll configure the Braze webhook channel to connect Braze with retargeting actions. It is important to have an automatic way of enabling Braze and the retargeting system (i.e. Remerge) to have visibility of what the other system does and adapt from the other’s message. Ad retargeting is helpful if you have users who have push notifications disabled or users who haven’t opened your app recently.

For example: An unregistered user could receive a push campaign saying “Thanks for installing our app, sign up today!” Once the user has signed up after receiving the push campaign they would receive an adapted follow-up message in a retargeted ad such as “Thanks for signing up! Here is 10% off your first order.”

One of the best ways to accomplish this is to use Braze as well as a retargeting partner specialized in mobile, such as Remerge. You want the retargeting partner to receive automated user info from Braze using webhooks. You’ll be able to leverage Braze’s targeting and triggering abilities to send events to Remerge, which could then be used to define retargeting campaign definitions in

Request URL and Body

For this webhook, all data is passed on alongside the HTTP URL as query string parameters. There are three parameters that need to be defined:

  • You’ll need to set the event name. This is to define the name of the event that will appear in your dashboard
  • Remerge requires you to pass along your app’s unique application identifier for Android (i.e. “com.example”) and iOS (i.e. “012345678”)
  • Finally you need to define a key. This will be provided by Remerge

Note: Braze does not automatically collect the device IDFA/AAID so you must store these values yourself. Please be aware that you may require user consent to collect this data.

Below is an example of what your Webhook URL might look like:

{% assign event_name = "your_remerge_event_name" %}
{% assign android_app_id = "your_android_app_id" %}
{% assign iOS_app_id = "your_iOS_app_id" %}
{% assign remerge_key = "your_remerge_key" %}

{% capture json %}{"name":"{{event_name}}","active":true,"joined":{{"now" | date: "%s" }}}{% endcapture %}{% if {{most_recently_used_device.${idfa}}} == blank %}{{android_app_id}}{% else %}{{iOS_app_id}}{% endif %}&key={{remerge_key}}&ts={{"now" | date: "%s" }}&{% if {{most_recently_used_device.${idfa}}} == blank %}aaid={{custom_attribute.${aaid}}}{% else %}idfa={{most_recently_used_device.${idfa}}}{% endif %}&event={{event_name}}&non_app_event=true&data={{json | url_param_escape}}

{% if {{most_recently_used_device.${idfa}}} == blank and {{custom_attribute.${aaid}}} == blank %}
{% abort_message('No IDFA or AAID available') %}
{% endif %}

After defining the parameters above, insert this liquid code template into the Webhook URL field and edit as needed. You do not have to define a Request Body for this webhook. Here is the template in Braze:

Webhook Template Remerge

Note: Remerge used to offer multiple endpoints depending on where your data is stored, however, they have now updated their docs with one single endpoint:

The old endpoints are still valid and will stay valid, however, Remerge recommends that customers switch to this new endpoint for reliability purposes.

You can find more information on Remerge’s API endpoint here.

Request Headers and Method

This webhook does not require any Request Headers, but be sure to choose GET in the dropdown for the HTTP Method.

Request Method Remerge

Preview Your Request

To ensure the request is rendering properly for different users, use the Message Preview. A good approach is to preview the Webhook for both Android as well as iOS users. You can also send test requests for these users. If the request was successful the API responds with HTTP 204.

Connected Content

Braze’s Connected Content feature expands on marketing personalization to boost customer engagement and conversions. This feature allows you to insert any information accessible via API directly into messages you send to users. Connected Content allows for pulling content either directly from your web server or from publicly accessible APIs.

Making an API Call

Messages sent by Braze can retrieve content from a web server to be included in a message by using the {% connected_content %} tag. For example, the following message body will access the url and include a fun trivia fact in your message:

Hi there, here is fun some trivia for you!: {% connected_content %}

You can also include user profile attributes as variables in the URL string when making Connected Content requests. As an example, you may have a web service that returns content based on a user’s email address and ID. If you’re passing attributes containing special characters, such as @, make sure to use the Liquid filter url_param_escape to replace any characters not allowed in URLs with their URL-friendly escaped versions, as shown in the e-mail address attribute below.

Hi, here are some articles that you might find interesting:

{% connected_content{{${email_address} | url_param_escape}}&user_id={{${user_id}}} %}

If the URL is unavailable, Braze will render an empty string in its place. Because Braze delivers messages at a very fast rate, be sure that your server can handle thousands of concurrent connections so we do not overload your server when pulling down content. When using public APIs, ensure your usage will not violate any rate-limiting that the API provider may employ. Braze requires that server response time is less than 2 seconds for performance reasons; if the server takes longer than 2 seconds to respond, the content will not be inserted.

If the endpoint returns JSON, you can detect that by checking if the connected value is null, and then conditionally abort the message. Additionally, Connected Content messages are processed with lower priority in our systems as not to roadblock other messaging campaigns due to long response times from servers. As a result, you may notice that delivery on Connected Content messages are slightly slower than other messages you send normally. Braze only allows URLs that communicate over port 80 (HTTP) and 443 (HTTPS).

Note: Attribute values must be surrounded by ${} in order to operate properly within Braze’s version of Liquid Syntax.

Note: Connected Content calls do not follow redirects.

Note: Braze’s systems may make the same Connected Content API call more than once per recipient. That is because Braze may need to make a Connected Content API call to render a message payload, and message payloads can be rendered multiple times per recipient for the purposes of validation, retry logic, or other internal purposes. Your systems should be able to tolerate the same Connected Content call being made more than one time per recipient.

Using Basic Authentication

If the URL requires basic authentication, Braze can generate a basic authentication credential for you to use in your API call. In the Connected Content tab in Manage App Group, you can manage existing basic authentication credentials and add new ones.

Basic Authentication Credential Management

To add a new credential, click Add Credential. You can then name your credential and put in the username and password.

Basic Authentication Credential Creation

You can then use this basic authentication credential in your API calls by referencing the token’s name:

Hi there, here is fun some trivia for you!: {% connected_content :basic_auth credential_name %}

Note: If you delete a credential, keep in mind that any Connected Content calls trying to use it will be aborted.

Local Connected Content Variables

Braze makes a standard GET request to the endpoint specified within the connected_content tag. If the endpoint returns JSON, it is automatically parsed and stored in a variable called connected. If the endpoint returns text, it will be directly inserted into the message in place of the connected_content tag.

Note: If you want to save your response to a variable, it’s recommended to return JSON objects. And if you want the response of connected content to replace the tag with the text, make sure the response is not valid JSON (as defined by

You can also specify :save your_variable_name after the url in order to save the data as something else. For example, the following connected_content tag will store the response to a local variable called localweather (you can save multiple connected_content JSON variables):

{% connected_content :save localweather %}

Metaweather is a free weather API that uses a “Where-on-Earth ID” to return weather in an area. Use this code for testing / learning purposes only. For more information about this API, see here.

Note: The stored variable can only be accessed within the field which contains the connected_content request. For example, if you wanted to use the localweather variable in both the message and title field, you should make the connected_content request within both fields. If the request is identical, Braze will use the cached results, rather than making a second request to the destination server. However, Connected Content calls made via HTTP POST do not cache and will make a second request to the destination server.

JSON Parsing

Connected Content will interpret any JSON-formatted results into a local variable, when you specify :save. For example, a weather-related Connected Content endpoint returns the following JSON object, which you store into a local variable localweather by specifying :save localweather.

  "consolidated_weather": [
      "id": 5.8143475362693e+15,
      "weather_state_name": "Clear",
      "weather_state_abbr": "c",
      "wind_direction_compass": "WSW",
      "created": "2017-06-12T14:14:46.268110Z",
      "applicable_date": "2017-06-12",
      "min_temp": 22.511666666667,
      "max_temp": 31.963333333333,
      "the_temp": 27.803333333333,
      "wind_speed": 6.8884690250312,
      "wind_direction": 251.62921994166,
      "air_pressure": 1021.335,
      "humidity": 50,
      "visibility": 14.945530601288,
      "predictability": 68
  "title": "New York",
  "location_type": "City",
  "woeid": 2459115,
  "latt_long": "40.71455,-74.007118",
  "timezone": "US\/Eastern"

You can test whether or not it’s raining by referencing {{localweather.consolidated_weather[0].weather_state_name}}, which if used on the object above would return Clear. If you want to also personalize with the resulting location name, {{localweather.title}} returns New York.

The following image illustrates the type of syntax highlighting you should see in the dashboard if you’re setting things up correctly. It also demonstrates how you could leverage the connected_content request above!

Connected Content Syntax Example

If the API responded with {{localweather.consolidated_weather[0].weather_state_name}} returning Rain, the user would then receive this push.

Connected Content Push Example

By default, Connected Content does not set a Content-Type or Accept header on the HTTP GET request that it makes. By adding :content_type application/json to the tag, Braze will set both the Content-Type and Accept header to the type you specify.

{% connected_content :content_type application/json %}


By default, Connected Content makes an HTTP GET request to the specified URL. To make a POST request instead, specify :method post.

You can optionally provide a POST body by specifying :body followed by a query string of the format key1=value1&key2=value2&.... Content-Type defaults to application/x-www-form-urlencoded unless you specify :content_type application/json, in which case Braze will automatically JSON-encode the body before sending.

{% connected_content :method post :body key1=value1&key2=value2 %}

HTTP Status Codes

You can utilize the HTTP status from a Connected Content call by first saving it as a local variable and then using the __http_status_code__ key. For example:

{% connected_content :save result %}
{% if result.__http_status_code__ != 200 %}
  {% abort_message('Connected Content returned a non-200 status code') %}
{% endif %}

Note: Be aware that this key will only be automatically added to the Connected Content object if the endpoint returns a JSON object. If the endpoint returns an array or other type, then that key cannot be set automatically in the response.

Configurable Caching

Connected Content will cache the value it returns from non POST endpoints for a minimum of 5 minutes. If a cache time is not specified, the default cache time is also 5 minutes. However, this cache time can be configured to be longer. For example:

#  Will cache for 900 seconds (15 minutes)
{% connected_content :cache 900 %}

Aborting Messages

Using Liquid templating, you have the option to abort messages within conditionals. For example:

{% connected_content :save connected %}
   {% if connected.recommendations.size < 5 or == nil %}
     {% abort_message() %}
   {% endif %}

You can also specify an abort reason, which will be saved to the Message Activity Log in your Developer Console:

{% abort_message('Could not get enough recommendations') %}

Note: Braze does not count Aborted Messages towards the send count in your Dashboard or the Raw Event Stream.

Accuweather Example Use-Case

If you have an Accuweather account, you can enrich and personalize your marketing campaigns, as well as automate translations, through Connected Content. Here are all of the Accuweather APIs you can reference within your Braze campaigns:

  • Locations API: Get a location key for your desired location. Use the location key to retrieve weather data from the Forecast or Current Conditions API.
  • Forecast API: Get forecast information for a specific location.
  • Current Conditions API: Get Current Conditions data for a specific location.
  • Indices API: Get daily index values for a specific location. Index availability varies by location.
  • Weather Alarms API: Get Weather Alarms for a specific location. AccuWeather Weather Alarms are determined using the daily forecasts for a location. An alarm exists for a location if the forecast weather meets or exceeds specific thresholds.
  • Alerts API: Get severe weather alerts from official Government Meteorological Agencies and leading global weather alert providers.
  • Imagery API: Get radar and satellite images.
  • Tropical API: Get current position, past positions, and forecasts for tropical cyclones worldwide.
  • Translations API: Get a list of available languages. Get translations for specific groups of phrases.

In order to get started, you’ll need to have your app’s Accuweather API key on-hand to use within your request urls.


For example, let’s say that you wanted to run a marketing campaign that has 3 different types of messages based on the current conditions of a user’s zip code in the US.

Within the first connected_content tag you will make a GET request to the Locations API. Here’s an example of what Accuweather will return as the JSON object:

    "Version": 1,
    "Key": "41333_PC",
    "Type": "PostalCode",
    "Rank": 35,
    "LocalizedName": "Seattle",
    "EnglishName": "Seattle",
    "PrimaryPostalCode": "98102",
    "Region": {
      "ID": "NAM",
      "LocalizedName": "North America",
      "EnglishName": "North America"
    "Country": {
      "ID": "US",
      "LocalizedName": "United States",
      "EnglishName": "United States"
    "AdministrativeArea": {
      "ID": "WA",
      "LocalizedName": "Washington",
      "EnglishName": "Washington",
      "Level": 1,
      "LocalizedType": "State",
      "EnglishType": "State",
      "CountryID": "US"
    "TimeZone": {
      "Code": "PDT",
      "Name": "America/Los_Angeles",
      "GmtOffset": -7.0,
      "IsDaylightSaving": true,
      "NextOffsetChange": "2018-11-04T09:00:00Z"
    "GeoPosition": {
      "Latitude": 47.636,
      "Longitude": -122.327,
      "Elevation": {
        "Metric": {
          "Value": 26.0,
          "Unit": "m",
          "UnitType": 5
        "Imperial": {
          "Value": 85.0,
          "Unit": "ft",
          "UnitType": 0
    "IsAlias": false,
    "ParentCity": {
      "Key": "351409",
      "LocalizedName": "Seattle",
      "EnglishName": "Seattle"
    "SupplementalAdminAreas": [
        "Level": 2,
        "LocalizedName": "King",
        "EnglishName": "King"
    "DataSets": [

Keep the “Key” ID on hand as you’ll need this for the second GET request. You can store the above JSON object into local variable location_info by specifying :save location_info after the url. Here is the example of the connected_content tag:

{% connected_content{{${country}}}/search?q={{custom_attribute.${Zip Code}}}&apikey={your API key} :save location_info %}

Note: Alternatively, you could also leverage the user’s {{${city}}} if you do not have a zip code custom attribute.

For the second connected_content tag, you will make a GET request to the Current Conditions API. You’ll need to add the location key to the request url. Here is the example connected_content tag:

{% connected_content{{location_info[0].Key}}?apikey={your API key} :save local_weather %}

Here is the returning JSON object:

    "LocalObservationDateTime": "2018-04-10T09:35:00-07:00",
    "EpochTime": 1523378100,
    "WeatherText": "Rain",
    "WeatherIcon": 18,
    "IsDayTime": true,
    "Temperature": {
      "Metric": {
        "Value": 11.0,
        "Unit": "C",
        "UnitType": 17
      "Imperial": {
        "Value": 52.0,
        "Unit": "F",
        "UnitType": 18
    "MobileLink": "",
    "Link": ""

As you can see from the connect_content tag above, we stored the JSON object into local variable local_weather by adding :save local_weather after the url.

You can test what the output of the WeatherText should be by referencing {{local_weather[0].WeatherText}}.

Bringing our use-case together, here is what the syntax of the campaign would look like:

{% connected_content{{${country}}}/search?q={{custom_attribute.${Zip Code}}}&apikey={your API key} :save location_info %}
{% connected_content{{location_info[0].Key}}?apikey={your API key} :save local_weather %}
{% if {{local_weather[0].WeatherText}} == 'Cloudy' %}
No sunscreen needed :)
{% elsif {{local_weather[0].WeatherText}} == 'Rain' %}
It's raining! Grab an umbrella!
{% else %}
Enjoy the weather!
{% endif %}

If the API responded with {{local_weather[0].WeatherText}} returning Rain, the user would then receive the following push:

Connected Content Push Example

Transifex Example Use-Case

If you have a Transifex account, you can use Braze’s Connected Content feature to automate the translations in your marketing campaigns.

This integration will allow you to type in a source string instead of copying and pasting the translation for every language into the message composer.

In order to set up your Transifex integration, you’ll need to set up basic authentication for your account. In the Connected Content tab in Manage App Group, you can manage existing basic authentication credentials and add new ones.

Basic Authentication Credential Management

To add a new credential, click New Credential. You can then name your credential and put in the username and password.

Basic Authentication Credential Creation

You can then use this basic authentication credential for calls to Transifex.

The code for our Transifex integration was built using Transifex’s translation strings API.

The following CURL will allow you to see if your Transifex account has context values associated with translations:

curl -i -L --user username:password -X GET<project_name>/resource/<resource_name>/translation/en/strings

You’ll need to input the project and resource name into CURL. You can find these values in the URL of your Transifex account.


An example response with a blank context field is pictured below:


Transifex Integration Code Example

Here is example code which utilizes the Transifex Strings API and the user’s “language” attribute

{% assign key = "<Insert Key Here>" %}
{% assign context = "<Insert Context Here>" %}
{% assign source_string = key | append: ':' | append: context %}
{% assign project = "<Insert Project Name Here>" %}
{% assign resource = "<Insert Resource Name Here" %}
{% assign source_hash = source_string | md5 %}

{% if {{${language}}} == "en" or {{${language}}} == "it" or {{${language}}} == "de" or {{${language}}} == "another_language_you_support"  %}
{% connected_content{{project}}/resource/{{resource}}/translation/{{${language}}}/string/{{source_hash}}/ :basic_auth <Insert Basic Auth Credential Name Here> :save strings %}
{% endif %}

{% if {{strings}} != null and {{strings.translation}} != "" and {{${language}}} != null %}
{% else %}
  {% abort_message('null or blank') %}
{% endif %}

Note: Alternatively, you could also leverage the user’s {{${most_recent_locale}}} if you wanted to include a variation based upon a user’s specific version of a language such as zh_CN or pt_BR.

Note: Braze or third parties may make available certain third party products or services to our customers that interoperate with the Braze Services. Any purchase or use of such third party services, and any exchange of data between a customer and such third parties, is solely between that customer and the third party chosen by that customer. Braze does not warrant or support any such third party services or products. Additionally, any customer who chooses to purchase or use any such third party services or products should recognize that any customer data that they submit to such third party products or services may be accessed by Braze in connection with the interoperation of the Braze Services with such third party services. Braze is not responsible for any disclosure, modification or deletion of any customer data by such third party providers, and Braze cannot guarantee the continued availability of any such third party products or services. If such third party discontinues making such services or products available for use with the Braze Services, customers shall not be entitled to any refund, credit or other compensation from Braze.

Connected Content Retries

Because Connected Content relies on receiving data from APIs, there is the possibility that an API is intermittently unavailable while Braze makes the call. In this case, Braze supports retry logic to re-attempt the request using exponential backoff. To enable retries, add :retry in the Connected Content call, as shown below:

{% connected_content :retry %}
{% connected_content :save my_content :basic_auth auth_name :retry %}

If the API call fails and this is enabled, Braze will retry the call while respecting the rate limit you set for each resend. Braze will move any failed messages to the “back of the queue” and add additional minutes, if necessary, to the total minutes it would take to send your message.

Please note that if a retried attempt succeeds, the message is sent and no further retries are attempted for that message. If the Connected Content call errors out 5 times, the message is aborted similar to if an abort message tag was triggered.

Connected Content :retry is available in emails and push notifications.

Public APIs

There are a variety of publicly available APIs that can be used for Connected Content. As seen in the examples above, public APIs allow you to insert custom data in messages. We’ve compiled a list below of public APIs that could be used for Connected Content. However, there are many more APIs out there, providing a wide variety of potential Connected Content uses. Let us know if you have an API to share!

Note: Public APIs can be subject to usage restrictions and rate limiting. Be sure to read through API documentations and contact API providers about your intended use.

News and Information

API Description
OpenWeatherMap Provides current weather data, 5 and 16 day forecast, and historical data.
NYT Article Search Provides NYT article data which includes headline, topic, URL, date, abstract, etc.
The Guardian API Provides Guardian article data which includes headline, topic, URL, date, abstract, etc.
Alchemy Provides data from an index of 250-300 thousand news articles and blogs.

Events and Ticketing

API Description
SeatGeek Provides ticket information for concerts, sports, and theater events.
OnConnect Provides box-office movie information and showtimes in US and Canadian theaters.
Eventbrite Provides data on a variety of public events.
Eventful Provides data on a variety of public events
Ticketmaster Provides data on public events, venues, and prices

Food & Drink

API Description
BreweryDB Provides information on breweries, beers, and beer events.
Zomato Provides a variety of restaurant information, including ratings, locations, and cuisine.


API Description
Barchart OnDemand Provides a variety of stock, futures, and foreign exchange data.
CoinDesk Provides a variety of cryptocurrency data.
Yahoo Finance Provides a variety of stock data.


API Description
AirVisual Provides Air quality and weather data.
Nutritionix Worlds Provides verified nutrition data.
openFDA Provides FDA data on drugs, devices, and foods
USDA Nutrients Provides access to the National Nutrient Database.


API Description Provides a variety of music data including artist information, recommended artists, and more.
iTunes Provides data on a variety of items in the iTunes, App Store, and iBooks stores.
Bandsintown Provides local concert information and recommends live music events.
Songkick Provides live music information with artists, venues, locations, etc.
Discogs Provides information on artists, labels, and recordings.

Product Information

API Description
Semantics3 Provides product metadata in a variety of categories.
Factual Provides various product data including nutrition and ingredients data.
eBay Provides live eBay data including item data, popular searches, and more.


API Description
Numbers API Provides random numerical trivia facts.
Clearbit Provides company logo images.
London Unified and NYC MTA Provide realtime public transit data including line statuses, arrival times, etc.
Sunrise and Sunset Provides Sunset and sunrise times for a given latitude and longitude.

Utilizing Badge Count

The iOS badge count displays the number of unread notifications within your application, taking the form of a red circle in the upper-right hand corner of the app icon. In recent years, badging has come to be an effective means for re-engaging app users.

The badge count can be used to re-engage your users who did not notice a push, or who have disabled foreground push notifications. Similarly, it can be used to notify your users about unviewed messages such as News Feed changes or in-app updates.

Badge Count with Braze

You can specify the desired badge count when you compose a push notification through Braze’s dashboard. This can be set to a user attribute with Braze’s personalized messaging, allowing endlessly customizable logic. If you wish to send a silent push that updates the badge count without disturbing the user, add the “Content-Available” flag to your push and leave its message contents empty.

Removing the Badge Count

Set the badge count to 0 or “” to remove the badge count from the app’s icon. Braze will also automatically clear the badge when a push notification is received while the app is in the foreground.

Best Practices

In order to optimize the re-engagement power of badging, it is crucial that you configure your badge settings in a way that most simplifies the user’s experience.

Keep the Badge Count Low

Research shows that once the badge count increases past double digits, users generally lose interest in the updates and often stop using the app altogether.

Note: There can be exceptions to this rule depending on the nature of your app (e.g. email and group messaging apps).

Limit the Things a Badge Count Can Represent

When badging, you want to make the notifications as clear and direct as possible. By limiting the number of things that a badge notification can represent, you can provide your users with a sense of familiarity with your app’s features and updates.

News Feed and In-app Badging

One of the most powerful features of badging is that it allows you to engage with your users without the immediacy of a push notification through the news feed and in-app updates. To ensure that your users stay interested in the in-app badging notifications, you should try to focus such badge updates on personalized or urgent messages.

News Feed Categories

News Feed “Categories” make it possible to integrate multiple instances of the news feed into your application. It’s possible to integrate feeds within different windows that only display news feed cards of a certain “category.”

News Feed Categories Image

Marking a News Feed as being from a specific “category” is not visible to the end user. By default, the Braze News Feed will display cards of all categories, unless a feed is specifically configured in the app code to display specific categories. For more information on the app code configuration, please see our technical documentation on the matter.

Managing User Subscriptions

Subscription States

Braze has three subscription tiers for e-mail users:

State Definition
Opted-in User has explicitly confirmed he/she wants to receive e-mail. We recommend an explicit opt-in process to acquire consent from users to send e-mail.
Subscribed User has neither unsubscribed, nor explicitly opted-in to receive e-mails. A user automatically gets set as Subscribed when a valid e-mail address is added to their user profile.
Unsubscribed User has either explicitly unsubscribed from your e-mails or been automatically unsubscribed after marked one of your e-mails as spam.

Changing Subscriptions

Changing Email Subscriptions

In most cases, your users will manage their email subscription through subscription links that are included in the emails they receive.

Braze automatically inserts a footer with an unsubscribe link at the bottom of every email you send, in accordance with the CAN-SPAM Act of 2003. When users click on the unsubscribe url in this footer, they are unsubscribed and taken to a landing page that confirms the change to their subscription.

Braze provides the ability to set an app group wide custom email footer which you can template into every email using the {{${email_footer}}} attribute. In this way, you do not have to create a new footer for every email template or email campaign you use. Changes you make to your custom footer will be reflected in every email campaign that starts after the changes are saved. Remember that compliance with the CAN-SPAM Act of 2003 requires you to include a physical address for your company and an unsubscribe link in your emails. It is your responsibility to make sure that your custom footer meets those requirements.

To create or edit your custom footer, go to the Manage App Group page under App Settings, and select the Email Settings tab.

Email Settings

In the Custom Footer section, you can choose to turn on Custom Footers. Once turned on, you will see a window to edit your footer and send a test message.

Custom Footer

You will see the default footer which uses the {{${set_user_to_unsubscribed_url}}} attribute and Braze’s physical mailing address. To comply with CAN-SPAM regulations, your custom footer must include {{${set_user_to_unsubscribed_url}}}; you will not be able to save a custom footer without {{${set_user_to_unsubscribed_url}}}.

If using the default footer which uses the {{${set_user_to_unsubscribed_url}}} attribute, be sure to select “other” for the Protocol as indicated below.

Default Unsub URL Protocol

No Footer-Email Settings

Note: be very careful to use a template with the custom footer {{${email_footer}}} or {{${set_user_to_unsubscribed_url}}}when composing an email campaign. A warning will pop-up, however the ultimate decision of whether to send an email without an unsubscribe link lies with you.

No Footer-Campaign Composition

When creating a custom footer, Braze suggests you use attributes for personalization. Here are a few you may find useful:

Attribute Tag
User’s Email Address {{${email_address}}}
User’s Custom Unsubscribe URL {{${set_user_to_unsubscribed_url}}}
User’s Custom Opt-In URL {{${set_user_to_opted_in_url}}}
User’s Custom Subscribe URL {{${set_user_to_subscribed_url}}}

Of course, the full set of default and custom attributes are available to you. As a best practice, Braze recommends including both an unsubscribe link (i.e. {{${set_user_to_unsubscribed_url}}}) and an opt-in link (i.e. {{${set_user_to_opted_in_url}}}) in your custom footer. This way users will be able to both unsubscribe or opt-in and you can passively collect opt-in data for a portion of your users.

You can also choose to set a custom footer for plaintext emails, which follows the same rules as the custom footer for HTML emails. If you choose not to write a plaintext footer, Braze will automatically build one from the HTML footer. When your custom footers are to your liking, press Save at the bottom of the page.

Save Custom Footer

Custom Unsubscribe Landing Page

When a user clicks on an unsubscribe url in an email, they are taken to a default landing page that confirms the change to their subscription.

Optionally, you may provide HTML for your own custom landing page, which users will be directed to (instead of the default page) upon unsubscribing. This feature is available on the “App Settings - Email” page. We recommend including a resubscribe link (i.e. {{${set_user_to_subscribed_url}}} ) on this page so that users have the option to resubscribe in case they unsubscribed by accident.

Custom ReSubscribe

Changing Push Subscriptions

Braze’s SDKs provide methods for changing a user’s push message subscription. Please refer to Braze’s technical documentation for your mobile platform for information on configuring these methods:

Manually Changing User Subscriptions

You can manually change the subscription status for any user in his/her individual user profile. You can find individual user profiles by searching for a user’s ID or email address on the “User Search” page. Under the user profile’s “Engagement” tab, you’ll find a user’s current push and email subscription status. Clicking on the “Unsubscribed”, “Subscribed”, or “Opted In” buttons will allow you to change that user’s subscription status. If available, the user profile also displays a timestamp for when the user’s subscription was last changed.

User Profile Subscription UI

Subscriptions and Campaign Targeting

Campaigns with push or email messages are targeted at users who are subscribed or opted-in by default. You can change this targeting preference when editing a campaign by going to the “Target Users” step and clicking “Advanced Options.”

Braze supports three targeting states:

  • Users who are subscribed or opted-in (default).
  • Only users who are opted-in.
  • All users, including those who have unsubscribed.

Please note that it is your responsibility to comply with any applicable spam laws when using these targeting settings.

Campaign Targeting Subscription UI

Segmenting by User Subscriptions

The “Email Subscription Status” and “Push Subscription Status” filters allow you to segment your users by their subscription status.

This can be useful - for example, if you want to target users who have neither opted in nor out and encourage them to explicitly opt-in to email or push. In that case, you would create a segment with a filter for “Email/Push Subscription Status is Subscribed” and campaigns to this segment will go to users who are subscribed but not opted in.

Subscription Filter

Sending Test Messages

Before sending out a messaging campaign to your users, you may want to test it to make sure it looks right and operates in the intended manner. Creating and sending test messages to select devices or members of your team is very simple using the tools in the dashboard.

Sending a Test Mobile Push Notification or Email Message

After drafting your Push or Email, you have the ability to send the message to your own device to see what it looks like in real time. In the settings bar, click the “eye” icon, input your email address or userID, and click “Send Test.” This will send the message that you drafted to your device.

This is what the testing process will look like for a push message.

Test Push

And here is what the process will look like for an email message.

Test Email

Keep in mind that you will either need your users’ email address or Braze UserID to send test messages to your device.

Sending a Test Web Push Notification

After drafting your web push, you have the ability to send the message to your computer to see what it looks like in real time. In the settings bar, click the “eye” icon, and click “Send Test to Myself.”

Test Web Push

If you have already accepted push messages from the Braze Dashboard, you will see the push come through in the corner of your screen. Otherwise, please click “Allow” when prompted, and the message will then appear.

Sending a Test In-App Message

If you have push notifications set up within your app and on your test device, you have the ability to send test in-app messages to your app to see what it looks like in real time. In the settings bar, click the “eye” icon, input your email address or userID, and click “Send Test:”

Test In App

This will send a push message to your device like the following:

Test Push for In App

Directly clicking and opening the push message will send you to your app where you’ll be able to view your in-app message test.

Sending a Test News Feed Card

Sending a test newsfeed card requires you to set up a test segment and subsequently send a test campaign out.

Creating a Designated Test Segment

Once you set up a test segment, you can utilize it these messaging channels. The process is very simple and if configured properly will only need to be done once.

Navigate to the “Segments” page in the dashboard and create a new segment. In the dropdown menu under “Add Filter”, you’ll find our testing filters at the bottom of the list.

Testing Filters

Our testing filters allow you to select users with specific email addresses or external user IDs.

Testing Filter Options

These filters have three options:

  1. “Equals” - This will look for an exact match of the email or user ID that you provide. Use this if you only want to send the test campaigns to devices associated with a single email or user ID.
  2. “Does Not Equal” - Use this if you want to exclude a particular email or user ID from test campaigns.
  3. “Matches” - This will find users that have email addresses or user IDs that match part of the search term you provide. You could use this to find only the users that have an “” address, allowing you to send messages to everyone on your team.

These filters can also be used in conjunction with each other to narrow down your list of test users. For example, the test segment could include an email address filter that matches “” and another filter that does not equal “”. You can also select multiple specific emails by using the matches option and separating the email addresses with a “|” character (e.g. matches “|”).

After adding the testing filters to your test segment, you can verify that you’ve selected only the users you intended by clicking “Preview” at the top of the segment editor or by exporting that segment’s user data to CSV by clicking on the gear icon in the right hand corner of the editor and selecting “CSV Export All User Data” from the dropdown menu.

Verify Test Segment

Note: Exporting the segment’s User Data to CSV will give you the most accurate picture of who falls under that segment. The “Preview” tab is only a sample of the users in the segment - see more details about this in our FAQ - and therefore may appear to have not selected all intended members.

Once you’ve confirmed that you’re only targeting the users that you want to receive the test message, you can either select this segment in an existing campaign that you want to test or click the “Start Campaign” button in the segment menu.

Sending the Test Campaign

In order to send test newsfeed cards, you need to target your previously created test segment. Begin by creating a Multichannel campaign and following the usual steps. When you reach the ‘Target Users’ section, select your test segment as shown below.

Test Segment

Finish confirming your campaign and launch it to test your newsfeed cards.

Note: Be sure to check the box titled “Allow users to become re-eligible to receive campaign” under the Schedule portion of the campaign wizard if you intend to use a single campaign to send a test message to yourself more than once.

Sending a Test Campaign Personalized with User Attributes

If you are using personalization in your message, you’ll need to take some additional steps to properly preview your campaign and check that user data is properly populating the content.

When sending a test message, make sure to choose either the option to “Select Existing User” or preview as a “Custom User.”

Testing a personlized message

If selecting a user, you’ll be able to enter the user ID or email of a specific app user into a search field. Then you’ll be able to use the dashboard preview to see how that user’s message would appear, and send a test message to your device that reflects that that user would see.

Select a user

If previewing as a customized user, you’ll be able to enter in text for various fields available for personalization, such as first name and any custom attributes. Once again, you can enter your own email address to send a test to your device.

Custom user

Sending a Test Campaign Personalized with Custom Event Properties

Testing campaigns personalized with Custom Event Properties differs slightly from testing other types of campaigns outlined above. The most robust way to test campaigns personalized using Custom Event Properties is to trigger the campaign yourself. Begin by writing up the copy involving the event property:

Composing Test Message with Properties

Then use Action Based Delivery to deliver the campaign when the event occurs. Note that if you’re testing an iOS Push campaign, you must set the delay to 1 minute to allow yourself time to exit the app, since iOS doesn’t deliver push notifications for the currently open app. Other types of campaigns can be set to deliver immediately.

Test Message Delivery

As described above, target the users as you would for testing using either a testing filter or simply targeting your own e-mail address and finish creating the campaign.

Test Message Targeting

Go into your app and complete the custom event, and the campaign will trigger, and you should see the message customized with the event property:

Test Message Example

Alternatively, if you are saving custom user IDs, you can also test the campaign by sending a customized test message to yourself. After writing the copy for your campaign, click the eye icon on the upper right corner of the preview, then select “Customized User”. Add the custom event property on the bottom of the page, add your user ID or e-mail address to the top box and click “Send Test”. You should receive a message personalized with the property.

Testing Using Customized User

User Import

Braze’s User Import feature allows users to upload and update user profiles via CSV files. This feature supports updating default and custom user profile attributes.


Braze accepts user data in the standard CSV format from files up to 100MB in size. The particulars of how to construct your file are described below.

Column Headers

Braze expects that the first row in your CSV file will contain the headers for each column in the file. The number of columns in each row must match the number of headers.

Users imported to Braze via CSV must be identified – Braze does not support creating entirely anonymous users via User Import. You must specify either a ‘braze_id’ or an ‘external_id’, but not both, allowing Braze to match an existing user.

  • If you provide an external_id, we will update any existing user with the same external_id or create a new identified user with that external_id set if one is not found.

  • If you provide a braze_id, we will update any existing user with the same braze_id but will not create a new identified user with that braze_id if one is not found since we do not allow entirely anonymous users via User Import.

All headers will be interpreted as custom attributes unless they match these fields used with the user data REST API:

  • braze_id
  • external_id
  • first_name
  • last_name
  • email
  • dob
  • country
  • language
  • home_city
  • bio
  • gender
  • phone
  • email_subscribe
  • push_subscribe
  • image_url

Note: all of these fields are of type String except for dob (date of birth). Take care to use the exact spelling and proper case for pre-existing user data fields.


These data types are accepted in User Import:

  • Datetime (Must be stored in the ISO 8601 format)
  • Boolean (TRUE/FALSE)
  • Number (Integer or Float with no spaces or commas, floats must use ‘.’ as the decimal separator)
  • String (no commas)
  • Blank

Note that the following data types are not supported in User Import:

  • Arrays
  • Push Tokens
  • Custom Events

For uploading these kinds of values, please use our User Data API.


Any value which is not formatted to match the Datetime, Boolean, Integer, or Float specifications will be read as a String. Each comma in the input will be interpreted as a column separator, therefore any commas in values will cause errors in parsing the file. In addition, all leading and trailing whitespace will be trimmed from each value. Otherwise, values will be stored exactly as stored in the input CSV file. Blank values will not overwrite existing values on the user profile, and you do not need to include all existing user attributes in your CSV file.

For segmentation, it is important that each column contains a consistent data type. Values which do not match the attribute’s data type will not match the filters used to segment the attribute. In addition, for custom attributes whose data type is set as “Detect Automatically” on the dashboard, the most recently added value is used to set the data type of the attribute, so an error in your last row can interfere with proper segmentation.

During import, Braze determines the data type of each column by scanning a sample from the top rows of the file. Mixed data types in a column will not prevent you from importing your file, so we recommend exercising caution and ensuring the values in each column are consistent and match the data type you expect.


To import your CSV file, navigate to the User Import page under the Users section on the left hand toolbar. In the lower text box, “Recent Imports”, there will be a table which lists up to twenty of your most recent imports, their file names, number of lines in the file, number of lines successfully imported, total lines in each file, and the status of each import.

User Import

The upper box, “Import CSV”, will contain importing directions and a button to begin your import. Press the “Select CSV File” button and select your file of interest, then press “Start Upload.” Braze will upload your file and check the column headers as well as the data types of each column. Once the upload is complete, you will see a modal window with a table previewing the contents of your file. All the information in this table is based off of the values in top few rows of your CSV file. For column headers, default attributes will be written in normal text, while custom attributes will be italicized and have their type noted in parentheses. There will also be a short summary of your file at the top of the pop-up.

You can import more than one CSV at the same time. CSV imports will run concurrently, and as such the order of updates is not guaranteed to be serial. If you require CSV imports run in a serial fashion, you should wait until a CSV import has finished before uploading a second one.

Errorless Import

If Braze notices something malformed in your file during the upload, errors will be shown above the summary. A file can be imported with errors, but once started, an import cannot be cancelled or rolled-back. Review the preview, and if errors are found cancel the import and modify your file. It is important to examine the full file before upload as well. Braze does not scan every row of the input file at this stage; errors can exist which Braze does not catch while generating this preview. Malformed rows and rows lacking an external ID (A) will not be imported, all other errors can be imported (B) but may interfere with filtering when creating a segment. Note that errors are based solely off of data type and file structure - for example, a poorly formatted email address (C) would still be imported as it can still be parsed as a string.

Import Errors

When you are satisfied with the upload, start the import. The pop-up will close and the import will begin in the background. You can track its progress on the User Import page, which will refresh every 5 seconds, or at the press of the refresh button in the Recent Imports box. Under Lines Processed, you will see the progress of the import; the status will change to Complete when finished. You can continue to navigate around other parts of the dashboard during the import, you will receive modal notifications when the import begins and ends.

When the import process runs into an error, a yellow warning icon will be displayed next to the total number of lines in the file. You can mouse over the icon to see details into why certain lines failed. Once the import is Complete, all data will have been added to existing profiles or all new profiles will have been created.

Error Tooltip


User Import creates and updates user profiles, and can also be used to create segments. To create a segment, check the ‘Create a segment from this CSV’ box.

Create a Segment

You can set the name of the segment or accept the default, which is the name of your file. Files which were used to create a segment will have a link to view the segment once the import has completed.

View the Segment

The filter used to create the segment selects users who were created or updated in a selected import, and is available with all other filters in the edit segment page. Note that as of 4/10/2018, for each user, only the last 100 CSVs the user was imported/updated in are cached. So if you attempt to create a segment by filtering for members who were in an older import, the segment will not include users who have been in 100 or more imports since. Previous to 4/10/2018 Braze cached the last 10 CSVs that a user was imported/updated in.

Edit the Segment

Common Errors

  • No external_id: To connect data from User Import to user profiles, Braze requires an external_id in each row. Rows without a value in the external_id column will be excluded from the import. User profiles that lack an external_id cannot be created or updated via the User Import.
  • Malformed Row: There must be a header row in order to properly import data. Each row must have the same number of cells as the header row. Rows whose length that have more or fewer values than the header row will be excluded from the import. Commas in a value will be interpreted as a separator and can lead to this error being thrown. Additionally, all data must be UTF-8 encoded.
  • Multiple Data Types: Braze expects each value in a column to be of the same data type. Values which do not match their atttribute’s data type will cause errors in segmenting.
    • Incorrectly Formatted Dates: Dates not in the ISO 8601 format will not be read as datetimes on import.
    • String Quotation: Values encapsulated in single (‘’) or double (“”) quotation marks will be read as strings on import.

Exporting to Facebook Audiences

Braze provides Facebook marketing integration, allowing you to export segments as Facebook marketing audiences and target those users for ad campaigns. Here are instructions on setting up this feature.

In order to export custom audiences from the dashboard, your Facebook App must be configured to allow Braze to make requests to Facebook through the Facebook Marketing API on behalf of the members of your team. Common use cases for exporting custom audiences include:

  • Retargeting Campaigns
  • Seed audiences for lookalike targeting

Before You Begin…

In order to configure your Facebook App’s settings, ensure the following:

  • Your organization has connected your app or apps within the Facebook App Dashboard
  • Your organization’s administrator has granted you either Developer or Admin access through the Facebook App Dashboard
  • You have set up Facebook Login
  • You have admin access to the Facebook Ad Account you’d like to export audiences to
    • Note: You will need to have full admin access and will not be able to test this functionality as a Test User.

Configuring Facebook App Settings

Due to Facebook’s increased security policies, you will need to whitelist OAuth Redirect URIs from Braze in order to send custom audiences.

  • From the Facebook App Dashboard, select the Facebook App that you’d like to export audiences to
  • From the left-hand side of the Facebook App Dashboard, select “Facebook Login” and then “Settings”
  • Within “Settings” you should be able to see Client OAuth Settings.

FB Settings

Before you proceed to the Braze dashboard, you’ll need to have your Facebook App ID and App Secret on hand.

  • From the Facebook App Dashboard, select “Settings” then “Basic.”


Configuring Braze 3rd Party Integration

Once your Facebook app has been correctly configured, you’ll need to add your credentials to the appropriate App Group in Braze.

  • Within the Braze dashboard, head to the “3rd Party Integrations” section, and click on the Facebook tab. Make sure you’ve selected the correct App Group.
  • Enter your Facebook App ID and App Secret in the “Facebook Marketing App ID” and “Facebook Marketing App Secret” fields.

Braze FB

  • Note: The “Facebook App ID” field is optional. If users authenticate with Facebook in your app and you are providing Facebook data to the Braze SDK, you will have the option to export those users to Facebook using their Facebook User ID. If you’d like to do this, save the Facebook app ID that you use to authenticate your users in the “Facebook App ID” field.
  • Save your changes.

Exporting Your Users

The Facebook Audience Export link will be in the settings menu of each segment in an app group that has Facebook credentials.

  • While this link will be present for all members of your app group, only users with permissions in your Facebook App will be able to successfully export a segment.

Facebook Export 1

  • When you click on this link for the first time, a modal will appear to connect your Facebook credentials. During this process, you must accept Facebook’s Custom Audience Terms of Service.
  • Once you have connected your Facebook credentials, a modal will appear to let you select which data type you’d like to export.
    • There are 4 possible user data types we can use for the export: email, device IDFA, Facebook UID, and phone number. If you haven’t entered a Facebook App ID in your 3rd Party Integration settings, you won’t be able to select Facebook UID.
    • If you choose more than 1 data type, Braze will create a separate custom audience for each.
  • Click on export. As with CSV exports, you will receive an email when the segment has finished exporting.
  • You can view the custom audience on the Facebook Ads Manager.

Facebook Audience Export FAQ

Can I see the exact users that were successfully added to a Custom Audience?

  • Facebook does not allow this for user privacy reasons. Learn more here.

Why can’t I see the Custom Audience size?

Why can’t I select Google Advertising IDs or Android IDs data types?

  • Due to Google Play’s Terms of Service, we do not collect and store an Android identifier in a way that allows you to link the ID to PII. For more see here.

Lookalike Audiences

Once you’ve successfully exported a segment as a Facebook Audience, you can create additional groups using Facebook’s Lookalike Audiences. This feature looks at demographics, interests, and other attributes of your chosen audience and creates a new audience of people with similar attributes.


Braze tracks some author, editor, date, and status information about segments, campaigns, Canvases and News Feed cards, and gives you the ability to create tags to further organize and sort your engagement.

Campaign, Segment, and News Feed Card Tags

You can add tags when creating or editing a campaign, Canvas, segment, or News Feed card. Click the Add Tag button below the engagement name and add an existing tag or write in a new tag.

Campaign Creation

You can also add tags to multiple campaigns, Canvases, segments, or News Feed cards by checking the box next to each engagement and clicking the Tag As dropdown.

Tagging multiple

The tags set on a campaign, Canvas, segment, or News Feed card are visible on the detail page below the engagement name.

Campaign Details

They are also visible in the list of campaigns, Canvases, segments, and News Feed cards, as bubbles above the engagement name, along with status labels such as Archived and Draft.


To filter by a tag, select the tag name in the left-hand toolbar or search for the tag in the search pane using the tag selector.

Tag Search for Campaigns and Segments

Best Practices

Tags can be a useful organizational tool for keeping track of engagement tactics. You can link segments, campaigns, and News Feed cards to business objectives, funnel stages, and the like.

Below is an example of tags an eCommerce app might find useful:

Potential Tags

You can use the same tags across segments, campaigns, and News Feed cards. To efficiently rename or remove tags across your dashboard, use the Tags tab in the Manage App Group page.

tags view

Advanced Search Functionality

Our dashboard allows you to search through your segments, campaigns, and news feed cards using various advanced search filters. This feature is intended to help you locate your specific campaign or segment even faster and is useful to help parse through dozens of campaigns and segments that you may have.

To access this feature, you simply click on the dropdown arrow to the right of the search box on the campaign, segments, or news feed page:

Search Dropdown

Segment Search Filters

For segments, you will be able to search by the below filters:

  • Last Edited By
  • Search by Date of when a segment was created or last edited

Segments Search

Campaign Search Filters

For campaigns, you will be able to search by the below filters:

  • Last Edited By
  • Target Segment
  • Messaging Channel
  • Search by Date of when a campaign was created, last edited, or last sent

Campaigns Search

News Feed Search Filters

For news feed cards, you will be able to search by the below filters:

  • Last Edited By
  • Target Segment
  • Search by Date of when a card was created or last edited

News Feed Card Search


The Braze Canvas is a powerful solution for visualizing how campaigns connect to shape a customer’s journey. Canvas provides a single unified interface where marketers can set up multiple multiple messaging paths, compare and optimize those experiences, and view comprehensive analytics for the full user experience.

Canvas is only available to customers on annual contracts. If you are not on contract, please reach out to learn how to get Canvas.

Getting Started With Canvas

Marketing is a science—but one that needs an artist’s touch and specialized tools. Within Canvas, you can mix rigor and artistry to create meaningful, relevant, and personal experiences for each customer. Canvas is a single unified interface where marketers can set up campaigns with multiple messages and steps to form a cohesive journey and then compare and optimize those experiences using comprehensive analytics for the full user experience.

This guide will walk you through setting up a Canvas and give you important questions and thought starters as you build and consider your customer experiences. If you prefer a visual format for learning Canvas, check out this three part video series!

Canvas: The Basics

Find your strategy with the Five W’s of visualization

Fill in the form here to get started:

  • What am I trying to help the customer do or understand?_________ (Canvas Name)

  • When will a user start this experience? Pick one.
    • Enter users at a designated time:
      • Scheduled
      • Start a session
      • Perform a custom event
      • Enter a location
      • Interact with or leave another campaign or Canvas
    • Enter user when they perform actions: Action-Based
      • Make purchase
      • Start a session
      • Perform a custom event
      • Enter a location
      • Interact with or leave another campaign or Canvas

  • Who are we trying to reach? _________ (Segment Name) with [optional] additional filters:
    • Custom Data
    • User Activity
    • Retargeting
    • Marketing Activity
    • User Attributes
    • Install Attribution
    • Social Activity

  • Why am I creating this canvas?
    • Start Session: I want them coming back and engaging with the app.
    • Make Purchase: I want them to buy.
    • Perform Custom Event: I want them to perform a specific action that I’m tracking as a custom event.

  • Where will we reach them?
    • Push (Android, iOS, Windows, web)
    • Email
    • Webhook

  • How will we reach them? (Great place to test different messaging configurations)
    • Timing: Schedule or trigger messages using tools like Intelligent Delivery and delays after trigger events
    • Cadence & Channel: Use one channel and then another or sent messages on multiple channels simultaneously
    • Content: Build creative with strong appeals, value propositions, and CTAs
    • Targeting: Add additional segments and/or filters
    • Triggers: Use customer actions to trigger messages

Anatomy of Canvas


Canvas refers to the workspace and overall visualization.


A journey or customer journey is an individual user’s experience within the Canvas.


Variants are the variant flows marketers build that create personalized journeys.


Steps are individual decision points (like messages) within a variant.

Building The Customer Journey In Canvas

Name Your Canvas: the “what”

Never underestimate the power of the name. Braze is built for collaboration so this is a good time to get grounded in how you’ll communicate goals with your team. You can add Tags (including Teams Tags) and name both steps and variants within the Canvas.

Create Starting Conditions: the “when”

When will a customer run into this Canvas? Users can enter your Canvas in two ways: scheduled or action-based triggers.


You can use scheduled delivery when you want to send a Canvas out immediately to your target audience, have it regularly sent, or schedule it for a specific time in the future.


These Canvases respond to specific customer behaviors as they happen. These action-based triggers can include opening your app, making a purchase, interacting with another campaign, or triggering any custom event.

Select an Entry Audience for Entry: the “who”

Who are you trying to reach? Here you can use a pre-defined segment and add further filters. Filters include:

  • Custom Data: Custom data filters allow you to segment users based on events and attributes you define. With them, you can use features specific to your product.
  • User Activity: User activity filters allow you to segment customers based on their actions and purchases.
  • Retargeting: Retargeting filters allow you to segment customers who have been sent, received, or interacted with previous Campaigns or Canvases.
  • Marketing Activity: Marketing filters segment customers based on universal behaviors like last engagement or received campaigns.
  • User Attributes: User attribute filters segment customers by their constant attributes and characteristics.
  • Install Attribution: Install attribution filters segment customers by their first source, adgroup, campaign, or ad.
  • Social Activity: Social activity filters segment customers by their social media activity namely through connection to Facebook and Twitter.

Only the users who match these target audience criteria can enter the journey.

Identify Conversion Events: the “why” Why are you building this Canvas? It’s always important to have a defined goal in mind and Canvas helps you understand how you are performing against KPIs like session engagement, purchases, and custom events.

Selecting at least one conversion event will give you the ability to understand your campaign performance and also to help you optimize performance within the Canvas as if your Canvas has multiple variants and/or a control group Braze will use the conversion event to determine the best variation for achieving this goal.

Build the experience: the “how” and “where”

  1. Setting up variants: A variant is the trail each customer follows on their journey. Canvas supports up to four variants with a control group. While not required, you can name each variant, as well as control the distribution of the target audience following each variant.

  2. Building steps: A step is a marketing decision point—what is the experience you’re creating? Within a step you can set triggers or schedule delivery, refine targeting by adding filters or marking exception events, and add channels from email to push to webhooks.

  3. Determining when and how to use steps & variants: Each Canvas must have at least one variant and at least one step. The sky’s the limit from there—so how do you decide on the shape of your Canvas? That’s where your goals, data, and hypothesis come into play. The “how” and “where” brainstorm from above will help you map out the right shape and structure of your Canvas. There are a couple approaches you can use:

    a. Work backward: Some goals have smaller sub-goals. There is a great lecture on growth from Alex Schlutz that explains how finding your North Star and that Magic Moment where customers understand your value proposition are powerful stimulants. This can be applied on the Canvas level by finding the intermediate step to your goal. For instance, if you’re aiming for converting a free user into a subscription, you may need a page with your subscription services outlined. A visitor may need to see the options before they purchase. You may focus your messaging efforts on showing them this page before a checkout page. Working backward to understand the journey a customer must go through to get to your goal is key to guiding them through to conversion.

    b. Start with the status quo and add more: Have you ran a similar campaign in the past? Or is one currently running? Use that one message and add to it. Try a new filter or add a followup message. Look at your performance and keep optimizing by making incremental changes.

    c. Look to others: Imitation is the highest form of flattery. Don’t reinvent in the wheel. Don’t worry, we have you covered. At the end of this guide, you’ll find some outlines that can help you get started.

Moving the needle: Measuring and testing with Canvas Analytics

You need to know if what you’re building is moving the needle. Canvas makes it easy to understand how the experiences you’re building are impacting your goals. Once you build your Canvas and set it live, you can review performance on the Canvas Details page.

Canvas Overview


At the top of the Canvas Details page, there are topline Canvas stats. These include the number of messages sent within the Canvas, the total number of times customers have entered the Canvas, how many have converted and your total rate, the revenue generated by the Canvas, and the estimated total audience. This is a great way to level set in general how you’re doing against your goal.

Performance Visualization


As you move down the Canvas details page, you’ll see the performance for each step. These metrics include sends, unique recipients, conversion count, and revenue generated. You can click to breakdown further and see channel specific performance.

Performance Breakdown (by Variant)


At the bottom of the Canvas Details page, you can see a breakdown (by variant and Control Group if you have more than one) of performance. This is a clear table showing you by variant the number of steps, total sends, total entries, conversions, and total revenue. You can quickly infer effective variants and identify the right cadences, content, triggers, timing, and more!

Four Canvas Outlines


Onboarding - Restaurant Reservation Example

  • What: Onboarding users to their first reservation
  • When: Triggered at session start
  • Who: All New Customers
  • Why: Perform custom event “completed reservation”
  • Where: Push, Email
  • How: Channel, Content (test)


Upsell - Music Streaming Example

  • What: Upgrading active freeloaders to basic premium subscription
  • When: Triggered after custom event of “milestone - 3 hours music streamed”
  • Who: All Active, but free customers
  • Why: Perform custom event: visit pricing page
  • Where: Push, Email, Webhook
  • How: Content, Discount


Cart Abandonment - Clothing Retail Example

  • What: Reminding customers of incomplete purchases
  • When: Triggered after custom event of “abandoned cart”
  • Who: All registered customers
  • Why: Make purchase
  • Where: Push, Email
  • How: Channel, Trigger (test)


Holiday Travel - Airline

  • What: Educate customers on resources and prime them for good flight and airport experiences.
  • When: Scheduled daily until January 1st
  • Who: Customers booked for travel in two days with the app
  • Why: Session Start
  • Where: Push
  • How: Channel, Cadence (test)

Creating A Canvas

Step 1: Navigating to the Canvas page

Click on the “Canvas” link on the Dashboard’s side navigation located underneath the “Campaigns” link:

Canvas Dropdown

Step 2: Create a New Canvas

Click the “Create New Canvas” button:

Create New Canvas Button

Step 3: Name Your Canvas

Click on the name of your Canvas to edit it:

Name Your Canvas

Step 4: Set Your Starting Condition

Click on the “Starting Condition” link to control how users will be enrolled in a particular Canvas.

Canvas Starting Condition

There are two ways in which users can enter your Canvas. With scheduled delivery, users will enter on a time schedule, similarly to how you would schedule a Campaign. You can enroll users in a Canvas as soon as it is launched, or enter them into your journey at some point in the future, or on a recurring basis.

Canvas Scheduled Delivery

Additionally, you can choose to enter users into a Canvas when they perform certain triggers using Action-Based Delivery. Users will enter your Canvas and begin receiving messages when they take particular actions, such as opening your app, making a purchase, or triggering a custom event.

Canvas Action-Based Delivery

You can control other aspects of your Canvas’ behavior from the Entry Audience window, including rules for re-eligibility and frequency capping settings.

Note: Should the window of re-eligibility be less than the maximum duration of the Canvas, a user will be allowed to re-enter and receive more than one step’s messages. In the edge case where a user’s re-entry reaches the same step as its previous entry, Braze will deduplicate that step’s messages. In the event where a user re-enters the Canvas, reaches the same step as their previous entry, and is eligible for an in-app message for each entry, the user will get the message twice (depending on in-app message priority) as long as they re-open a session 2 times.

Step 5: Select Your Send Settings

Click “Send Settings” to turn on rate-limiting and/or Frequency Capping.

Send Settings Click

By turning on rate-limiting or Frequency Capping below you can ease the marketing pressure placed on your users and ensure you aren’t over messaging them. To learn more about the benefits of rate-limiting and Frequency Capping click here.

Send Settings

Step 6: Set Your Target Audience

Click on the “Target Audience” link to control the eligible audience for your Canvas:

Canvas Target Audience

You can set the target audience for your Canvas from this screen. Only the users who match these criteria can enter the journey. For example, you might want to limit a particular journey to users who first used your app less than 3 weeks ago. You can also control settings such as whether messages should be sent to users who are subscribed or opted-in to your notifications.

Canvas Audience Entry

Step 7: Choose a Conversion Event

Click on the “Conversion Event” link to choose a conversion event goal for your Canvas:

Canvas Conversion Event

We will use the Conversion Event that you set from this screen to measure the efficiency of your Canvas. If your Canvas has multiple variants or a Control Group, Braze will use this Conversion Event to determine the best variation for achieving this Conversion goal. Using the same logic, you can create multiple Conversion Events:

Canvas Conversion Start

Step 8: Add a Variant

Click the “Add Variant” button and select the option to add a new variant to your Canvas. variants represent a journey that your users will take:

Canvas Add Variant

You can add additional variants by pressing the + button. When you add new variants, you’ll be able to adjust how your users will be distributed between them so that you can cross-compare and analyze the efficacy of different engagement strategies:

Canvas Multiple Variants

Step 9: Editing a Step

Click anywhere on a Step, and Braze will open the Step editing interface. Steps can be configured to send messages after either a fixed delay, or when a user performs a particular action. For example, you can use Canvas to configure a Day 1, Day 3, Day 7 onboarding Campaign with time delays between messages:

Canvas One Day

Or you can set a group of messages to be sent after your users take a particular action, with a configurable window, delay, and exception events:

Canvas Exception Events

You can also apply Filters to each Step of a Canvas. Use this to add additional control flow logic, such as dropping users out of a journey when they’re not likely to need additional engagement encouragement:

Canvas Additional Engagement

Edit the Messages in a Step to control messages that a particular Step will send. Canvas can send Email, Mobile & Web Push messages, and Webhooks to integrate with other systems.

Canvas Message Edit

Press the “Done” button once you’ve finished configuring your Step.

Step 10: Add More Steps

Add more Steps by pressing the blue plus icon:

Canvas More Step

Step 11: Multivariate Testing Using Canvas

You can add a Control Group to your Canvas by clicking on the Plus icon to add a new variant. Braze will track the Conversions for users who are placed into the Control Group, although they will not receive any messages. In order to preserve an accurate test, we will track the number of Conversions for your variants and the Control Group for exactly the same amount of time, as shown on the Conversion Event selection screen. Adjust the distribution between your messages by double clicking the variant Name headers.

Canvas Multivariate

Intelligent Selection for Canvas

Intelligent Selection capabilities are now available within Multivariate Canvases. Similar to the Intelligent Selection feature for multivariate Campaigns, Intelligent Selection for Canvas analyzes the performance of each Canvas variant and adjusts the percentage of users being funneled through each based off their performance metrics in such a way that the total expected number of conversions is maximized. Keep in mind that multivariate Canvases allow you to test more than copy, but timing and channels as well. Through Intelligent Selection you can test Canvases more efficiently and have confidence that your users will be sent on the best possible Canvas journey.

Intelligent Selection

Intelligent Selection for Canvas optimizes your Canvas’s results by making gradual real-time adjustments to the distribution of users sorted into each variant. When the statistical algorithm determines a decisive winner among your variants it will rule out the underperforming variants and slot all future eligible recipients of the Canvas into the winning variants. For this reason, Intelligent Selection works best on Canvases that have new users entering frequently.

Step 12: Saving & Launching Your Canvas

Once you’re done, press the “Launch Canvas” button at the bottom right to save and launch your Canvas. You can also save your Canvas as a Draft if you need to come back to it.

Once you’ve launched your Canvas, you’ll be able to view analytics for your journey as they come in:

Canvas Analytics

Changing Your Canvas After Launch

Initial Conditions

Editable Not-Editable
Initial Condition Conversion Events
Target Audience  
Pause / Resume Initial Condition  
Workflow Name  

Canvas Graph

Editable Not-Editable
Pause / Resume Execution of All Workflow Steps Deleting Steps
Insert Workflow Steps Deleting Variants
Add New Connections Deleting Connections
Add New Variants  
Variant Distribution  

Individual Step

Editable Not-Editable
Name Schedule Type (change from delay to trigger)
Message Content  
Step Message Platforms (add/delete)  
Exception Events  
Delays / Windows  

There are a number of things to know if you plan to edit or add more steps to any other step in Canvas after launching:

  • Users who have not yet entered the Canvas will be eligible for newly created steps
  • Users who have already passed newly created steps will be eligible next time they re-enter if you have allowed users to re-enter the Canvas in Canvas Entry Settings
  • Users who are currently in a Canvas, but have not reached the points where new steps are added will be eligible to receive those new steps.


Create a Branch

You can harness the power of Braze’s action based delivery and powerful realtime segmentation to deliver personalized experiences for your users.

To create a branch, click on the blue circle at the bottom of a Step. Then click on one of the shadowed icons to create a new step.

Canvas Create Branch 1

Create another step, branching from the first:

Canvas Create Branch 2

You can setup filters to determine how users should flow to subsequent steps.

Canvas Create Branch 3

Or you can have users flow between branches based upon actions that they take.

Canvas Create Branch 4


Overlapping Filters

When setting up your Canvas, you should ensure that the Filters that you use to split users down different branches do not overlap. If a user can match multiple steps, Braze will pick a branch to send them down. For example:

Canvas Create Branch 5

If a user first made a purchase 7 days ago, they will be randomly slotted into one of the branches above.

In-app Messages In Canvas

In-app Messages in canvas are now in Beta. If you’re interested in participating in the beta program, please contact your customer success manager or Braze’s support team.

Adding an in-app message to Canvas

In-app messages can be included in any Canvas step. Please note that in app messages from canvases can only be displayed at session start. In-app message steps triggered off of custom events will not display in real time when the user completes the event. After completing the trigger event, your users will be eligible to receive the associated in-app message on their next session start.

Canvas Step Advancement

In some canvases, a customer will be eligible to receive a particular in-app message and the in-app message will never display for them.

This scenario could occur if a customer does not open the app during the in-app message’s availability window or if higher priority in-app messages display when the user opens their app. Note that eligibility means that a customer could get a particular message if they open their app - it does not mean that the in-app message actually displays for that customer.

Braze considers an in-app message as “sent” as soon as the user becomes eligible for the in-app message. As such, a user advances to subsequent canvas steps as soon as they are eligible to receive an in app message (or actually receive an email, push or webhook) from previous step.

More specifically, if a canvas step includes an in-app message, users will advance to the next step if they:

  • Meet the segmentation criteria for the current step as well as the subsequent step
  • Do not perform exception events for the current step before in-app message eligibility begins

To summarize, once a user becomes eligible for an in-app message in a canvas step, advancement to the next step is guaranteed.

In-app Message Availability Window

The availability window controls the duration of in app message eligibility. The maximum length of the availability window is 14 days.


In-app Message Eligibility Options

You can choose whether you’d like the in-app message to be displayed in the event that the customer has received messages from subsequent steps. By default, customers will not receive in-app messages from previous steps once they’ve received a message from a subsequent step.


Setting Message Priority

It is possible that a customer will trigger two in-app messages within your Canvas at the same time. When this occurs, Braze will follow the priority order below to determine which in-app message is displayed. Drag different Canvas steps to re-order their priority. By default, steps earlier in a Canvas variant will display before later steps.


Navigate to the “send settings” of the canvas section to prioritize in-app messages from a canvas against in-app messages from other canvases and campaigns.

By default, canvas step priority is set to medium with the most recently created steps having the highest relative priority. Canvas/campaign level priorities also default to medium with the highest relative priority defaulting to the most recently created items.


Key-Value Pairs

Braze enables you to send extra data payloads to user devices via key-value pairs. This feature is available across push, in-app, and News Feed messaging channels. Extra data payloads can help you update internal metrics and app content as well as customize push notification properties, such as alert prioritization, localization, and sounds.

Push Notifications


Apple Push Notifications service (APNs) supports setting alert preferences and sending custom data using key-value pairs. APNs makes use of the Apple-reserved aps library, which includes predetermined keys and values that govern alert properties.

APS Library
Key Value Type Value Description
alert string or dictionary object For string inputs, displays an alert with the string as the message with Close and View buttons; for non-string inputs, displays an alert or banner depending on the input’s child properties
badge number Governs the number that is displayed as the badge on the app icon
sound string The name of the sound file to play as an alert; must be in the app’s bundle or Library/Sounds folder
content-available number Input values of 1 signal to the app the availabilty of new information upon launch or session resumption
Alert Properties Library
Key Value Type Value Description
title string A short string that Apple Watch displays briefly as part of a notification
body string The push notification’s content
title-loc-key string or null A key that sets the title string for the current localization from the Localizable.strings file
title-loc-args array of strings or null String values that can appear in place of the title localization format specifiers in title-loc-key
action-loc-key array of string or null If present, the specified string sets the localization for the Close and View buttons
loc-key string or null A key that sets the notification message for the current localization from the Localizable.strings file
loc-args array of strings String values that can appear in place of the localization format specifiers in loc-key
launch-image strings The name of an image file in the app bundle you wish to be used as the launch image when users tap the action button or move the action slide

Braze’s message composer automatically handles the creation of the following keys: alert and its properties, content-available, sound, and category. These values can be input directly in the Dashboard as shown below.

iOS Automatic Keys

When Braze sends a push notification to APNs, the payload will be formatted as a JSON.

Simple Payload

    "aps" : { "alert" : "Message received from Spencer" },

Complex Payload

    "aps" : {
        "alert" : {
            "body" : "Hi, welcome to our app!",
            "loc-key" : "France",
            "loc-args" : ["Bonjour", "bienvenue"],
            "action-loc-key" : "Button_Type_1",
            "launch-image" : "Paris"
        "content-available" : 1
Custom Key-Value Pairs

In addition to the aps library payload values, you may send custom key-value pairs to a user’s device. In the message composer, click the gear icon and specify your key-value pairs below. The values in these pairs are restricted to primitive types: dictionary (object), array, string, number, and Boolean.


Use-cases for custom key-value pairs include but are not limited to internal metrics keeping and setting the context for the user interface. Braze allows you to send additional key-value pairs along with a push notification to be used however you so please via your application within the extras key. If you prefer to use another key, ensure that your app can handle this custom key. Note you should avoid handling a top-level key or dictionary called ab in your application.

Apple advises clients to avoid including customer information or any sensitive data as custom payload data. Furthermore, Apple recommends that any action associated with an alert message should not delete data on a device. Note that if you are using the HTTP/2 provider API, any individual payload you send to APNs cannot exceed a size of 4096 bytes. The legacy binary interface, which will soon be depreciated, only supports a payload size of 2048 bytes.


Google Cloud Messaging (GCM) allows you to send send additional data payloads in push notifications using key-value pairs. GCM specifies two types of payloads: notification and data. The notification payload has a 2KB limit and predetermined set of keys that govern message content. The data payload enables developers to send as much as 4KB of custom key-value pairs.

Notification Payload Key-Values
Key Value Type Value Description
body string The content of the push notification
title string The title of the push notification
icon string The file name of the desired image to display

Braze’s message composer automatically handles the creation of the notifcation payload.

Data Payload

Custom key-value pairs can be input by clicking the gear icon and specifying your key-value pairs below.


Use-cases for custom key-value pairs include but are not limited to internal metrics keeping and setting the context for the user interface; they may be used for whatever purpose you choose. Note that your app’s backend must be able to process custom key-value pairs for the data payload to function properly. For more information on accessing key-value pairs sent with Android push notifications, refer to the Braze Documention.

Braze automatically formats both payloads as a JSON before sending them to GCM.

Notification and Data Payloads

    "notification" : {
        "body" : "Message received from Spencer",
        "title" : "Hi Will!",
        "icon" : "Smiley"
    "data" : {
        "volume" : "6.7",
        "contents" : ""
GCM Messaging Options

Android push notifications can be further customized with GCM message options. These include notification priority, sound, delay, lifespan, and collapsibility. These values can be input directly in the Dashboard as shown below. Refer to the Braze Documentation for further instructions on how to set these options in the Braze message composer.

Android Automatic Keys

Silent Push Notifications

A silent push notification is a push notification containing no alert message or sound, used to update your app’s interface or content in the background. These notifications make use of key-value pairs to trigger these background app actions. Silent push notifications also power Braze’s uninstall tracking.

Marketers should test that silent push notifications trigger expected behavior before sending them to their app’s users. Once you compose your iOS or Android silent push notification, ensure that you only target a test user by filtering on external user ID or email address.

Upon campaign launch, you should check that you have not received any visible push notification on your test device. For instructions on how to check if your silent push notification has updated your app as intended, contact your dedicated success manager or

Please note that the iOS operating system may gate notifications for some features (Uninstall Tracking, Geofences, and Push Stories). Please note that if you are experiencing difficulties with these features, the iOS’s silent notifications gate might be the cause.


Key-value pairs can also be added to web push notifications. Select the gear icon in the Braze message composer to do so.


In-App Messages

To add a key-value pair to an in-app message, select the gear icon in the Braze message composer.



For Braze customers that use SendGrid, key-value pairs will be sent as unique arguments. SendGrid allows you to attach an unlimtied number of key-value pairs up to 10,000 bytes of data. These key-value pairs can be seen in posts from the SendGrid Event Webhook. Note that bounced emails will not deliver key-value pairs to SendGrid.


News Feed

Key-value pairs can be added to a News Feed Card in the Braze message composer below the categories drop down-menu.


In-App Message Color Templates

You can save in-app message and in-browser message templates on the dashboard to swiftly build new campaigns and messages using your style.

Adding a Color Profile

Color Profiles

You can customize the color scheme of your message template by either entering HEX color code or by clicking the colored box and selecting a color with the color picker. Click the “Save Color Profile” button on the bottom right when you’re finished.

Template options

Template Options

From the template options page, you can add a new color profile and edit or delete existing color profiles. You can also set a default color file by selecting “Set as Default” from the dropdown menu.

Notification Channels

Notification Channels are a way to organize push notifications that were added with Android O. Starting with O, all push notifications must have a Notification Channel that indicates the type of message (e.g. “chat notifications,” or “follow notifications”). End users can then control aspects of their notification (e.g. snoozing, noise/vibration settings, or opting-out etc) based upon individual Channels.

Transitioning to Android O

Notification channels can only be created in the code of your application, and cannot be created programmatically in the Braze Dashboard. We recommend your engineering team work with your marketers to ensure the desired notification channels are properly added to the dashboard.

Starting with Android O, push notifications require a valid channel to display. If your app targets Android O or above, you must use Braze SDK version 2.1.0 or higher. Your development team should define the channels that you want to use as well as suggested notification settings (e.g importance, sound, lights) for each channel in your application code. You can find Android’s developer documentation here and Braze’s developer documentation here.

Note that Android supports localization for channel names, so in the code of your application you can associate one channel ID with multiple translations of a channel name.

Once these channels are created, your engineers will need to pass on the associated channel IDs to your marketing team. Your team should enter your channel names and channel IDs into the Braze dashboard for use in your Campaigns and Canvases.

To add a channel to the Braze dashboard, navigate to the Android push composer, select the notification channels field and then select “manage channels.” Note that only users with permissions that include “manage apps” will be able to manage channels.

SDK Default Channel

Android requires a valid channel to display push notifications on API level 26 (Android O) or above. Braze’s Android SDK 2.1.0 includes a default channel called “General,” which will be created and used if you do not specify additional channels in the dashboard or if you attempt to send to an invalid channel. You can rename this label in the SDK and provide a description for the channel. We recommend that you consider this in order to provide a better user experience.

Once a channel is added to your application, you can opt to remove it. However, consumers will always be able see the number of channels that you’ve removed. Braze’s dashboard does not include support for programmatically creating channels - channels must be created and defined in the code of your application in order to provide a seamless experience.

Again, we recommend that you coordinate with your engineering team to ensure a seamless transition to targeting Android O.

Dashboard Fallback Channel

Braze allows you to specify a dashboard fallback channel. The purpose of the dashboard fallback channel is to provide a channel ID for legacy push messages with no explicit channel selection. We define a channel selection as choosing a channel in our Android push composer.

Messages that do not have a channel selected will be sent with the dashboard fallback Channel ID. When you change your dashboard fallback channel, any message that does not have a channel explicitly selected will send with the ID of the new fallback channel.

Here’s an example of the dashboard fallback channel expected behavior:

Your dashboard fallback channel is called “Marketing” and you have 10 Android push messages that you have never selected a channel for. These Campaigns are sending through the “Marketing” channel because the “Marketing” Channel is the dashboard fallback channel.

Additionally, you have 15 messages that you’ve selected to send through the “Social Notifications” channel and 5 messages that you’ve selected to send through the “Marketing” channel.

You then decide to change your dashboard default channel from “Marketing” to “Updates”.

In this situation, all 10 Campaigns with no channel selection that were previously sending through the “Marketing” Channel will now send through the “Updates” channel because these messages send through the fallback channel. The 15 messages that were sending through the “Social Notifications” channel will continue to send through the “Social Notifications” channel. The 5 messages that were sending through the “Marketing” channel will continue to send through the “Marketing” channel.

In the event an invalid channel ID is supplied to Braze (ie. if you provide a channel ID that your developers did not create in the SDK), we will deliver the notification through your SDK default channel. Therefore, we highly encourage you to test your notification channels via Braze’s dashboard during development.

To better understand the expected behavior for channels, please refer to the following table:

Scenario Outcome
Company ABC updates to an SDK that supports Android O
Company ABC does not add any channels to the Braze dashboard
Company ABC does not rename their SDK default channel
Push notifications sent to Android O devices will create a channel called “General” and notifications will be sent through the “General” channel
Company XYZ updates to an SDK that supports Android O
Company XYZ does not add any channels to the Braze dashboard
Company XYZ renames their SDK default channel to “Marketing”
Push notifications sent to Android O devices will create a channel called “Marketing” and notifications will be sent through the “Marketing” channel
Company LMN updates to an SDK that supports Android O
Company LMN defines 2 channels in their application code, “Promotions” and “Order Updates”
Company LMN adds the channel IDs for “Promotions” and “Order Updates” to the Braze dashboard
Company LMN designates “Promotions” as the dashboard fallback channel
Company LMN renames their SDK default channel to “Marketing”
Push notifications sent to Android O devices will not create a channel

Unless the marketer explicitly specifies that notifications should send through the “Order Updates” or “Marketing” channel, all notifications created before the channels were added to the dashboard will send through the “Promotions” channel

The SDK default channel, “Marketing” is only created and used if the company attempts to send a notification through an invalid channel ID or if explicitly selected
Company HIJ updates to Android O but does not update to Braze Android SDK to 2.1.0 or higher Notifications sent to users running Android O or above do not appear

Adding Channels to Braze’s Dashboard

  • Open any Campaign or Canvas that includes an Android push and click “edit Campaign”.
  • Navigate to the Android Push message composer
  • Click “Manage Notification Channels”. Note that any channels added here will be available globally for all Campaigns and Canvases and that you must have “manage apps” permissions for your app group in order to manage channels.


  • Click “Add Notification Channel”

  • Enter the name and ID of the notification channel you want to add

Enter Channel

  • Repeat the two steps above for each notification channel that you’d like to add

  • Press “save” to save your changes

Specifying your Fallback Channel

Your fallback channel is the channel that Braze will attempt to send your android message with if you have not selected a channel for the message. The only Campaigns/Canvases that will have android messages without a channel selection are Campaigns/Canvases that were created before your team added channels to the Braze dashboard. If you change your fallback channel, the change will be applied globally to all Campaigns and Canvases without an explicit channel selection.

  • Open any existing Campaign or Canvas

  • Navigate to the android push composer

  • Select “Manage Notification Channels”

  • Add the channel to the dashboard (if it has not already been added)

  • Select the radio dial next to the channel that you’d like to designate as the fallback channel


  • Save your changes. Your changes will be applied globally

Adding Channels to your Android Push Messages

  • Navigate to the Android Push composer on any Campaign or Canvas


  • Select the channel you’d like to use from the dropdown. If you do not have a dropdown, but rather have the below view, you’ll need to add channels before selecting them for Campaigns


Rich Notifications

Rich Notifications allow for more customization in your push notifications by adding additional content beyond just copy. Android notifications have included images in push notifications for some time now, messaged as an ‘Expanded Notification Image’. Starting with iOS 10, your customers will be able to receive iOS push notifications that include gifs, images, videos, or audio.

Rich Not Blog

Android Rich Notifications


  • Note that expanded notification view is only available on devices using Jelly Bean (Android 4.1) or higher. If a user’s device is not running on these systems, they will not see the notification image.
  • Currently, Android rich notifications only allow for static images including jpg and png file formats.

Setting Up Your Android Rich Notification

  1. Follow the campaign steps you normally do to compose a push notification for Android. You will be using the same composer that you use for setting up push notifications that do not contain rich content.

  2. Add your Summary Text/ Image Caption that you’d like to display above the image in the notification.

    Add Android Summary Text

  3. Add your image in the ‘Expanded Notification Image’ field in the composer of the message. Images can be uploaded directly through the dashboard or by specifying a content URL that is hosted elsewhere.

    Add Android Image

  4. Once your rich notification content is uploaded to the dashboard, you can simply continue scheduling your campaign the way you always do.

iOS 10 Rich Notifications


  • To ensure your app is able to send rich notifications, please follow these instructions here, as your developer will need to add a service extension to your app.
  • You should also reference Apple’s documentation for media limitations and specs. We recommend using as small of a file size as possible. In practice, sending large files can cause both unnecessary network stress and make download timeouts more common.
  • File types that we currently support for direct uploading within our dashboard include jpg, png, or gif. These files can also be entered into the templatable URL field along with these additional file types: aif, m4a, mp3, mp4, or wav.

Setting Up Your iOS Rich Notification

  1. Follow the campaign steps you normally do to compose a push notification for iOS. You will be using the same composer that you use for setting up push notifications that do not contain rich content.

  2. Add your image, gif, audio, or video file in the ‘Rich Notification Asset’ field in the composer of the message. Please reference the above requirements on how to add your content files.

    Add Image

    You can also limit this message to only send to users who have a device that runs on iOS 10. For users who have not upgraded to iOS 10 it will appear as a text only notifications without the rich content if you leave the below box unchecked.

    iOS 10 Checkbox

  3. Once your rich notification content is uploaded to the dashboard, you can simply continue scheduling your campaign the way you always do.

Notification IDs

A notification ID can be assigned to a push notification when you want the option to group or replace it with an updated version once it’s been issued.

To do this, navigate to the composition page of the push you’d like to add the ID to and enter an integer in the Notification ID section. To update this notification once you’ve issued it, send another notification with the same ID that you used previously.


Developer Console

The Developer Console is useful for both important identification information for your app group and for troubleshooting. There are typically four tabs in this section, which might show subject to your access or permissions level: API Settings, Message Activity Log, Event User Log, and Internal Groups. Each is outlined below.

API Settings Tab

The API Settings page displays API identifications for your app group. The first section on Services will link you to our technical documentation for whatever you’re using the API for (User Data, Messaging, Email Sync, and Exporting your data).

Rest API Keys

This section provides your App Group REST API Key, the unique identifier that allows you access to your data for an app group. This key is required with every request to the Braze API.

API Whitelisting

You can whitelist specific IP addresses and subnets to send requests to our API for this app group. If you don’t specify any, requests can be sent from any IP address.


These identifiers are used to reference specific Apps in requests made to the Braze API.

Additional API Identifiers

To integrate with our API, you can search for the identifiers related to any Segment, Campaigns or Cards that you want to access from Braze’s external API. Once you’ve selected any of them, the identifier will be displayed underneath the dropdown menu.

Message Activity Log Tab

The Message Activity Log, in the Developer Console, gives you the opportunity to see any messages, especially error messages, associated with your campaigns and sends. You can see API campaign transactions, troubleshoot details on failed messages, and gather insight on how to improve notification delivery or solve existing technical issues.


These messages can come from our own system, your apps or platforms, or our third party partners. This can result in an infinite number of messages that can appear in this log.

To determine what your messages mean, pay attention to the wording of each message and the columns that correspond with it, as it can help you troubleshoot using context clues. For example, if you have a log entry whose message states “empty-cart_app” and you aren’t sure what that means, look to the left at the Type column. If you see “Aborted Message Error”, you can safely assume the message was what was written as the abort message using Liquid, and that the message was aborted because the intended recipient of the message had an empty cart in your app.

However, there are some common message types you might see, and some might even provide troubleshooting links to help you diagnose and fix issues.

Message Type Sample Text in Message Column Context/Explanation
Block The email account that you tried to reach is disabled. Learn more at SAMPLE URL. Your message never reached this person’s inbox - because there was no inbox to reach! If you want to dig further in, messages like this can sometimes have links in the View Details column that will allow you to view the intended recipient’s profile.
Block Spam message is rejected because of anti-spam policy. For more information, please visit SAMPLE URL. Uh oh. Looks like your message got categorized as spam here. It might just might be for that intended recipient, but if you’re seeing this message a lot, you might want to re-evaluate your send habits or the content of your message. Also, think back - did you do an IP warm-up? If not, reach out to Braze for advice on getting one going.
Aborted Message Error empty-cart_web If you have an app with a cart or you create a send with an abort message in the liquid, you can customize what message is returned to you if the send is aborted. In this case, the message returned is empty-cart_web.

Event User Log Tab

The Event User Log can help you break down, debug, or otherwise troubleshoot issues in your Braze Integration. This tab gives you a log of errors that details the type of error, which app it’s associate with, when it happened, and often an opportunity to view the raw data associated with it.

To find your logs easily, you can filter based on:

  • SDK or API
  • App Names
  • Time frame
  • User

Each log is broken up into multiple sections, which can include:

  • Device Attributes
  • User Attributes
  • Events
  • Campaign Events
  • Response Data

Click the “Raw Data” button to show the raw JSON data for that specific log.

Raw logs

Event User Logs will remain in the dashboard for 7 days after they are logged.

Internal Groups Tab

Internal Groups are a great way to build and organize internal or 3rd party test groups and provide insight into the SDK or API logs available from your test device during SDK integration testing. You can create an unlimited number of custom Internal Groups with up to 1000 members.

Creating a Group

Depending on your access and permissions, you can create Internal Groups from the Developer Console in the

  • Click ‘Create Internal Group’ on the top, right to create a new group.
  • Give your group a name.
  • Choose a group type from those shown (defined below).

Internal Group

Group Type Use Case
User Event Group Used for verifying events or logs from your test device.
Content Test Group A similar concept to Test Lists. Can be used across Push, Email, and In-App messages to send a rendered copy of the message.
Seed Group Automatically sends a copy of the Email to everyone the Seed Group upon send.

Adding Test Users

After you create your Internal Group you can add test users as members. If you are not already on your Internal Group’s management page, click into it. Then, click “Add Test User” and add them as identified or anonymous users, or in Bulk.

User Logs 1

Add Test User Tab Name Description
Identified Users Search for the user by their External User ID or email address.
Anonymous Users Search by IP address. Then, provide a name for each test user that is added. This is the name that all event logs will be associated with on the Event User Log page.
Bulk Add Users Copy and paste a list of email addresses or external ID’s into the provided section. Braze will only allow you to add users that are already known in the database. Remember to upload your .csv files to add users to the database or programmatically create them via the API.

Content Test Groups

Similar to sending a preview test of a message, the Content Test group saves you time and allows you to launch tests to a pre-defined list of Braze Users simultaneously. This functionality is available for Push, In-App Message, and Email within Braze.

You can select individual Braze Users or as many Internal Groups to send the message to as you want. The message will utilize the attributes available for each individual User. For Users who have no attributes, the default value set will be utilized.

Additionally, if you preview the message as a ‘random user’, ‘custom user’ or ‘select an existing user’ - the option to send that previewed version is presented. Unchecking the box will allow you to send based on each Users’ attributes versus the previewed version.

Lastly, for clients who use an IP pool to send out email, you can now select which IP pool you would like the email to be sent from by simply selecting the pool from the dropdown available.

Only Groups that are tagged as Content Test will be available on the ‘preview’ section of a message.

Content test group settings

Seed Groups

Seed Groups are only meant for the Email channel and allow you to send a copy of each email variant message to members of that group. Seed Groups are not available for API Campaigns, though you can include Seed Groups via an API triggered entry in Campaign. This feature is typically used with partners such as Return Path or 250OK to measure deliverability metrics. It can be used to keep a record of the email content for historical/archive purposes.

Once you have created an Internal Group and tagged it to be used as a Seed Group, you can select it from the Delivery section of the Campaign composer or on the Send Settings section in a Canvas.

If your Seed Group members report not seeing the message in their inbox, ensure that they are listed in the Internal Group, verify that your subject lines are different and that Gmail has not bundled the emails together, or have them check their SPAM folders.

For Campaigns

Seed Groups can be edited from the ‘Targeting’ page when composing an Email Campaign.

Seed Groups send to each email variant once and are delivered the first time your user receives that particular variant. For scheduled messages this typically is the first time the campaign launches. For Action-Based or API Triggered campaigns, this will the time the first user is sent a message.

If your campaign is multivariate and your variant has a 0% send percentage, it will not be sent to seed groups. Additionally, if the variant has already been sent and has not been updated to resend in Edit Seed Groups on the Target page, it will not send again by default.

If there is a recurring campaign and an update is conducted on any one of the variants, you have the option of re-sending to only the updated variants, all variants or to turn off seed group sending upon update.


For Canvas

Seed groups in Canvas work in a similar fashion to that of any Triggered Campaign. Braze automatically detects all steps that contain an email message and will send to these when your user first reaches that particular email step.

If an Email step was updated after the Seed Group was mailed, the option to only send to updated steps/all steps/turn off seeds will be presented.

iOS Push Message Titles

To add a headline to an iOS push notification, use the Title field in the Braze message composer. The headline will appear in bold once the message is sent.


Engagement Reports

With Engagement Reports, customers can now extract data across multiple Campaigns and/or Canvases. Customers have the ability to:

  1. Run a one time report or Schedule a report to be sent later.
  2. Email the report Daily, Weekly, or Monthly.
  3. Set a defined time range of data to include or do a rolling window with scheduled reports.
  4. Choose a defined number of messages to be included in the report or automatically insert messages based on tags.
  5. Select from over 20+ KPI Metrics.
  6. Choose various delimiters and compression types for the report.

How To Use

Creating A New Report

Navigate to Data » Engagement Reports. Note that your Braze user account must have ‘Export User Data’ access to utilize Engagement Reports. To create a new report, click ‘Create New Report’ located on the top right of the page.


Add Messages

The Add Messages tab allows you to select your messages in two ways:


Manually select Campaigns or Canvases - This option gives you the freedom to choose whichever Campaigns or Canvases you would like in this report.

Automatically select Campaigns or Canvases - This option gives you the ability to automatically include all messages based on a specific tag. You can target messages that have any one or all of the tags listed. This option is useful if you are setting up recurring reports and utilize our tagging system.

Add Stats

The Stats tab will automatically show you stats for the types of Campaigns or Canvases you have selected. For instance, if you picked Email messages, you will only see the Email Stats. If you picked a combination of Email and Push, you will see the stats for those two channels.

channel stats available
Email Sent, Opens, Unique Opens, Clicks, Unique Clicks, Unsubscribes, Bounces, Delivered, Reported Spam
Push Sent, Opens, Influenced Opens, Bounces, Body Clicks
Web Push Sent, Opens, Bounces, Body Clicks
In App Message Impressions, Clicks, First Button Clicks, Second Button Clicks
Webhook Sent, Errors


Set Up Report

The Set Up Report tab allows you to enter your report name, select the compression and delimiter of the report and include whom you would like to send this report to. Additional functionality now includes “Data Coverage” and “Schedule Report”.

Data Coverage

Time Frame: By default the data range shown will go from the earliest message selected till present date. You can customize this by selecting the date dropdown and using the custom range selection OR by selecting the next radio button and defining your date range with the dropdown options available.

Data Display: By default the data displayed in the engagement reports is daily (1 day). Should you like to view this data across different intervals, you can choose an explicit number of days or weeks to aggregate the data for the report. So instead of seeing daily metrics, you can look at your engagement by week, month, quarter, etc. Should a time-centric aggregation not suffice, you can also elect to export data at the Campaign or Canvas level.


Schedule Report

There are two options when scheduling your report.

  • Send Immediately: After the report is saved, Braze will send this report Immediately

  • Send at a Designated Time: This option gives you flexibility to choose how frequently you would like to receive this report. You can choose to send this report every X days, weeks or months. Additionally you can define when to stop sending the report.


About the Report

  • The report is exported as a link embedded inside of a triggered email.
  • Regardless of the number of Campaigns or Canvases selected, only a max of 2 CSV files will be generated - one for all of the Campaign data, and one for all of the Canvas data.
  • The report, when opened, will contain all the statistics selected in the ‘Add Stats’ section of the setup process.
  • Certain data is aggregated at the ‘Campaign’ or ‘Canvas’ level versus at the individual ‘variant’ or ‘step’ level.
  • Note: Reports are not saved, and re-running the report can result in updated statistics.

Report Glossary

Statistic Description
Date Represents the date of the data shown. This will coordinate to your company timezone
id Canvas API identifier. You can retrieve a list of Canvas id’s through this API or utilize that identifier to further query details, time series data, and rollups
name Name of the Canvas as written in the dashboard
variant_name Name of the Canvas path as written in the dashboard
step_name Name of the Canvas step as written in the dashboard
unique_recipients Integer count of the number of users who have received Campaign or Canvas messages
type Indicates whether the data in the row are specific to a variant, step, or specific message within a step
sent Integer count of the number of push, email and or webhook messages successfully fired from the platform
delivered Integer count of the number of emails that did not bounce and made it to a user’s inbox
opens (Email) Integer count of all the times users open an email. For the equivalent metric for push, please find total_opens and direct_opens
unique_opens (Email) Integer count of the unique instances users open an email
clicks Integer count of all of the clicks tracked on an Email or In-App Message. Please note that for In-App Messages, this metric only populates for those that do not have buttons
unique_clicks (Email) Integer count of all unique clicks tracked on an email message
reported_spam Integer count of the number of times users clicked on the spam button in their inbox. This metric does not track the number of times an email went directly into a user’s spam folder.
bounces Indicates whether the Email or Push message failed to reach to user. Email-related data will indicate a hard bounce
unsubscribes Integer count of the number of users who unsubscribed from an email message
direct_opens Integer count of all the times users directly clicks/tapped on a push notification
total_opens Integer count of al the time users logged a direct_open or influenced open
entries Integer count of all the users who entered into a Canvas. This number does not always equal the number of users who received messages from Canvas steps, as segmentation and or triggering criteria can affect this
errors Integer count of non-200 error responses from wehook campaigns and Canvases
revenue Any purchase event logged by a user who entered the canvas and is still within the primary conversion event window will be attributed here. The amount is converted into dollars. Users can multiple purchases within this period and all amounts will be attributed back to the day of purchase
conversions Number of users who have performed the primary conversion event, or “conversion event A,” on that particular day
conversions_by_entry_time Number of users who have entered into a Canvas on that particular day and also performed “conversion event A” by the end of the conversion deadline
conversions1 Number of users who have performed “conversion event B” on that particular day
conversions1_by_entry_time Number of users who have entered into a Canvas on that particular day and also performed “conversion event B” by the end of the conversion deadline
conversions2 Number of users who have performed “conversion event C” on that particular day
conversions2_by_entry_time Number of users who have entered into a Canvas on that particular day and also performed “conversion event C” by the end of the conversion deadline
conversions3 Number of users who have performed “conversion event D” on that particular day
conversions3_by_entry_time Number of users who have entered into a Canvas on that particular day and also performed “conversion event D” by the end of the conversion deadline

Creating a Webhook Template

Step 1: Navigate to the Webhook Template Editor

You can access the Webhook Template by first clicking the Campaigns tab under Engagement on the navigation bar, which will reveal a drop down menu with a ‘Templates and Styles’ tab. Click on this tab to access the Webhook Template Editor.


Step 2: Create a New Template

You can now create a new template, edit an existing template or utilize one of the predesigned webhook templates that are offered. The pre-designed templates currently offered are for Twilio and Facebook messenger.

Step 3: Customize Your Template

Webhook templates can be used for many different use cases. You can start by entering a unique template name to be utilized. You can also fill in the webhook URL, the Request Body, Request Headers and select the HTTP Method to be used.

If you want to see how your webhook looks before sending it out to your users, you can send a test webhook through the Settings tab in the top right corner.


Step 4: Save Your Template

Be sure to save your template by clicking the “Save Template” button in the bottom right corner of the editor. You’re now ready to use this template in any campaign you choose.


Note: Edits made to an existing template will not be reflected in campaigns that were created using the previous versions of that template.

iOS 10.3 Customizable App Icon Feature

With iOS 10.3 Apple introduced the ability to change an app’s home screen icon without having to update the application from the Apple App Store. The developer can now allow the user to change the home screen icon inside of their app. Apple requires all of the app icon images that the developer wants to make available to the user to be included in the binary that is submitted to Apple for review during the publishing of the app on the Apple App Store.

To notify your users of this feature it is possible to send an In-App Message or push notification through Braze to the user explaining this functionality or asking the user if they would like to change their icon. The developer would only need to create a deep link into the application where the the native iOS prompt can be shown to make the icon change. This is similar to the same guidance we provide around setting up a Push Notification Primer for APNS today.

In additon, this messaging can take full advantage of Braze’s segmentation ability to make the message copy highly contextual to a user. You can also leverage Braze’s A/B testing of messages to see which messaging makes the most impact to your desired result.

Push Action Buttons

Push Action Buttons enable you to set content and actions for buttons when utilizing Braze’s iOS and Android push notifications. Your users will now be able to interact directly with your app from a notification without needing to click into an app experience to take action.

Push Action Buttons

How To Use Action Buttons

Each interactive button can link to a webpage, a deep link, open the app, or dismiss the notification. You can specify your Push Action Buttons in the ‘On Click Behavior’ section of the push message composer in the Dashboard.

iOS Push Action Buttons

iOS Push Action Buttons

Note: Due to iOS’s handling of buttons, you will need to perform additional integration steps when setting up push action buttons, which are outlined in our Documentation. In particular, you will need to either configure iOS Categories or will need to select from certain default button options. For Android integrations, these buttons will work out of the box.

Android Push Action Buttons

Android Push Action Buttons

Templates and Media

The ‘Templates and Media’ section allows you to manage templates and upload images for messages in a single, centralized location. You can consolidate and organize your templates across the dashboard for a coherent look and feel. To access this section, navigate to Engagement > Templates & Media in the Dashboard.

Templates and Media

The Templates & Media section allows you to aggregate templates across the following features:

Locations and Geofences

Geofences are only available in select Braze packages. For access please create a support ticket or speak with your Braze Customer Success Manager.

The ubiquity and flexibility of mobile technology allows marketers, product managers and growth teams to reach their users everywhere, blurring the lines between digital and real-world experiences. Using the Braze platform, you can create and enhance relationships with your users based upon their location in the real world, unlocking a powerful set of deeply connected interactions:

  • Upload the locations of all of your brands’ brick and mortar stores, and send push notifications to loyal users notifying them of in-store promotions if they pass nearby.
  • Upload the location of an upcoming concert, and message users letting them know where to register when they reach the venue. Then, follow up with a thank you message an hour after they depart.

At the core of Braze’s real-time location offering is the concept of a “geofence.” A geofence is a virtual geographic area, represented as latitude/longitude pairs combined with a radius, forming a circle in a specific position on the globe. Geofences can vary in size from the size of a building to the size of an entire city.

You can define geofences on the Braze Dashboard and trigger campaigns in real-time as users enter and exit them across the globe. Geofences are deeply integrated into Braze’s segmentation and messaging capabilities. Campaigns can be delivered in real-time to users as they exit or enter geofences, or sent as followups hours or days later. As users enter or exit your geofences, Braze’s location analytics also add a new layer of user data that can be used for segmentation and re-targeting. Geofence-specific analytics also generate insight on the activity of particular locations of interest.

Dashboard Overview

On the Braze dashboard, geofences are managed in the Locations page in the Engagement section. Geofences are organized into geofence sets - a group of geofences that can be used to segment or engage users throughout the platform. Example geofence sets include All Northeast Regional Stores or September Events. A given geofence set may only contain up to 10,000 geofences.

Creating Geofence Sets Manually


Once you have created a geofence set, you can manually add geofences by drawing them on the map. We recommend creating geofences with a radius of at least 100 meters for optimal functionality.

Creating Geofence Sets via Bulk Upload

Geofences may be uploaded in bulk as a GeoJSON object of type FeatureCollection. Each individual geofence is a Point geometry type in the feature collection. The properties for each feature require a "radius" key, and an optional "name" key for each geofence.

The sample below represents the correct GeoJSON for specifying two geofences: one for Braze’s headquarters in NYC, and one for the Statue of Liberty south of Manhattan. We recommend uploading geofences with a radius of at least 100 meters for optimal functionality.

  "type": "FeatureCollection",
  "features": [
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [-73.992473, 40.755669]
      "properties": {
        "radius": 200,
        "name": "Braze HQ"
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [-74.044468, 40.689225]
      "properties": {
        "radius": 100,
        "name": "Statue of Liberty"
    }, ...

Note: The maximum geofence radius that may be uploaded is 100000 meters (100km/62mi).

Using Geofence Events

Once geofences have been configured, you can use them to enhance and enrich how you communicate with your users.

To use a geofence, create a Campaign or Canvas and choose “Action-based Delivery” for its delivery method. Next, add a trigger action of Trigger a Geofence. Finally, choose the geofence set and geofence transition event types for your message. You can also advance users through a Canvas using geofence events.


Mobile Integrations

Cross-Platform Requirements

Geofence-triggered campaigns are available on iOS and Android. To support geofences:

  1. Your integration must support background push notifications.

  2. Braze location collection must not be disabled.

Note: Braze location collection is enabled by default. To verify your location collection status on Android, ensure that com_appboy_disable_location_collection is not set to true in your appboy.xml.

Note: On iOS, we are not strictly enforcing the Braze request processing policy for geofences. When geofences are enabled, the requests will automatically be sent up even if the processing policy is manual processing.

Geofence Configuration


The geographic center of the geofence.


The radius of the geofence in meters, measured from the geographic center. We recommend setting a minimum radius of 100 meters for all geofences.


Users receive geofence triggered notifications after performing enter or exit transitions on individual geofences. After a transition occurs, there is a pre-defined period of time during which that user may not perform the same transition on that individual geofence again. This period of time is called the “cooldown” and is pre-defined by Braze. Its main purpose is to prevent unnecessary network requests.

Frequently Asked Questions

How do geofences affect battery life?

Our geofencing solution uses the native geofence system service on iOS and Android and is tuned to intelligently trade off accuracy and power, ensuring best in class battery life and improvements in performance as the underlying service improves.

How many geofences can I upload to Braze?

You may create or upload an unlimited amount of geofences on the Dashboard, allowing your marketing team to setup geofence sets and campaigns without needing to calculate numbers of geofences. However, each geofence set can hold a maximum of 10,000 geofences. Braze dynamically re-synchronizes the geofences that it tracks for each individual user, ensuring that the most relevant geofences to them are always available.

Can I store more than X geofences?

Per Android’s documentation, Android apps may only store up to 100 geofences locally at a time. Braze is configured to store only up to 20 geofences locally per app. For geofences to work correctly, you should ensure that your App is not using all available geofence spots.

iOS devices may monitor up to 20 geofences at a time per app. Braze will monitor up to 20 locations if space is available. For geofences to work correctly, you should ensure that your App is not using all available geofence spots.

When are geofences active?

Braze geofences work even when your app is closed, at all hours of the day.

How accurate are Braze geofences?

Braze geofences use a combination of all location providers available to a device to triangulate the user’s location. These include Wifi, GPS, and cellular towers.

Typical accuracy is in 20-50m range and best-case accuracy will be in the 5-10m range. In rural areas, accuracy may degrade significantly, potentially going up to several kilometers. Braze recommends creating geofences with larger radii in rural locations.

Media Library

The Media Library allows you to manage your assets in a single, centralized location. To access this feature please go into the “Media Library” tab in the Templates & Media section of your dashboard.

The Library now allows you to:

  • Upload multiple images at one time
  • Upload a folder with your images (max: 50 images)
  • Crop an existing image to create the right ratio for your messages
  • Add tags or teams to help further organize your images
  • Search by tags or teams in the new Media Library grid
  • Drag and drop images or folders to be uploaded
  • Delete images


Stats Available

Within the Media Library you can now see the image dimensions, URL, type as well as the date it was added to the library.

Accessing the Media Library from a Message Composer

Previously when composing a message, you would upload images for each respective message. As the Media Library now acts as your dashboard’s centralized location for assets, all images will now be uploaded directly to it. This additional functionality gives you the flexibility to re-use images across different messages.


How do I crop an existing image?

You can crop an existing image by selecting the image from the Media Library and clicking the button for “Save & Crop Image”. You will be redirected to a cropping composer where you can select your ratio type and edit the name of the new image. Once you hit save, your new image can be used.



Can I crop all images?

Please note that the Media Library does not currently support cropping GIF images.

Why can’t I upload any image I want into the Push Composers?

The reason for this is because most composers have restrictions on the image ratio size that is allowed.

CSS Inlining

What is CSS inlining?

CSS Inlining is a form of email preprocessing that moves styles in a CSS style sheet into the body of an HTML email. The term “inlining” refers to the fact that styles are applied “inline” to individual HTML elements.

Why use CSS inlining?

For some email clients, CSS inlining can improve the way that emails render and help ensure that your emails look the way you expect.

How do I enable/disable CSS inlining?

You can control whether CSS Inlining is turned on or off for any email message through a checkbox in the Sending Info section of Braze’s Email Composer.


Additionally, a default on or off state can be set globally from Manage App Group > Email Settings > Inline CSS. This setting ensures that all new email messages start with the desired default value. Note that changing this setting will not affect any of your existing email messages. You can also override this default at any time while composing email messages.


Link Templates

Link Templates, allow users to append parameters or pre-append URI’s to all links in an Email message. This can be ideally used for the following use cases:

  1. Appending Google Analytics query parameters to all links in a given Email message easily.
  2. Pre-appending a URI to all links in a given Email message

On the Braze dashboard, Link Templates are found in the Templates & Media section. Dashboard users can create an unlimited number of Link Templates to support their various needs.

There are two types of Link Templates a user can create.

Clients who want to pre-append a string or URI before a link in their Email message can create a new Link Template and choose the Template position to be “Before URI”. This will allow you to enter a string that will always get appended before a URI. A preview section is provided to give you an example of the insertion process.


Clients who want to append query parameters after a URI in their Email message can create a new Link Template and choose the Template position to be “After URI”. This will allow you to enter query parameters (value=something) to end of each URI. You can have multiple parameters appended to the end of a URI.


Selecting a Template

Once your templates are setup, you can select which template you would like to use from the Email Editor Composer. Proceed to open the Email composer, click Content Library and select Link Templating tab. You will see all the links present in your Email and can add the template from there.



Q: Can I upload multiple templates to my Email?

Yes, you can insert as many templates as you would like in your Email messages. As best practice, you should test your emails to ensure that the links are not exceeding 2000 characters as most browsers will shorten or cut the links.

Q: How do I preview my links with all of the tags applied?

Once you have applied the Link Template, you can send yourself a test email to view all the links. Additionally you can open the links from the preview pane in a new tab to view the links. Lastly you can hover over the links in the Preview Pane and see them at the bottom of your browser.

Push Stories

Push Stories is a new type of Push Notification introduced by Braze (formerly known as Appboy). It allows customers to send down multiple ‘pages’, which consists of an image, click action, title, and description to a device. The users can iterate through these pages and go though the ‘story’ as told by each marketer.

Android Example (Expanded) IOS Example (Expanded)
AndroidPreview IOSPreview

How it works

Pre-req: Clients must update to the latest version of Android(version:2.2.0+) and IOS (version: 3.2.0+)

Dashboard Changes


New Composer


The Push Story composer is controlled by a drop down at the top. You can choose to send a Standard Push Notification as you would today or send a Push Story Notification instead.

To create a page:

  • Click “Manage Pages” from the main composer.
  • Insert an image for each page, along with the click behavior for that image.
  • Title/Description for each page can also be inserted (if inserted for one page, they must be inserted for all pages).
  • The previews will be reflected and are interactive.

Push Stories Analytics


The analytics will look very similar to the current analytics section for Push Notification. The only difference is when you open the “Direct Opens” section, you can now see clicks per page.


Can I target users who clicked a particular page in the Push Story?

At this time, segment/filter support was not included. We will look to enable this feature in v2.

I sent myself a Push Story on iOS but did not receive the notification - what happened?

Apple has specific rules in place that will prevent certain types of notifications from being sent to a device based on a number of different factors - this includes evaluating the customers data plan, notification size and/or the customers storage capacity. As a result, sometimes no notification will be sent to your customers. This is a limitation imposed by Apple that should be considered when designing your Push Story.

I sent myself a Push Story on iOS but saw the condensed view instead - what happened?

In certain situations where all the pages do not load, for example due to a loss of data connection, the Push Story will only show the condensed notification.

Inbox Vision

Inbox Vision allows marketers to view their emails from the perspective of various email clients and mobile devices. Access Inbox Vision from the email editor by clicking the ‘Preview and Test’ button. It also allows you to spam test from the Spam Test tab.

Test Your Email

To test your email message in Inbox Vision, click ‘Preview and Test’ within the email composer. Braze then sends an HTML version of your email to various email clients used across the globe, which may take between two and ten minutes to complete.

Braze will then display screenshots of a sample, rendered HTML on desktops, mobile devices, and tablets. The devices in which screenshots are displayed are scrollable, to allow for better viewing.

If you run an Inbox Vision test, you will also receive a code analysis and spam testing results.


Code Analysis

Code analysis is a way for Braze to highlight issues that may exist with your HTML. Code analysis shows the number of occurrences of each issue and provides insight into which HTML elements are not supported.

inboxvision2 inboxvision3

Spam Testing

Spam testing attempts to predict whether your email will land in spam folders or in your customers’ inboxes. Spam testing runs across major spam filters, such as IronPort, SpamAssassin, and Barracuda, as well as major ISP filters such as and


Q: What does the reprocess screenshot button do?

A: Very rarely, you will encounter that some screenshots for certain email clients are not clear. The reprocess screenshot button will create another screenshot.

Q: Why does the email preview not appear but my code analysis does for the same client?

A: Taking a screenshot takes longer than code analysis since we wait till the email arrives in the inbox before taking the screenshot. As a result, sometimes the code analysis will show up faster than the preview for a particular email client.

Q: Can I trust the accuracy of your email test results?

A: All of our tests are run through actual email clients. We work hard to ensure that all renderings are as accurate as possible. If you consistently see an issue with an email client, please open a support ticket.