> ## Documentation Index
> Fetch the complete documentation index at: https://moengage-sdk-docs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Merge Users

> The Merge User API merges two users in MoEngage based on their ID. ID is a client-defined identifier for a user. This API can be used when multiple profiles have been created for a single user. For example, a user registered once with a mobile number and once with an email id can be merged. Duplicate users created due to integration or tech issues can also be merged.

**Types of user merging in MoEngage**

* Default or normal merge
  * MoEngage merges users with the same ID
  * Happens automatically, and no action is required from your side.
* Manual merge
  * MoEngage merges users having different IDs
  * Does not happen automatically; the Merge User API needs to be called with the list of users to be merged along with their IDs.

<Warning>
  - User Merging is a complex functionality and, if misused, can lead to data integrity issues. If the data passed to the API is incorrect, resulting in a merge of two unintended users, MoEngage will not be able to recover/rectify the data. The retained user would have erroneous data, and segmentation queries would not provide the right results.
  - MoEngage does not support transitive/canonical merging. For example, if user A is merged to B (A ->B) and then user B is merged to C (B ->C), in this scenario, events of user A are not moved to user C.
  - The Merge User API is not functional in workspaces where the [Identity Resolution](https://help.moengage.com/hc/en-us/articles/24050999467284-Unified-Identity-Identity-Resolution) feature is enabled.
  - If you are updating the [Unique Identifier](https://developers.moengage.com/hc/en-us/articles/4404440336148-Tracking-User-Attributes) for a user, use the User Merge API at least 2 hours after you have updated the Unique Identifier.
  - Ensure that the data passed to the API is accurate. We recommend you test the merging starting with a small batch of users, such as 1, 5, 10, 20, 50, etc. Verify the merged data and users before proceeding with a bulk update.
</Warning>

**Terms to Know**

* **Retained User**- This is the user that is retained in the system. The merged user’s attributes and associated devices are mapped to the retained user post-merge. Reachability calculation is done for the retained user based on the devices. All of the user attributes of the merged user are moved to the retained user. If an attribute is present for the retained user and the same attribute is not for the merged user, the attribute is retained for the retained user.
* **Merged user**- All the data of this user will merge into the retained user. Merged users will be deleted after 30 days of inactivity. If MoEngage receives any event or user property for the merged user after the merging activity, the merged user will not be deleted. The following happens in MoEngage post-user merging:
  * In the user profile, all events of the last 30 days are moved from the merged user to the retained user.
  * Segmentation and campaign have moved all of the data from merged user to retained user.

**Rate limit**

The rate limit is 1000 user updates per minute.

**Postman Collections**

We have made it easy for you to test the APIs. Click [here](https://www.postman.com/moengage-dev/api-docs/collection/3182294-3c80e7c5-32a1-4279-b1bb-566c7d4c5588?action=share\&creator=3182294) to view it in Postman.

**FAQs**

* **Will the merged user information be available after using this API?**

No, the merged user will get deleted after calling this API. All the user attributes and devices of the merged user will be transferred to the retained user.

* **What will happen to the reachability of the retained user?**

The reachability status of the user will be recalculated based on the devices present after merging the user.

* **Can any two users be merged?**

Any registered user present in the MoEngage system can be merged with another registered user irrespective of the source of creation.

* **Should both users have a device attached to them before merging?**

Not necessarily; we allow the merging of users with or without devices.

* **Is there any restriction on the number of times a user can be merged?**

No.

* **Is there any restriction on the number of devices a merged/retained should have?**

No.

* **What happens to the `merged_user` after the merge?**

This user will get deleted, and if any devices are attached to this user, they will be associated with the `retained_user`, and all the events and user details of `merged_user` will reflect on the `retained_user`. A merge event `MOE_USER_MERGE_EVENT` will be added to the `merged_user` (who will only have the MoEngage ID now).

* **What happens to `retained_user` after the merge?**

The `retained_user` will now have all the user, device, and event details of `merged_user` along with details of `retained_user`, `MOE_USER_MERGED` will be added to `retained_user`.

* **What happens if a user creation request comes with the same `ID` as the deleted user (which is deleted after the merge)?**

  We will create a new user with that `ID`, but the MoEngage `ID` of this user will be different as compared to the deleted user.

  * **What happens to the reachability if both users do not have devices?**

The user will not be reachable.

* **What is the SLA to see user details reflect after the merge?**

The maximum SLA is 30 minutes.

* **How are events copied from the merged user to the retained user?**

In the user profile, all events of the last 30 days are moved from the merged user to the retained user.


## OpenAPI

````yaml /api/data/data.yaml post /customer/merge
openapi: 3.0.3
info:
  title: MoEngage Data APIs
  version: '1.0'
  description: >-
    This is a comprehensive OpenAPI specification for MoEngage's Data APIs,
    including User, Event, and Device management.

    It's designed to power an interactive API playground on your new
    documentation site.
servers:
  - url: https://api-0{dc}.moengage.com/v1
    description: MoEngage Core API Server
    variables:
      dc:
        default: '1'
        description: >-
          The ‘dc’ in the API Endpoint URL refers to the MoEngage Data Center
          (DC). MoEngage hosts each customer in a different DC. You can find
          your DC number and replace the value of ‘dc’ in the URL by referring
          to the DC and API endpoint mapping
          [here](https://help.moengage.com/hc/en-us/articles/360057030512-Data-Centers-in-MoEngage).
          Your MoEngage Data Center (DC) can be 1, 2, 3, 4,5, 6. 
        enum:
          - '1'
          - '2'
          - '3'
          - '4'
          - '5'
          - '6'
security:
  - Authentication: []
tags:
  - name: User
    description: Operations for creating, updating, retrieving, and managing user profiles.
  - name: Event
    description: Operations for tracking user events.
  - name: Device
    description: Operations for managing user devices.
  - name: Tracking
    description: Endpoints for tracking attribution and installs.
  - name: Utilities
    description: Utility endpoints for testing connections.
  - name: File Imports
    description: Operations for managing asynchronous file imports.
  - name: Bulk
    description: Operations for importing users and events in bulk.
  - name: Webhooks
    description: Incoming webhook specifications from MoEngage.
paths:
  /customer/merge:
    post:
      tags:
        - User
      summary: Merge Users
      description: >-
        The Merge User API merges two users in MoEngage based on their ID. ID is
        a client-defined identifier for a user. This API can be used when
        multiple profiles have been created for a single user. For example, a
        user registered once with a mobile number and once with an email id can
        be merged. Duplicate users created due to integration or tech issues can
        also be merged.
      parameters:
        - name: app_id
          in: query
          required: true
          description: >-
            This is the Workspace ID of your MoEngage account that has to be
            passed along with the request. You can find your Workspace ID at
            Settings > Account > APIs > Workspace ID.
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MergeUserRequest'
      responses:
        '200':
          description: >-
            This response is returned when the request is processed
            successfully.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    description: >-
                      This field contains the status of the request and
                      specifies whether the request was successful. Supported
                      values are : "success", "failure"
                    example: success
                  operation:
                    type: string
                    description: >-
                      This field contains “created” when there is no error in
                      the payload, and the user merge is successful.
                    example: created
              examples:
                success_response:
                  summary: Successful request
                  value:
                    status: success
                    operation: created
        '400':
          description: >-
            This response is returned when the required parameters are missing
            from the request or when the provided parameters are invalid.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    description: >-
                      This field contains the status of the request and
                      specifies whether the request was a failure.
                    example: fail
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        description: >-
                          A descriptive error message explaining why the request
                          failed.
                      type:
                        type: string
                        description: >-
                          The type or category of the error (e.g., Malformed
                          JSON).
                      request_id:
                        type: string
                        description: >-
                          A unique identifier for the request, useful for
                          debugging.
              examples:
                malformed_json:
                  summary: Malformed JSON request
                  value:
                    status: fail
                    error:
                      message: >-
                        Could not decode the request body. The JSON was
                        incorrect or not   encoded as UTF-8.
                      type: Malformed JSON
                      request_id: pIvbWnGT
                app_blacklisted:
                  summary: App blacklisted by MoEngage
                  value:
                    status: fail
                    error:
                      message: Your account is blacklisted, Please contact MoEngage.
                      type: Blacklisted
                      request_id: pIvbWnGT
                invalid_workspaceid:
                  summary: Invalid Workspace ID in request parameter
                  value:
                    status: fail
                    error:
                      message: given app_id is invalid/blocked
                      type: InvalidParams
                      request_id: pIvbWnGT
                missing_workspaceid:
                  summary: Workspace ID not present in the Request Parameter
                  value:
                    status: fail
                    error:
                      message: app_id is required in path/query params.
                      type: ParamsRequired
                      request_id: pIvbWnGT
                invalid_payload:
                  summary: Workspace ID not present in the Request Parameter
                  value:
                    status: fail
                    error:
                      message: A valid JSON document is required.
                      type: Body type is not JSON
                      request_id: pIvbWnGT
                empty_request:
                  summary: Empty request body
                  value:
                    status: fail
                    error:
                      message: A valid JSON document is required.
                      type: Body type is not JSON
                      request_id: pIvbWnGT
                invalid_datatype:
                  summary: Invalid datatype
                  value:
                    status: fail
                    error:
                      attribute: merged_user
                      message: merged_user is expected to be String or Unicode String.
                      type: MissingAttributeError
                      request_id: dBSEscwl
                missing_contenttype:
                  summary: Content type header is missing in the request
                  value:
                    status: fail
                    error:
                      message: The Content-Type Header is required.
                      type: Missing header value
                      request_id: pIvbWnGT
                suspended_account:
                  summary: Suspended MoEngage account used in the request
                  value:
                    status: fail
                    error:
                      message: Account Suspended.
                      type: Account Suspended
                      request_id: pIvbWnGT
        '401':
          description: >-
            This response is returned when the authorization fails due to
            incorrect values for the APP KEY/ HTTP Auth Header.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    description: >-
                      This field contains the status of the request and
                      specifies whether the request was a failure.
                    example: fail
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        description: >-
                          A descriptive error message explaining why the request
                          failed.
                      type:
                        type: string
                        description: >-
                          The type or category of the error (e.g.,
                          Authentication required).
                      request_id:
                        type: string
                        description: >-
                          A unique identifier for the request, useful for
                          debugging.
              examples:
                incorrect_header:
                  summary: Incorrect values for the APP KEY/ HTTP Auth Header
                  value:
                    status: fail
                    error:
                      message: >-
                        MOE_APPKEY doesn't match the Username (APP_KEY) used in
                        Basic Auth authorization.
                      type: Authentication required
                      request_id: pIvbWnGT
                missing_header:
                  summary: Missing APP KEY in HTTP Auth Header
                  value:
                    status: fail
                    error:
                      message: MOE-APPKEY is missing in Header
                      type: Authentication required
                      request_id: pIvbWnGT
                missing_appsecret:
                  summary: Missing APP SECRET in HTTP Auth Header
                  value:
                    status: fail
                    error:
                      message: MOE-APPKEY is missing in Header
                      type: Authentication required
                      request_id: pIvbWnGT
                missing_username:
                  summary: Username is not provided in the Auth header
                  value:
                    status: fail
                    error:
                      message: >-
                        Username (APP_KEY) is missing in the Basic Auth
                        authorization.
                      type: Authentication required
                      request_id: pIvbWnGT
                missing_password:
                  summary: Password  is not provided in the Auth header
                  value:
                    status: fail
                    error:
                      message: >-
                        Password (APP_SECRET) is missing in the Basic Auth
                        authorization.
                      type: Authentication required
                      request_id: pIvbWnGT
                invalid_auth:
                  summary: Other authorization type is used instead of Basic Auth
                  value:
                    status: fail
                    error:
                      message: >-
                        Invalid authorization used. MoEngage only supports
                        'Basic Auth' authorization.
                      type: Authentication required
                      request_id: pIvbWnGT
                missing_authdetails:
                  summary: Authorization details are missing in the header
                  value:
                    status: fail
                    error:
                      message: Authorization details are missing
                      type: Authentication required
                      request_id: pIvbWnGT
                invalid_appkey:
                  summary: Invalid APP Secret key in Authorization Header
                  value:
                    status: fail
                    error:
                      message: >-
                        App Secret key mismatch. Please login to the dashboard
                        to verify key
                      type: Authentication required
                      request_id: JooAzchF
                incorrect_appkey:
                  summary: Incorrect APP KEY
                  value:
                    status: fail
                    error:
                      message: >-
                        Password (APP_KEY) doesn't match the one available on
                        the dashboard. Kindly ensure the same APP_KEY available
                        on the dashboard is used.
                      type: Authentication required
                      request_id: pIvbWnGT
        '403':
          description: >-
            This response is returned when the user account that is being merged
            has been suspended temporarily.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    description: >-
                      This field contains the status of the request and
                      specifies whether the request was a failure.
                    example: fail
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        description: >-
                          A descriptive error message explaining why the request
                          failed.(e.g., Your account is suspended. Please
                          contact MoEngage team.)
                      type:
                        type: string
                        description: >-
                          The type or category of the error (e.g., Account
                          Temporarily Suspended).
                      request_id:
                        type: string
                        description: >-
                          A unique identifier for the request, useful for
                          debugging.
              examples:
                account_suspension:
                  summary: Temporary account suspension
                  value:
                    status: fail
                    error:
                      message: Account Temporarily Suspended.
                      type: Account Temporarily Suspended.
                      request_id: pIvbWnGT
        '409':
          description: >-
            This response is returned when the authorization fails due to the
            APP SECRET key not being set on the Dashboard.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    description: >-
                      This field contains the status of the request and
                      specifies whether the request was a failure.
                    example: fail
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        description: >-
                          A descriptive error message explaining why the request
                          failed.
                      type:
                        type: string
                        description: >-
                          The type or category of the error (e.g.,
                          Authentication required).
                      request_id:
                        type: string
                        description: >-
                          A unique identifier for the request, useful for
                          debugging.
              examples:
                authorization_errors:
                  summary: >-
                    Authorization errors due to APP SECRET not being set in the
                    Dashboard
                  value:
                    status: fail
                    error:
                      message: >-
                        App Secret key is not set. Please login to the dashboard
                        to set a key.
                      type: Authentication required.
                      request_id: pIvbWnGT
                appkey_mismatch:
                  summary: >-
                    Mismatch in the app id sent in the request parameter and the
                    authorization header
                  value:
                    status: fail
                    error:
                      message: App key mismatch in params and authentication.
                      type: Authentication required.
                      request_id: WNqwxfwM
        '413':
          description: >-
            TThis response is returned when the payload size has exceeded the
            limit set.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    description: >-
                      This field contains the status of the request and
                      specifies whether the request was a failure.
                    example: fail
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        description: >-
                          A descriptive error message explaining why the request
                          failed.
                      type:
                        type: string
                        description: >-
                          The type or category of the error (e.g., Payload too
                          large).
                      request_id:
                        type: string
                        description: >-
                          A unique identifier for the request, useful for
                          debugging.
              examples:
                payload_exceeded:
                  summary: Request Payload Size Exceeded
                  value:
                    status: fail
                    error:
                      message: The payload can not exceed 128KB
                      type: PayloadTooLarge
                      request_id: VFzDwhwt
        '415':
          description: >-
            This response is returned when the header “Content-Type” is not
            provided/is not supported.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    description: >-
                      This field contains the status of the request and
                      specifies whether the request was a failure.
                    example: fail
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        description: >-
                          A descriptive error message explaining why the request
                          failed.
                      type:
                        type: string
                        description: >-
                          The type or category of the error (e.g., Unsupported
                          media type).
                      request_id:
                        type: string
                        description: >-
                          A unique identifier for the request, useful for
                          debugging.
              examples:
                unsupported_media_type:
                  summary: Unsupported Media Type
                  value:
                    status: fail
                    error:
                      message: >-
                        The header 'Content-Type' is missing. Kindly provide the
                        header 'Content-Type' and set it as 'application/json'
                      type: MediaTypeError
                      request_id: SgBQfKJh
        '429':
          description: >-
            This response is returned when the number of requests per minute has
            exceeded the rate limit.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    description: >-
                      This field contains the status of the request and
                      specifies whether the request was a failure.
                    example: fail
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        description: >-
                          A descriptive error message explaining why the request
                          failed.
                      type:
                        type: string
                        description: >-
                          The type or category of the error (e.g., Rate Limits
                          Exceeded).
                      request_id:
                        type: string
                        description: >-
                          A unique identifier for the request, useful for
                          debugging.
              examples:
                rate_limit:
                  summary: Rate limit breach
                  value:
                    status: fail
                    error:
                      message: Rate limit exceeded
                      type: RateLimitError
                      request_id: onqucLYL
        '500':
          description: >-
            This response is returned when the system runs into an unexpected
            error.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    description: >-
                      This field contains the status of the request and
                      specifies whether the request was a failure.
                    example: fail
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        description: >-
                          A descriptive error message explaining why the request
                          failed.
                      type:
                        type: string
                        description: >-
                          The type or category of the error (e.g., Server
                          Error).
                      request_id:
                        type: string
                        description: >-
                          A unique identifier for the request, useful for
                          debugging.
              examples:
                unknown_error:
                  summary: Unknown errors
                  value:
                    status: fail
                    error:
                      message: >-
                        An unexpected error was encountered while processing
                        this request. Please contact MoEngage Team
                      type: ServerError
                      request_id: KovrwJiF
components:
  schemas:
    MergeUserRequest:
      type: object
      properties:
        merge_data:
          type: array
          description: >
            This field contains the list of UID pairs of the users who are to be
            merged.


            Example:

            ```json

            {
              "merge_data": [    // All the different pairs of users to merge
                {
                  "merged_user": "<sample_uid>", // This user will merge into below user
                  "retained_user": "<sample_uid>"   // Above user will merge into this user
                },
                {
                  "merged_user": "<sample_uid>", // This user will merge into below user
                  "retained_user": "<sample_uid>"   // Above user will merge into this user
                }
              ]
            }

            ```




            * Every object in the Array contains a pair of UID strings - the
            ‘merged_user’ and the ‘retained_user’.

            * UID is the unique identifier for a user maintained by you.
            MoEngage stores this identifier in the ID attribute in the user
            profile.

            * If the merging of any user fails in the array, it will skip that
            object and continue with others.
          items:
            type: object
            properties:
              merged_user:
                type: string
                description: The user ID to be merged and then deleted.
              retained_user:
                type: string
                description: >-
                  The user ID that will remain and absorb the merged user's
                  data.
  securitySchemes:
    Authentication:
      type: http
      scheme: basic
      description: >
        This authentication parameter, used for access control, must be passed
        along with the request. The API request will be authenticated through
        Basic Authentication. Basic Authentication sends a Base64-encoded string
        containing your username and password with every API request. It encodes
        a 'username:password' string in Base64 and appends the encoded string
        with 'Basic '. This string is included in the authorization header as
        shown below:


        `{"Authorization: Basic Base64_ENCODED_WORKSPACEID_APIKEY=="}`


        The username and password details can be obtained from the MoEngage
        Dashboard. If you're using the API for the first time, follow these
        steps:

        1. Navigate to Settings -> Account -> APIs.

        2. Copy the following details:
           * **Username:** Under Workspace ID (earlier app id), click the copy icon to copy the username.
           * **Password:** In the **API keys** section, click the copy icon in the **Data** tile to copy the API key.

        Use these details to authenticate the API requests.

````