Initial SDK Setup

Integrating the Braze SDK will provide you with basic analytics functionality as well as in-app messages with which you can engage your users. Note that the web SDK file size is 32.3 KB.

Step 1: Integrate the Braze Library

To integrate the Braze Web SDK, simply follow the instructions in the “Getting Started” section of the Braze Web SDK Github Repository. Be sure to substitute the API key found within the “App Settings” page of the Braze dashboard for YOUR-API-KEY-HERE. For more detailed technical documentation, refer to the complete JSDocs.

If you have been provided a custom SDK endpoint, please include this in addition to your API key:

US Cluster:

appboy.initialize('YOUR-API-KEY-HERE', {baseUrl: ''})

EU Cluster:

appboy.initialize('YOUR-API-KEY-HERE', {baseUrl: ''})

Error Logging

To enable logging, you can pass the option enableLogging: true to your initialize function (or call appboy.toggleAppboyLogging() after initialization), which will cause Braze to log to the javascript console. This is useful for development but is visible to all users, so you should remove this option or provide an alternate logger with appboy.setLogger() before you release your page to production.

Tag Managers

Google Tag Manager

Initializing the SDK

Braze’s SDK can be initialized and controlled within tags configured from Google Tag Manager.

To initialize Braze’s SDK create a ‘Custom HTML’ tag within your Google Tag Manager workspace. Place Braze’s Web SDK/javascript code from the standard integration instructions within the tag.

This is instead of directly placing the snippit directly within the <head> section of your website.

On page load, include window.appboy = appboy; after appboy.openSession() near the end of the of the initialize tag. Subsequent tags which fire after page load can then reference this. For example <script type="text/javascript">window.appboy.logCustomEvent("test event")</script>.


Please also ensure to replace the API key and custom SDK endpoint in the code with your API key and, if applicable, custom endpoint.

Braze suggests the tag has the trigger configuration of Page View > DOM Ready. Other Page View triggers can fire the tag, provided that no other Braze related tags are fired to prior to this.


Logging Events and using Braze’s Messaging Channels

For Push, In-App Message, Newsfeed integration instructions please follow the standard integration instructions.

For Analytics integration, reference <script type="text/javascript">window.appboy.logCustomEvent("test event")</script> instead of re-using Braze’s Web SDK/javascript code.


AMD Module Loader

If you are using Google Tag Manager alongside an AMD module loader such as RequireJS to load Braze’s SDK you will need to use the RequireJS-compatible integration snippet in your <head> tag.

For further instruction on this please see the appropriate section of our Braze Web SDK Github Repository.

Tealium iQ

Tealium iQ offers a basic turnkey Braze integration. To configure the integration, just search for Braze in the Tealium Tag Management interface, and provide the Web SDK API key from your dashboard.

For more details, or in-depth Tealium configuration support, please reach out to your Tealium Account Manager.

Other Tag Managers

Braze may also be compatible with other tag management solutions. Please reach out to the Success Squad if you need help evaluating these solutions.

Upgrading The SDK

When you reference the Braze Web SDK from our content delivery network, for example (as recommended by our default integration instructions), your users will receive minor updates (bug fixes and backwards compatible features, versions a.a.a through a.a.z in the above examples) automatically when they refresh your site. When we release major changes however, we require you to upgrade the Braze Web SDK manually to insure that nothing in your integration will be impacted by any breaking changes. Additionally, if you download our SDK and rehost it yourself (which is also a valid integration path), you won’t receive any version updates automatically and should upgrade manually from time-to-time to receive the latest features and bug fixes.

You can keep up-to-date with our latest release following our release feed with the RSS Reader or service of your choice, and see our changelog for a full accounting of our Web SDK release history. To upgrade the Braze Web SDK:

  • Update the Braze JavaScript file - in the default integration, this means changing the version number of[OLD VERSION NUMBER]/appboy.min.js in the <head> of your site to[NEW VERSION NUMBER]/appboy.min.js
  • If you have web push integrated, update the service worker file on your site - by default, this is located at /service-worker.js at the root of your site, but the location may be customized in some integrations.

These files must be updated in coordination with each other to ensure proper functionality.

Push Notifications


A push notification is an alert that appears on the user’s screen when an important update occurs. Push notifications can be received even when your web page is not currently open in the user’s browser. Push notifications are a valuable way to provide your users with time-sensitive and relevant content or to re-engage them with your site.

Sample Push

Check out Braze Academy for additional best practices.

Web push notifications are implemented using the W3C Push standard, which browsers are in the process of supporting. Currently, the browsers which support web push include most versions of Chrome, Firefox, and Opera. Web Push is not supported on any iOS browsers to date. It’s expected that as the standard becomes more widely adopted, more browsers will continue to implement support. Additionally, desktop Safari (on Mac OS X) has a custom web push solution based on Apple Push Notification Services; Braze supports these Safari notifications as well.

