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

# Merge Users

> This API merges two users in MoEngage based on their ID, which is a client-defined identifier for a user. You can use this API when multiple profiles have been created for a single user. For example, you can merge a user registered once with a mobile number and once with an email ID. You can also merge duplicate users created due to integration or tech issues.

#### 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; you must call the Merge User API 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](/user-guide/data/user-data/unified-identity-identity-resolution) feature is enabled.
  - If you are updating the [Unique Identifier](/developer-guide/unity-sdk/data-tracking/tracking-user-attributes) for a user, use the Merge User 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.
  - Set of 100 users can be merged in a single call.
  - Payload size should not exceed 128 KB.
</Warning>

#### Rate limit

The rate limit is 1000 user updates per minute.


## 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-{dc}.moengage.com/v1
    description: MoEngage Core API Server
    variables:
      dc:
        default: '01'
        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](/api/introduction#data-centers). Your MoEngage Data Center (DC)
          can be 01, 02, 03, 04, 05, 06, or 101. 
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: >-
        This API merges two users in MoEngage based on their ID, which is a
        client-defined identifier for a user. You can use this API when multiple
        profiles have been created for a single user. For example, you can merge
        a user registered once with a mobile number and once with an email ID.
        You can also merge duplicate users created due to integration or tech
        issues.
      parameters:
        - name: app_id
          in: query
          required: true
          description: >-
            This is the Workspace ID of your MoEngage account that must be
            passed with the request. You can find it in the MoEngage dashboard
            at **Settings** > **Account** > **APIs** > **Workspace ID (earlier
            app 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. 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 move all data from merged user to retained user.
              retained_user:
                type: string
                description: >
                  The user ID that will remain and absorb the merged user's
                  data. 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.
  securitySchemes:
    Authentication:
      type: http
      scheme: basic
      description: >
        Authentication is done via Basic Auth. This requires a base64-encoded
        string of your credentials in the format 'username:password'.


        - **Username**: Use your MoEngage workspace ID (also known as the App
        ID). You can find it in the MoEngage dashboard at **Settings** >
        **Account** > **APIs** > **Workspace ID (earlier app id)**.

        - **Password**: Use your API Key, which you can find within the **Data**
        tile.


        **Note**: After you generate and save the Data API Key, DO NOT generate
        a new key unless there is a security breach. After you generate a
        different Data API key and save it, the authentication will start
        failing. You must update your existing data tracking. 


        For more information on authentication and getting your credentials,
        refer
        [here](https://www.moengage.com/docs/api/introduction#getting-your-credentials).

````