Skip to content

Merge users

post

/users/merge

Use this endpoint to merge one user into another user.

Up to 50 merges may be specified per request. This endpoint is asynchronous.

Prerequisites

To use this endpoint, you’ll need an API key with the users.merge permission.

Rate limit

For customers who onboarded with Braze on or after September 16, 2021, we apply a shared rate limit of 20,000 requests per minute to this endpoint. This rate limit is shared with the /users/delete, /users/alias/new, /users/identify, and /users/alias/update endpoints, as documented in API rate limits.

Request body

1
2
Content-Type: application/json
Authorization: Bearer YOUR_REST_API_KEY
1
2
3
{
  "merge_updates" : (required, array of objects)
}

Request parameters

Parameter Required Data Type Description
merge_updates Required Array An object array. Each object should contain an identifier_to_merge object and an identifier_to_keep object, which should each reference a user either by external_id, user_alias or email. Both users (original user and target user) being merged must be identified using the same method.

Merge behavior

The behavior documented below is true for all Braze features that are not powered by Snowflake. User merges won’t be reflected for the Messaging History tab, Segment Extensions, Query Builder, and Currents.

This endpoint will merge any of the following fields if they are not found on the target user:

  • First name
  • Last name
  • Email
  • Gender
  • Date of birth
  • Phone number
  • Time zone
  • Home city
  • Country
  • Language
  • Session count (the sum of sessions from both profiles)
  • Date of first session (Braze will pick the earlier date of the two dates)
  • Date of last session (Braze will pick the later date of the two dates)
  • Custom attributes (existing custom attributes on the target profile are retained and will include custom attributes that didn’t exist on the target profile)
  • Custom event and purchase event data
  • Custom event and purchase event properties for “X times in Y days” segmentation (where X<=50 and Y<=30)
  • Segmentable custom events summary
    • Event count (the sum from both profiles)
    • Event first occurred (Braze will pick the earlier date of the two dates)
    • Event last occurred (Braze will pick the later date of the two dates)
  • In-app purchase total in cents (the sum from both profiles)
  • Total number of purchases (the sum from both profiles)
  • Date of first purchase (Braze will pick the earlier date of the two dates)
  • Date of last purchase (Braze will pick the later date of the two dates)
  • App summaries
  • Last_X_at fields (Braze will update the fields if the orphaned profile fields are more recent)
  • Campaign interaction data (Braze will pick the most recent date fields)
  • Workflow summaries (Braze will pick the most recent date fields)
  • Message and message engagement history

Session data will only be merged if the app exists on both user profiles. Note that this endpoint does not merge subscription groups or subscriptions.

Custom event date and purchase event date behavior

Note that these merged fields will update “for X events in Y days” filters. For purchase events, these filters include “number of purchases in Y days” and “money spent in last Y days”.

Merging users by email

If an email is specified as an identifier, an additional prioritization value is required in the identifier. The prioritization should be an array specifying which user to merge if there are multiple users found. prioritization is an ordered array, meaning if more than one user matches from a prioritization, then merging will not occur.

The allowed values for the array are: identified, unidentified, most_recently_updated. most_recently_updated refers to prioritizing the most recently updated user.

Only one of the following options may exist in the prioritization array at a time:

  • identified refers to prioritizing a user with an external_id
  • unidentified refers to prioritizing a user without an external_id

Example requests

Basic request

This is a basic request body to show the pattern of the request.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
curl --location --request POST 'https://rest.iad-01.braze.com/users/merge' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_REST_API_KEY' \
--data-raw '{
{
  "merge_updates": [
    {
      "identifier_to_merge": {
        "external_id": "old-user1"
      },
      "identifier_to_keep": {
        "external_id": "current-user1"
      }
    },
    {
      "identifier_to_merge": {
        "email": "[email protected]"
      },
      "identifier_to_keep": {
        "email": "[email protected]"
      }
    },
    {
      "identifier_to_merge": {
        "user_alias": {
          "alias_name": "[email protected]",
          "alias_label": "email"
        }
      },
      "identifier_to_keep": {
        "user_alias": {
          "alias_name": "[email protected]",
          "alias_label": "email"
        }
      }
    }
  ]
}'

Merging unidentified user

The following request would merge the most recently updated unidentified user with email address “[email protected]” into the user with external_id “john”. Using most_recently_updated filters the query to just one unidentified user. So, if there were two unidentified users with this email address, only one would get merged into the user with external_id “john”.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
curl --location --request POST 'https://rest.iad-01.braze.com/users/merge' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_REST_API_KEY' \
--data-raw '{
{
  "merge_updates": [
    {
      "identifier_to_merge": {
        "email": "[email protected]",
        "prioritization": ["unidentified", "most_recently_updated"]
      },
      "identifier_to_keep": {
        "external_id": "john"
      }
    }
  ]
}'

Merging unidentified user into identified user

This next example merges the most recently updated unidentified user with email address “[email protected]” into the most recently updated identified user with email address “[email protected]”. Using most_recently_updated filters the queries to just one user (one unidentified user for identifier_to_merge, and one identified user for the identifier_to_keep).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
curl --location --request POST 'https://rest.iad-01.braze.com/users/merge' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_REST_API_KEY' \
--data-raw '{
{
  "merge_updates": [
    {
      "identifier_to_merge": {
        "email": "[email protected]",
        "prioritization": ["unidentified", "most_recently_updated"]
      },
      "identifier_to_keep": {
        "email": "[email protected]",
        "prioritization": ["identified", "most_recently_updated"]
      }
    }
  ]
}'

Merging an unidentified user without including the most_recently_updated prioritization

If there are two unidentified users with email address “[email protected]”, this example request doesn’t merge any users since there are two unidentified users with that email address. This request only works if there is only one unidentified user with email address “[email protected]”.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
curl --location --request POST 'https://rest.iad-01.braze.com/users/merge' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_REST_API_KEY' \
--data-raw '{
{
  "merge_updates": [
    {
      "identifier_to_merge": {
        "email": "[email protected]",
        "prioritization": ["unidentified"]
      },
      "identifier_to_keep": {
        "external_id": "john"
      }
    }
  ]
}'

Response

There are two status code responses for this endpoint: 202 and 400.

Example success response

The status code 202 could return the following response body.

1
2
3
{
  "message": "success"
}

Example error response

The status code 400 could return the following response body. Refer to Troubleshooting for more information about errors you may encounter.

1
2
3
{
  "message": "'merge_updates' must be an array of objects"
}

Troubleshooting

The following table lists possible error messages that may occur.

Error Troubleshooting
'merge_updates' must be an array of objects Check that merge_updates is an array of objects.
a single request may not contain more than 50 merge updates You can only specify up to 50 merge updates in a single request.
identifiers must be objects with an 'external_id' property that is a string, or 'user_alias' property that is an object Check the identifiers in your request.
identifiers must be objects of the same type Check that the identifier object types match.
'merge_updates' must only have 'identifier_to_merge' and 'identifier_to_keep' Check that merge_updates only contains the two objects identifier_to_merge and identifier_to_keep.
HOW HELPFUL WAS THIS PAGE?
New Stuff!