HTTPS Requirement

Web standards require that the domain requesting push notification permission be secure.

What defines a secure site?

A site is deemed secure if it matches one of the following secure origin patterns:

  • (https, , *)
  • (wss, *, *)
  • (, localhost, )
  • (, .localhost, *)
  • (, 127/8, )
  • (, ::1/128, *)
  • (file, *, —)
  • (chrome-extension, *, —)

This is a security requirement in the open standards specification that Braze Web Push is built on, and prevents man-in-the-middle attacks.

What if a secure site is not available?

While industry best practice is to make your whole site secure, customers who cannot secure their site domain can work around the requirement by using a secure modal. Braze has prepared an example of this approach.

Step 1: To Support browsers based on Chromium 51 and earlier, create a Firebase Cloud Messaging Project

  1. In the Firebase console, Create New Project
  2. Select the gear icon next to your project name at top left, and select Project Settings
  3. Select the “Cloud Messaging” tab, and note the “Server Key” and “Sender ID”. You will need these.

Firebase Console Server Key and Sender ID Location

Please ensure that you do not restrict access to your Cloud Messaging Server Key to specific IP ranges. This will allow any IP to utilize your Server Key so that Braze can send push notifications appropriately.

Step 2: Configure your Site

  • Add <link rel="manifest" href="/manifest.json" /> to the <head> section of your website.
  • Create a manifest.json file with the content below, and place it in the root directory of your website:

      "gcm_sender_id": "YOUR_CLOUD_MESSAGING_SENDER_ID"
  • Create a service-worker.js file with the content below, and place it in the root directory of your website:

Step 3: Set your Cloud Messaging Server Key on the Braze Dashboard

  1. On the app settings tab of the Manage App Group page (where your API keys are located), select your Web app.
  2. Enter your Cloud Messaging Server Key in the appropriate field under the Push Notifications section.

Step 4: Browser Registration

In order for a browser to receive push notifications, you must register it for push by calling appboy.registerAppboyPushMessages(). Note that this will immediately request push permission from the user. Refer to Chrome’s best practices for user experience guidance on when to call this method. If you wish to show your own push-related UI to the user before requesting push permission (known as a soft push prompt), note that you can test to see if push is supported in the user’s browser with appboy.isPushSupported(). See below for a soft push prompt example using Braze In-App Messages. If you wish to unsubscribe a user, you can do so by calling appboy.unregisterAppboyPushMessages().

Step 5: Configure Safari Push

If you wish to support push notifications for Safari on Mac OS X, follow these additional instructions:

  • Generate a Safari Push Certificate following these “Registering with Apple” instructions
  • In the Braze dashboard, on the app settings page (where your API keys are located), select your Web app. Click “Configure Safari Push” and follow the instructions, uploading the push certificate you just generated.
  • When you call appboy.initialize supply the optional safariWebsitePushId configuration option with the Website Push ID you used when generating your Safari Push Certificate, for example appboy.initialize('YOUR-API-KEY', {safariWebsitePushId: ''})

Common Issues

  1. I followed the integration instructions but I’m still not receiving any push notifications.
    • Not all browsers can receive push messages. Please ensure that appboy.isPushSupported() returns true in the browser.
    • Note that if a user has denied a site push access, they won’t be prompted for permission again unless they remove the denied status from their browser preferences.
    • Note that web push notifications require that your site be https.

Soft Push Prompts

It’s often a good idea for sites to implement a “soft” push prompt where you “prime” the user and make your case for sending them push notifications before requesting push permission. This is useful because the browser throttles how often you may prompt the user directly, and if the user denies permission you can never ask them again. This can be done simply through Braze’s triggered In-App Messages for a seamless user experience. Instead of calling appboy.registerAppboyPushMessages() directly as described above, instead:

  1. Create a “Prime for Push” in-app messaging Campaign on the Braze dashboard.
    • Make it a “Modal” In-App Message. Give it whatever text and styling you wish to present to the user (“Can we stay in touch?”)
    • Give the in-app message a Button 1 Text value of “OK” (or whatever affirmative text you wish), and set the On-Click Behavior to “Close Message.” You’ll customize that behavior later.
    • Under the gear composer section, add a key-value pair. Give it a key of msg-id and a value of push-primer.
    • Give the message a trigger action of the Custom Event ‘prime-for-push’ (you can create that custom event manually from the dashboard) if you need to)
  2. In your Braze SDK integration, find and remove any calls to appboy.display.automaticallyShowNewInAppMessages() from within your loading snippet.

  3. Replace the removed call with the following snippet:
