# Braze Cloud Mode Integration


After you have successfully instrumented Braze as a destination in RudderStack, follow this guide to correctly send your events to Braze in [cloud mode]({{< ref "/destinations/rudderstack-connection-modes.md#cloud-mode" >}}).

Find the open source transformer code for this destination in the [GitHub repository](https://github.com/rudderlabs/rudder-transformer/tree/main/src/v0/destinations/braze).

{{< warning >}}
**Braze `/users/track` partial failures**

In cloud mode, when Braze returns item-level errors for individual events in an otherwise successful `/users/track` response, RudderStack marks the affected events as failed with a `400` status. 

Review the Braze error message in [Destination Live Events]({{< ref "monitor/live-events.md#destination-live-events" >}}) and update the event payload before retrying.
{{< /warning >}}

## Batching for Monthly Active Users (MAU) plans

Braze's [Monthly Active Users (MAU) pricing plans](https://www.braze.com/docs/api/endpoints/user_data/post_user_track#monthly-active-users-cy-24-25-universal-mau-web-mau-and-mobile-mau) set rate limits on the `/users/track` endpoint based on each account's historical data ingestion activity. 

To align with these rate limits, RudderStack has updated its batching implementation for the cloud mode integration — the batch size for [`identify`]({{< ref "event-spec/standard-events/identify.md" >}}) and [`track`]({{< ref "event-spec/standard-events/track.md" >}}) events has been reduced from 225 events per batch to **75 events per batch**. This adjustment ensures the API rate limits are optimally respected, minimizing latency and maximizing throughput. 

{{< info >}}
Accounts not on the MAU plans will continue to have a batch limit of **225 events**.
{{< /info >}}

You can review your current limits in the Braze dashboard under **Settings** > **APIs and Identifiers** > **API Usage Dashboard**.

See [Monthly Active Users (MAU) pricing plans](https://www.braze.com/docs/api/endpoints/user_data/post_user_track#monthly-active-users-cy-24-25-universal-mau-web-mau-and-mobile-mau) for more information on the hourly limits, burst limits, and rate limit response headers for these plans.

## Identify

You can use the [`identify`]({{< ref "event-spec/standard-events/identify.md" >}}) call to identify a user in Braze in any of the below cases:

- When the user registers to the app for the first time.
- When they log into their app.
- When they update their information.

A sample `identify` call is shown below:

```javascript
rudderanalytics.identify("1hKOmRA4GRlm", {
  email: "alex@example.com",
  name: "Alex Keener"
});
```

### Set a custom user ID (`externalId`)

You can use the `externalId` field within your `identify` event to explicitly set a custom user ID in Braze.

{{< info >}}
Note that:

- Braze gives first preference to the `externalId` field in the `identify` event to identify the user. If `externalId` is absent, it falls back to the `userId` field.
- RudderStack recommends sending the `identify` event containing the `externalId` object before sending any subsequent `track` events, so that it can persist the `externalId` information successfully.
{{< /info >}}

The following snippet shows how to add an `externalId` to your `identify` event using the [JavaScript SDK]({{< ref "sources/event-streams/sdks/rudderstack-javascript-sdk/" >}}), before sending it to Braze:

```javascript
rudderanalytics.identify(
  "1hKOmRA4GRlm", {
    firstName: "Alex",
    city: "New Orleans",
    country: "USA",
    phone: "+1-202-555-0146",
    email: "alex@example.com",
    favorite_flavor: "chocolate",
    externalId: [{
      id: "12323412432432",
      type: "brazeExternalId",
    }],
  }
);
```

### Delete a user

You can delete a user in Braze using the [Suppression with Delete regulation]({{< ref "api/user-suppression-api/_index.md#adding-a-suppression-with-delete-regulation" >}}) of the RudderStack [User Suppression API]({{< ref "api/user-suppression-api/_index.md" >}}).

{{< warning >}}
While RudderStack forwards the deletion request, it **does not guarantee** deletion within a 30-day window. You will need to check with Braze if the request is fulfilled.
{{< /warning>}}

To delete a user:

- Use a [REST API key]({{< ref "destinations/streaming-destinations/braze/setup-guide.md#connection-settings" >}}) containing the [`users.delete` permission](https://www.braze.com/docs/api/basics#rest-api-key-permissions) for setting up the Braze destination in RudderStack.
- Specify the `userId` in the event. You can also specify a custom identifier (optional) in the event.

A sample regulation request body for deleting a user in Braze is shown below:

```json
{
  "regulationType": "suppress_with_delete",
  "destinationIds": ["2FIKkByqn37FhzczP23eZmURciA"],
  "users": [
    {
      "userId": "1hKOmRA4GRlm",
      "<customKey>": "<customValue>"
    }
  ]
}
```

### Send user traits as nested custom attributes

You can send the user traits to Braze as [nested custom attributes](https://www.braze.com/docs/user_guide/data_and_analytics/custom_data/custom_attributes/nested_custom_attribute_support/) and perform add, update, and remove operations on them. To do so, turn on the [Use Custom Attributes Operation]({{< ref "destinations/streaming-destinations/braze/setup-guide.md#event-settings" >}}) dashboard setting while setting up the Braze destination.

You can send the user traits as nested custom attributes in your `identify` events in the following format:

```javascript
rudderanalytics.identify("1hKOmRA4GRlm", {
  cars: {
    add: [{
      age: 27,
      id: 1,
      name: "Alex Keener"
    }],
    update: [{
        age: 30,
        id: 2,
        identifier: "id",
        name: "Alice"
      },
      {
        age: 27,
        id: 1,
        identifier: "id",
        name: "John"
      }
    ]
  },
  pets: [{
      breed: "Golden Retriever",
      id: 1,
      name: "Scooby",
      type: "Dog"
    },
    {
      breed: "German Shepherd",
      id: 2,
      name: "Milo",
      type: "Dog"
    }
  ]
  country: "USA",
  email: "alex@example.com",
  firstName: "Alex",
  gender: "M",
  properties: {
    mergeObjectsUpdateOperation: true
  }
});
```

To deep merge the updated custom attributes with the existing attributes, set `mergeObjectsUpdateOperation` to `true` within the event's `properties` object, as seen above.

You can also set the user traits as custom user attributes in the `track`, `page`, or `screen` events by pass `traits` as a contextual field in the event, as shown:

```javascript
rudderanalytics.track(
  "Product Viewed", {
    revenue: 8.99,
    currency: "USD"
  }, {
    traits: {
      cars: {
        add: [{
          age: 27,
          id: 1,
          name: "Alex Keener"
        }],
        update: [{
            age: 30,
            id: 2,
            identifier: "id",
            name: "Mike"
          },
          {
            age: 27,
            id: 1,
            identifier: "id",
            name: "Rowan"
          }
        ]
      },
      city: "Disney",
      country: "USA",
      email: "alexa@example.com",
      firstName: "Alexa",
      gender: "woman",
      pets: [{
          breed: "beagle",
          id: 1,
          name: "Scooby",
          type: "dog"
        },
        {
          breed: "calico",
          id: 2,
          name: "Garfield",
          type: "cat"
        }
      ]
    }
  }
);
```
{{< info >}}
Note that:

- `identifier` is a required key for the `update` and `remove` operations.
- RudderStack uses the `create` operation to create the properties if `add`, `update`, or `remove` operations are not present in the nested array.
{{< /info >}}

See the [Braze documentation](https://www.braze.com/docs/user_guide/data_and_analytics/custom_data/custom_attributes/nested_custom_attribute_support/) for more information on sending nested custom attributes to Braze.

## Track

The [`track`]({{< ref "event-spec/standard-events/track.md" >}}) call lets you record the customer events, that is, the actions that they perform, along with any properties associated with them.

A sample `track` call is shown below:

```javascript
rudderanalytics.track("Product Added", {
  numberOfRatings: "12",
  name: "item 1"
});
```

### Order Completed

When [Enable ecommerce recommended events]({{< ref "destinations/streaming-destinations/braze/setup-guide.md#event-settings" >}}) is toggled, RudderStack maps `Order Completed` to a single `ecommerce.order_placed` custom event instead of Braze purchases. See [Braze Recommended Ecommerce Events]({{< ref "destinations/streaming-destinations/braze/recommended-ecommerce-events.md" >}}).

When the setting is toggled off, RudderStack sends the product information present in the event to Braze as **purchases**.

A sample `Order Completed` event is shown below:

```javascript
rudderanalytics.track("Order Completed", {
  userId: "1hKOmRA4GRlm",
  currency: "USD",
  products: [
    {
      product_id: "123454387",
      name: "Game",
      price: 15.99
    }
  ]
});
```

## Page

The [`page`]({{< ref "event-spec/standard-events/page.md" >}}) call allows you to record your website's page views, with the additional relevant information about the viewed page.

A sample `page` call is as shown below:

```javascript
rudderanalytics.page("Cart", "Cart Viewed", {
  path: "/cart",
  referrer: "test.com",
  search: "term",
  title: "test_item",
  url: "http://test.in"
});
```

## Screen

The [`screen`]({{< ref "event-spec/standard-events/screen.md" >}}) call lets you record your users' mobile screen views with any additional information about the viewed screen.

A sample `screen` call is shown below:

```objectivec
[[RSClient sharedInstance] screen:@"Main"
                properties:@{@"prop_key" : @"prop_value"}];
```

## Group

You can use the [`group`]({{< ref "event-spec/standard-events/group.md" >}}) event to link an identified user with a group, such as a company, organization, or an account.

```javascript
rudderanalytics.group("12345", {
  name: "MyGroup",
  industry: "IT",
  employees: 450,
  plan: "basic"
});
```

Note that once you send a `group` event, RudderStack sends a custom attribute to Braze with the name as `ab_rudder_group_<groupId>` and the value as `true`. 

For example, if the `groupId` is `12345`, then RudderStack creates a custom attribute with the name `ab_rudder_group_12345` and sends it to Braze with its value to `true`.

### Subscription group status

To update the subscription group status, enable the [Enable subscription groups in group call]({{< ref "destinations/streaming-destinations/braze/setup-guide.md#event-settings" >}}) dashboard setting and send the [subscription group](https://www.braze.com/docs/api/endpoints/subscription_groups) status in the `group` call:

```javascript
rudderanalytics.group("12345", {
  subscriptionState: "subscribed",
  email: "alex@example.com"
});
```

{{< warning >}}
Either `email` or `phone` is mandatory to send the subscription group in a `group` call.
{{< /warning >}}

## Alias

You can use the [`alias`]({{< ref "event-spec/standard-events/alias.md" >}}) event to merge different identities of a known user.

A sample `alias` call is shown below:

```javascript
rudderanalytics.alias("newUserId", "previousUserId");
```

When you send the above event, RudderStack removes the user with `previousUserId` from Braze and merges all the associated fields with the user having `newUserId`.

## Delta management for `identify` and `track` calls

You can save costs by deduplicating the data sent to Braze via `identify` and `track` calls. To do so, enable the [Deduplicate Traits]({{< ref "destinations/streaming-destinations/braze/setup-guide.md#deduplication-settings" >}}) dashboard setting. RudderStack then sends only the changed or modified attributes (traits) to Braze.

{{< info >}}
RudderStack recommends reviewing Braze's [data points policy](https://www.braze.com/docs/user_guide/onboarding_with_braze/data_points/) to fully understand how this functionality can help you avoid data overages.
{{< /info >}}