appboy.subscribeToNewInAppMessages(function(inAppMessages) {
  var message = inAppMessages[0];
  if (message != null) {
    var shouldDisplay = true;

    if (message instanceof appboy.ab.InAppMessage) {
      // Read the key-value pair for msg-id
      var msgId = message.extras["msg-id"];

      // If this is our push primer message
      if (msgId == "push-primer") {
        // We don't want to display the soft push prompt to users on browsers that don't support push, or if the user
        // has already granted/blocked permission
        if (!appboy.isPushSupported() || appboy.isPushPermissionGranted() || appboy.isPushBlocked()) {
          shouldDisplay = false;
        if (message.buttons[0] != null) {
          // Prompt the user when the first button is clicked
          message.buttons[0].subscribeToClickedEvent(function() {

    // Display the message
    if (shouldDisplay) {

  // Remove this message from the array of IAMs and return whatever's left
  return inAppMessages.slice(1);

When you wish to display the soft push prompt to the user, call appboy.logCustomEvent("prime-for-push") - for instance, to prompt the user on every page load just after the Braze session begins, your code would look like:

appboy.openSession(function() {

In-App Messaging

In-App Messages are great for creating unobtrusive calls to action, notifying people of new content in the News Feed and driving them toward it, or communicating with users who have push turned off. They are also effective for other content that isn’t time-sensitive enough to warrant a push notification, or permanent enough to warrant a News Feed item. You can find a detailed explanation of in-app message behavior on Braze Academy.


By default, in-app messages are automatically displayed as part of our recommended integration instructions. Additional customization can be done by following the steps in this guide.

In-App Message Types

Braze currently offers the following default in-app message types: Slideup, Modal, and Full and HTML. Each in-app message type is customizable across content, images, icons, click actions, analytics, display, and delivery.

All in-app messages inherit their prototype from appboy.ab.InAppMessage, which defines basic behavior and traits for all in-app messages. The protypical subclasses are appboy.ab.SlideUpMessage, appboy.ab.ModalMessage, appboy.ab.FullScreenMessage, and appboy.ab.HtmlMessage.

Slideup In-App Messages

SlideUp in-app messages are so-named because traditionally on mobile platforms they “slide up” or “slide down” from the top or bottom of the screen. In the Braze Web SDK, these messages are actually displayed as more of a Growl or Toast style notification, to align with the web’s dominant paradigm. They cover a small portion of the screen and provide an effective and non-intrusive messaging capability.

Slideup Example

Modal in-app messages appear in the center of the screen and are framed by a translucent panel. Useful for more critical messaging, they can be equipped with up to two click action and analytics enabled buttons.

Modal Example

Full In-App Messages

Full in-app messages are useful for maximizing the content and impact of your user communication. On narrow browser windows (e.g. the mobile web), full in-app messages take up the entire browser window. On larger browser windows, full in-app messages appear similarly to modal in-app messages. The upper half of a full in-app message contains an image and the lower half allows up to eight lines of text as well as up to two click action and analytics enabled buttons

Full Example

HTML In-App Messages

HTML in-app messages are useful for creating fully customized user content. User-defined HTML is displayed in an iframe and may contain rich content, such as images, fonts, videos, and interactive elements, allowing for full control over message appearance and functionality. These support a Javascript appboyBridge interface to call methods on the Braze Web SDK from within your HTML, see The Academy Best Practices for more details.

To enable HTML in-app messages, your SDK integration must supply the enableHtmlInAppMessages initialization option to Braze, e.g. appboy.initialize('YOUR-API_KEY', {enableHtmlInAppMessages: true}). This is for security reasons - HTML in-app messages can execute javascript so we require a site maintainer to enable them.

The following example shows a paginated HTML in-app message:

HTML5 Example

In-App Message Delivery

In-App Messages (Triggered)

The following documentation refers to Braze’s In-App Messaging product, aka “triggered in-app messages,” which are branded as highlighted below in the “Create Campaign” drop-down:

In-App Messaging Composer

You may also refer to the documentation for our deprecated Original In-App Messaging product.

Trigger Types

Our in-app message product allows you to trigger in-app message display as a result of several different event types: Any Purchase, Specific Purchase, Session Start, Custom Event, Push Click. Furthermore, Specific Purchase and Custom Event triggers can contain robust property filters.

Delivery Semantics

All in-app messages that a user is eligible for are automatically delivered to the user upon a session start event. For more information about the SDK’s session start semantics, see our session lifecycle documentation.

Minimum Time Interval Between Triggers

By default we rate limit in-app messages to once every 30 seconds to ensure a quality user experience. To override this value, you can pass the minimumIntervalBetweenTriggerActionsInSeconds configuration option to your initialize function.

// Sets the minimum time interval between triggered in-app messages to 5 seconds instead of the default 30
appboy.initialize('YOUR-API-KEY', { minimumIntervalBetweenTriggerActionsInSeconds: 5 })

Manual In-App Message Display

If you don’t want your site to immediately display new in-app messages when they’re received, you can disable automatic display and register your own display subscribers. First, find and remove the call to appboy.display.automaticallyShowNewInAppMessages() from within your loading snippet. Then, create your own subscriber:

appboy.subscribeToNewInAppMessages(function(inAppMessages) {
  // Display the first in-app message. You could defer display here by pushing this message to code within in your own application.
  // If you don't want to use Braze's built-in display capabilities, you could alternatively pass the in-app message to your own display code here.

  // Return an array with any remaining, unhandled messages to Braze's internal queue.
  // These will be part of the inAppMessages param the next time this subscriber is invoked.
  return inAppMessages.slice(1);

The inAppMessages parameter will be an array of appboy.ab.InAppMessage subclass or appboy.ab.ControlMessage objects, each of which has various lifecycle event subscription methods. See the JSDocs for full documentation.

Only one Modal or Full in-app message can be displayed at a given time. If you attempt to show a second Modal or Full message while one is already showing, appboy.display.showInAppMessage will return false, and the message will automatically be returned to Braze’s internal queue, where it will part of the inAppMessages array parameter the next time your subscriber is invoked.

Local In-App Messages

In-app messages can also be created within your site and displayed locally in real-time. All customization options available on the dashboard are also available locally. This is particularly useful for displaying messages that you wish to trigger within the app in real-time. However, analytics on these locally-created messages will not be available within the Braze dashboard.

  // Displays a slideup type in-app message.
  var message = new appboy.ab.SlideUpMessage("Welcome to Braze! This is an in-app message.");
  message.slideFrom = appboy.ab.InAppMessage.SlideFrom.TOP;

Exit-Intent Messages

Exit-intent in-app messages appear when visitors are about to navigate away from your site. They provide another opportunity to communicate important information to users, while not interrupting their experience on your site. To be able to send these messages, first reference the open-source library with the code below, which will log ‘exit intent’ as a custom event. In-app message campaigns can then be created in the dashboard using ‘exit intent’ as the trigger custom event.

  var _ouibounce = ouibounce(false, {
    callback: function() { appboy.logCustomEvent('exit intent'); }


Key-Value Pair Extras

In-app message objects may carry key-value pairs as their extras property. These are specified on the dashboard under “Additional Message Settings” when creating an in-app message campaign. These can be used to send data down along with an in-app message for further handling by your site. For example:

appboy.subscribeToNewInAppMessages(function(inAppMessages) {
  if (inAppMessages[0] instanceof appboy.ab.InAppMessage) {
    var extras = inAppMessages[0].extras;
    for (var key in extras) {
      if (data.hasOwnProperty(key)) {
         console.log("key: " + key + ", value: " + extras[key]);

  return inAppMessages.slice(1);

Custom Styling

Braze UI elements come with a default look and feel that matches the composers within the Braze Dashboard and aims for consistency with other Braze mobile platforms. Braze’s default styles are defined in CSS within the Braze SDK. By overriding selected styles in your application, it is possible to customize our standard in-app message types with your own background images, font families, styles, sizes, animations, and more. For instance, the following is an example override that will cause a in-app messages’ headers to appear italicized:

  body .ab-in-app-message .ab-message-header {
    font-style: italic;

See the JSDocs for more information.


Troubleshooting Scenarios

Expected In-App Message Did Not Display

Most in-app message issues can be broken down into two main categories: delivery and display. To troubleshoot why an expected in-app message did not display on your device, you should first ensure that the in-app message was delivered to the device, then troubleshoot message display.

Impressions Are Lower Than Expected

Triggers take time to sync to the device on session start, so there can be a race condition if users log an event or purchase right after they start a session. One potential workaround could be changing the campaign to trigger off of session start, then segmenting off of the intended event or purchase. Note that this would deliver the in-app message on the next session start after the event has occurred.

In-App Message Delivery

The SDK requests in-app messages from Braze’s servers on session start. To check if in-app messages are being delivered to your device, you’ll need to ensure that in-app messages are being both requested by the SDK and returned by Braze’s servers.

Check If Messages Are Requested and Returned

  1. Add yourself as a test user on the Dashboard.
  2. Set up an in-app message campaign targeted at your user.
  3. Ensure that a new session occurs in your application.
  4. Use the Event User Logs to check that your device is requesting in-app messages on session start. Find the SDK Request associated with your test user’s session start event.
    • If your app was meant to request triggered In-App Messages, you should see trigger in the Requested Responses field under Response Data.
    • If your app was meant to request Original In-App Messages, you should see in_app in the Requested Responses field under Response Data.
  5. Use the Event User Logs to check if the correct in-app messages are being returned in the Response Data.

In-App Message

Troubleshoot Messages Not Being Requested

If your in-app messages are not being requested, your app might not be tracking sessions correctly, as in-app messages are refreshed upon session start. Also be sure that your app is actually starting a session based on your app’s session timeout semantics:

Session Start

Troubleshoot Messages Not Being Returned

If your in-app messages are not being returned, you’re likely experiencing a campaign targeting issue:

  • Your segment does not contain your user.
    • Check your user’s Engagement tab to see if the correct segment appears under Segments.
  • Your user has previously received the in-app message and was not re-eligible to receive it again.
    • Check the campaign re-eligibility settings under the Delivery tab of the Campaign Composer and make sure the re-eligibility settings align with your testing setup.
  • Your user hit the frequency cap for the campaign.
  • If there was a control group on the campaign, your user may have fallen into the control group.
    • You can check if this has happened by creating a segment with a “Received Campaign Variant” filter, where the campaign variant is set to “Control”, and checking if your user fell into that segment.
    • When creating campaigns for integration testing purposes, make sure to opt-out of adding a control group.

In-App Message Display

If your app is successfully requesting and receiving in-app messages but they are not being shown, some device-side logic may be preventing display:

  • Triggered in-app messages are rate-limited based on the minimum time interval between triggers, which defaults to 30 seconds.
  • If you have custom in-app message handling through appboy.subscribeToNewInAppMessages, check that subscription to ensure it is not affecting in-app message display.

News Feed

The News Feed is a fully customizable in-app content feed for your users. Our targeting and segmentation allows you to create a stream of content that is individually catered to the interests of each user. Depending on their position in the user life cycle and the nature of your app, this could be an on-boarding content server, an advertisement center, an achievement center, or a generic news center.

Example News Feed

Sample News Feed

News Feed Integration

To toggle display of the News Feed through the Braze Web SDK, simply call


This will display the most recent cached News Feed cards (kicking off a refresh if these cards are more than 1 minute stale, or if the News Feed has never been refreshed) and will automatically update the display when new cards are received from Braze servers for as long as it’s on the screen.

By default, the feed will be shown in a fixed-position sidebar on the right-hand side of the website (or as a full-screen overlay on mobile devices, through responsive css). If you wish to override this behavior and display a statically positioned News Feed inside your own parent element, simply provide this element as the first argument to showFeed, for instance:


If you wish to display a specific static set of News Feed cards, filter the cards from the server, or provide your own refresh semantics, you can disable automatic updating and supply your own cards. For instance:

appboy.subscribeToFeedUpdates(function(feed) {
  var cards =;
  appboy.display.showFeed(undefined, cards);

See the JSDocs for full documentation for showFeed, destroyFeed, and toggleFeed.

News Feed Customization

Braze UI elements come with a default look and feel that matches the composers within the Braze Dashboard and aims for consistency with other Braze mobile platforms. Braze’s default styles are defined in CSS within the Braze SDK. By overriding selected styles in your application, it is possible to customize our standard feed with your own background images, font families, styles, sizes, animations, and more. For instance, the following is an example override that will cause the News Feed to appear 800px wide:

body .ab-feed {
  width: 800px;


Instances of the Braze News Feed can be configured to only receive cards from a certain “category”. This allows for effective integration of multiple News Feed streams within a single application. For more information on this feature see Braze Academy

News Feed Categories can be defined by providing the third “allowedCategories” parameter to toggleFeed:

appboy.display.toggleFeed(undefined, undefined, [appboy.ab.Card.Category.NEWS]);

You can also populate a feed with a combination of categories as in the following example:

appboy.display.toggleFeed(undefined, undefined, [appboy.ab.Card.Category.ANNOUNCEMENTS, appboy.ab.Card.Category.NEWS]);

Read/Unread Indicators

Braze provides an Unread/Read indicator on News Feed cards as pictured below:


Disabling the Indicators

In order to disable this functionality add the following style to your css:

.ab-read-dot { display: none; }
.ab-read-indicator { display: none; }

Card Types

The Braze Web SDK supports 3 unique News Feed card types, ab.ClassicCard, ab.Banner, ab.CaptionedImage which share a base model, ab.Card.

Requesting Unread Card Count

You can request the number of unread cards at any time by calling:


This is often used to power badges signifying how many unread news-feed cards there are. See the JSDocs for more information. Note that Braze will not refresh News Feed cards on new page loads (and so this function will return 0) until you show the feed or call appboy.requestFeedRefresh();

Key-Value Pairs

ab.Card objects may optionally carry key-value pairs as extras. These can be used to send data down along with a card for further handling by the application. Simply call card.extras to access these values.

See the JSDocs for ab.ClassicCard, ab.Banner, or ab.CaptionedImage for more information.


Session Tracking

The Braze SDK reports session data that is used by the Braze dashboard to calculate user engagement and other analytics integral to understanding your users. Based on the below session semantics, our SDK generates “start session” and “close session” data points that account for session length and session counts viewable within the Braze Dashboard.

Session Lifecycle

By default, sessions begin when appboy.openSession() is first called and remain open until there are at least 30 minutes of inactivity. This means that if the user navigates away from the site and then returns less than 30 minutes later, the same session will be continued. If they return after the 30 minutes have expired, a “close session” datapoint is automatically generated for the time at which they navigated away, and a new session opens.

Note: If you need to force a new session, you can do so by changing users.

Customizing Session Timeout

To customize the session timeout, pass the the sessionTimeoutInSeconds option to your initialize function.

// Sets the session timeout to 15 minutes instead of the default 30
appboy.initialize('YOUR-API-KEY-HERE', { sessionTimeoutInSeconds: 900 });

If you have set a session timeout, then the above session semantics all extend to that customized timeout.

Note: The minimum value for sessionTimeoutInSeconds is 1 second.

Testing Session Tracking

To detect sessions via your user, find your user on the dashboard and navigate to “App Usage” on the user profile. You can confirm that session tracking is working by checking that the “Sessions” metric increases when you would expect it to.


Setting User IDs

User IDs should be set for each of your users. These should be unchanging and accessible when a user opens the app. A database ID or a hashed email address/username is usually a good reference to use. We strongly recommend providing this identifier as it will allow you to:

  • Track your users across devices and platforms, improving the quality of your behaviorial and demographic data.
  • Import data about your users using our User Data API.
  • Target specific users with our Messaging API for both general and transactional messages.

If such an identifier is not available, Braze will assign a unique identifier to your users, but you will lack the capabilities above. You should avoid setting User IDs for users for whom you lack a unique identifier that is tied to them as an individual. Passing a device identifier offers no benefit versus the automatic anonymous user tracking Braze offers by default.

These User IDs should be private and not easily obtained (e.g. not a plain email address or username).

You should make the following call as soon as the user is identified (generally after logging in) in order to set the user id:


Do not call changeUser() when a user logs out. Setting changeUser() to a static default value will associate ALL user activity with that default “user” until the user logs in again. Additionally, we recommend against changing the user ID when a user logs out, as it makes you unable to target the previously logged-in user with reengagement campaigns. If you anticipate multiple users on the same device, but only want to target one of them when your app is in a logged out state, we recommend separately keeping track of the user ID you want to target while logged out and switching back to that user ID as part of your app’s logout process.

Refer to the changeUser documentation for more information.

Automatic Preservation of Anonymous User History

Identification Context Preservation Behavior
User has not been previously identified Anonymous history is merged with user profile upon identification
User has been previously identified in-app or via API Anonymous history is not merged with user profile upon identification

Additional Notes and Best Practices

Please note the following:

  • If your app is used by multiple people, you can assign each user a unique identifier to track them.
  • Once a user ID has been set, you cannot revert that user to an anonymous profile
  • Do Not change the user ID upon a user “log out”.
    • Doing so separates the device from the user profile. You will be unable to target the previously logged out user with re-engagement messages. If you anticipate multiple users on the same device, but only want to target one of them when your app is in a logged out state, we recommend separately keeping track of the user ID you want to target while logged out and switching back to that user ID as part of your app’s logout process. By default, only the last user that was logged in will receive push notifications from your app.
    • When you request the user switch, the current session for the previous user is automatically closed and a new session is started. Furthermore, Braze will automatically make a data refresh request for the News Feed, slideup and other Braze resources for the new user.

If you opt to use a hash of a unique identifier as your userID take care to ensure that you’re normalizing the input to your hashing function. For example, if you’re going to use a hash of an email address, ensure that you’re stripping leading and trailing whitespace from the input.

Aliasing Users

An alias serves as an alternative unique user identifier. Use aliases to identify users along different dimensions than your core user ID:

  • Set a consistent identifier for analytics that will follow a given user both before and after they have logged in to a mobile app or website.
  • Add the identifiers used by a third party vendor to your Braze users in order to more easily reconcile your data externally.

Each alias consists of two parts: a name for the identifier itself, and a label indicating the type of alias. Users can have multiple aliases with different labels, but only one name per label.

appboy.getUser().addAlias(ALIAS_NAME, ALIAS_LABEL);

Tracking Custom Events

You can record custom events in Braze to learn more about your app’s usage patterns and to segment your users by their actions on the dashboard.

Before implementation, be sure to review examples of the segmentation options afforded by Custom Events vs. Custom Attributes vs Purchase Events in our Best Practices section.


See the logCustomEvent documentation for more information.

Adding Properties

You can optionally add metadata about custom events by passing a properties object with your custom event.

Properties are defined as key-value pairs. Keys are strings and values can be string, numeric, boolean, or Date objects.

appboy.logCustomEvent(YOUR_EVENT_NAME, {key: 'value'});

See the logCustomEvent documentation for more information.

Setting Custom Attributes

Braze provides methods for assigning attributes to users. You’ll be able to filter and segment your users according to these attributes on the dashboard.

Before implementation, be sure to review examples of the segmentation options afforded by Custom Events vs. Custom Attributes vs Purchase Events in our Best Practices section.

To assign attributes to your users, call the appboy.getUser() method to get a reference to the current user of your app. Once you have a reference to the current user, you can call methods to set predefined or custom attributes.

Braze provides predefined methods for setting the following user attributes within the ab.User class:

  • First Name
  • Last Name
  • Biographical Strings
  • Country
  • Date of Birth
  • Email
  • Avatar Image URLs for Braze User Profiles
  • Gender
  • Home City
  • Phone Number

We strongly recommend collecting email addresses even if you’re not sending emails through Braze. Email makes it easier to search for individual user profiles and troubleshoot issues as they arise.

Implementation Examples

Setting a first name


Setting a gender


Setting a date of birth

appboy.getUser().setDateOfBirth(2000, 12, 25);

Assigning Custom User Attributes

In addition to our predefined user attribute methods, Braze also provides custom attributes to track data from your applications. Braze Custom Attributes can be set with the following data types:

  • Strings
  • Arrays
    • Includes methods to set arrays, add items to existing arrays, and delete items from existing arrays.
  • Integers
  • Booleans
  • Dates
  • Longs
  • Floats

Full method specifications for custom attributes can be found here within the ab.User class JSDocs.

Implementation Examples

Setting a Custom Attribute with a String Value


Setting a Custom Attribute with an Integer Value


// Integer attributes may also be incremented using code like the following

Setting a Custom Attribute with a Date Value


// This method will assign the current time to a custom attribute at the time the method is called
  new Date()

// This method will assign the date specified by secondsFromEpoch to a custom attribute
  new Date(secondsFromEpoch * 1000)

Dates passed to Braze with this method must be javascript Date objects.

Setting a Custom Attribute with an Array Value

The maximum number of elements in Custom Attribute Arrays defaults to 25. The maximum for individual arrays can be increased to up to 100 in the Braze Dashboard, under “Manage App Group -> Custom Attributes”. Arrays exceeding the maximum number of elements will be truncated to contain the maximum number of elements. For more information on Custom Attribute Arrays and their behavior, see our Documentation on Arrays.

appboy.getUser().setCustomUserAttribute(YOUR_ATTRIBUTE_KEY_STRING, YOUR_ARRAY_OF_STRINGS);

// Adding a new element to a custom attribute with an array value
appboy.getUser().addToCustomAttributeArray(YOUR_ATTRIBUTE_KEY_STRING, "new string");

// Removing an element from a custom attribute with an array value
appboy.getUser().removeFromCustomAttributeArray("custom_attribute_array_test", "value to be removed");

Unsetting a Custom Attribute

Custom Attributes can be unset by setting their value to null.

appboy.getUser().setCustomUserAttribute(YOUR_ATTRIBUTE_KEY_STRING, null);

Setting a Custom Attribute via the REST API

You can also use our REST API to set user attributes. To do so refer to the User API documentation.

Custom Attribute Length

Custom attribute keys and values have a maximum length of 255 characters. See the full technical documentation for complete details around valid custom attribute values.

Setting Up User Subscriptions

To set up a subscription for your users (either email or push), call the functions setEmailNotificationSubscriptionType() or setPushNotificationSubscriptionType(), respectively. Both of these functions take the enum type ‘appboy.ab.User.NotificationSubscriptionTypes’ as arguments. This type has three different states:

Subscription Status Definition
OPTED_IN Subscribed, and explicitly opted in
SUBSCRIBED Subscribed, but not explicitly opted in
UNSUBSCRIBED Unsubscribed and/or explicitly opted out

When a user is registered for push, the browser forces them to choose to allow or block notifications, and if they choose to allow push, they are set OPTED_IN by default. For more information on implementing subscriptions and explicit opt-ins, visit the topic on Braze Academy.

Sample Code

Unsubscribing a user from email:


Unsubscribing a user from push:


Logging Purchases

Record in-app purchases so that you can track your revenue over time and across revenue sources, as well as segment your users by their lifetime value.

Braze supports purchases in multiple currencies. Purchases that you report in a currency other than USD will be shown in the dashboard in USD based on the exchange rate at the date they were reported.

Before implementation, be sure to review examples of the segmentation options afforded by Custom Events vs. Custom Attributes vs Purchase Events in our Best Practices section.

To use this feature, add this method call after a successful purchase in your app:

appboy.logPurchase(productId, price, "USD", quantity);

See the JSdocs for more information. Quantity must be less than or equal to 100.

Adding Properties

You can add metadata about purchases by passing an object of key-value pairs with your purchase information. Keys are string objects and values can be string, numeric, boolean, or Date objects.

appboy.logPurchase(productId, price, "USD", quantity, {key: "value"});

See the Jsdocs for more information.


You can also use our REST API to record purchases. Refer to the User API documentation for details.

Location Tracking

To enable location tracking via the Braze Web SDK, call


This will cause the Braze Web SDK to continuously collect the user’s location (in browsers that support it), whenever your site is visible in the foreground of the user’s browser. This location collection will continue for the duration of the page load (you should call this method for each page on which you want location to be tracked). Note that calling this will immediately request permission from the user, unless they have already granted or denied permission. See the JSDocs for more information.

Logging A Single Location

To manually set a user’s last known location yourself, you can use

appboy.getUser().setLastKnownLocation(latitude, longitude, accuracy, altitude, altitudeAccuracy);

See the JSDocs for more information.

Additionally, when the Web SDK sends data to Braze servers, the user’s country will be automatically detected from their IP Address if it has not been manually set by your application.

In order to comply with data privacy regulations, data tracking activity on the Web SDK can be stopped entirely using the method stopWebTracking(). This method will sync data logged prior to when stopWebTracking() was called, and will cause all subsequent calls to the Braze Web SDK for this page and future page loads to be ignored. If you wish to resume data collection at a later point in time, you can use the resumeWebTracking() method in the future to resume data collection.

If you wish to provide users with the option to stop tracking, we recommend building a simple page with two links or buttons, one that calls stopWebTracking() when clicked, and another that calls resumeWebTracking() to allow users to opt back in. You can use these controls to start or stop tracking via other data sub-processors as well.

Note that the Braze SDK does not need to be initialized in order to call stopWebTracking(), allowing you to disable tracking for fully anonymous users.

Amp Support

This section is NOT a necessary integration step unless you’re trying to integrate Braze on an AMP page.

Accelerated Mobile Pages (AMP) is a Google backed project designed to improve page load time on mobile devices by enforcing certain standards, including restricting the usage of JavaScript.

As a result, the Braze SDK cannot be loaded onto an AMP page. However, the AMP project does provide a component that supports web push. The following instructions detail how to setup that component and reference the following documentation on the amp-web-push component:

Step 1: Include AMP Web Push Script

Add the following async script tag to your head:

<script async custom-element="amp-web-push" src=""></script>

Step 2: Add Subscription / Unsubscription Widget

You’ll need to add a widget that allows users to subscribe and unsubscribe from push. This should live inside the body of your HTML and can be styled however you see fit.

<!-- A subscription widget -->
<amp-web-push-widget visibility="unsubscribed" layout="fixed" width="250" height="80">
  <button on="tap:amp-web-push.subscribe">Subscribe to Notifications</button>

<!-- An unsubscription widget -->
<amp-web-push-widget visibility="subscribed" layout="fixed" width="250" height="80">
  <button on="tap:amp-web-push.unsubscribe">Unsubscribe from Notifications</button>

Step 3: Download Helper IFrame & Permission Dialog

The AMP Web Push component works by creating a popup that handles the push subscription. As a result, you’ll need to include a couple of helper files into your project. Download the helper-iframe.html file and permission-dialog.html file and store them on your site.

Step 4: Create Service Worker File

Create a service-worker.js file with the content below, and place it in the root directory of your website:

Step 5: Configure AMP Web Push HTML Element

You’ll now need to add the amp-web-push html element to your page. Drop the following HTML code into the body of your document:


In particular, the service-worker-url requires appending your apiKey and baseUrl (if you don’t have a custom endpoint use the default: as query parameters, as shown above.

You should now be configured for push subscription and unsubscription on your AMP page.