---
title: Profile identity resolution and merging
related:
  - https://docs.kentico.com/documentation/developers-and-admins/digital-marketing-setup/customer-data-platform.md
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

> **Warning:** **Preview feature**
>
> Identity resolution and the [customer data platform](https://docs.kentico.com/documentation/developers-and-admins/digital-marketing-setup/customer-data-platform.md) feature as a whole are currently in preview mode. Expect the features to be modified and expanded significantly in upcoming releases, including breaking changes.
>
> Feel free to try the feature out. You can share your feedback directly with the Kentico [Product team](https://roadmap.kentico.com/).

Identity resolution determines when multiple [profiles](https://docs.kentico.com/documentation/developers-and-admins/digital-marketing-setup/customer-data-platform.md#profile-tracking) represent the same person based on shared information, such as an email address or member ID. When matching profiles are detected, the system automatically merges them into a single unified profile, consolidating all related data and activities.

## Default identity resolution behavior

By default, the system merges profiles when they have a **matching email address** in the linked [member](https://docs.kentico.com/documentation/business-users/members.md) entity, representing a registered user on a website. Profiles without an associated registered member are never merged by default.

You can [configure](#configure-identity-resolution-rules) identity resolution rules to match individual project requirements in the **Customer data management** application.

## Configure identity resolution rules

Identity resolution works by evaluating **identities**, which represent pieces of information that the system uses to match profiles. Each identity is based on a specific database column (field) of a [profile-related entity](https://docs.kentico.com/documentation/developers-and-admins/digital-marketing-setup/customer-data-platform.md) (contact, member, customer). When the value of an identity column is the same across two profiles, the system considers the profiles to represent the same person and treats them as candidates for [merging](#how-profile-merging-works).

You can view and adjust the project's identity resolution rules in the **Customer data management** application.

To add a new identity:

1. Select **New identity**.

2. Fill in the identity properties:
   - **Identity name**

   - **Source class** – the Xperience class representing one of the [entities connected to profiles](https://docs.kentico.com/documentation/developers-and-admins/digital-marketing-setup/customer-data-platform.md). A database column from the given class can be selected as the identity.

     > **Info:** **Contact column identities and form field mapping**
     >
     > When a column from the _Contact management - Contact_ class is added as an identity, [form field mapping](https://docs.kentico.com/documentation/business-users/digital-marketing/forms/create-and-edit-forms.md#map-form-submission-to-contact-attributes) cannot overwrite existing values in that column. Form submissions can still populate the column if its value is empty.

   - **Database column** – the specific column from the selected _Source class_ that holds the identity value. The system merges profiles when they have matching values in the identity column (if there are no conflicts in other immutable identity columns).

   - **Identity value mutability** – determines if the value of the identity column can change when attempting to [merge profiles](#how-profile-merging-works).

3. **Create** the identity.

The new identity is added to the end of the list of current identities, with the lowest priority. You can add any number of identities and [reorder](#reorder-identities) them as required.

See [How profile merging works](#how-profile-merging-works) to learn how identities control profile merging.

> **Note:** **Cross-column identities**
>
> Currently, the system does **not support** identity matching across different columns. For example, you cannot merge profiles when the value of the contact email address and member email address is the same.

### Reorder identities

When the system evaluates identity resolution rules to find matching profiles, the identities are processed in order of their **Priority**, from the lowest number (_Priority 1_ placed at the top of the list) to the highest.

The priority of identities can affect how the system merges profiles. See [Role of identity priority](#role-of-identity-priority) for detailed information.

To change the order of identities:

1. Open the **Customer data management** application.
2. Move identities up or down using the drag handle () to reorder them.
3. Select **Save priorities** to persist the new order.

## How profile merging works

Profile merging is triggered when:

- A **contact field** is updated.
  - Currently, only fields with the **Text** or **Long text** data type trigger the merge process (only text fields can be selected as identities).
  - This includes all possible ways contacts can be updated. For example, when a visitor submits a [form](https://docs.kentico.com/documentation/business-users/digital-marketing/forms.md), an administrator edits profile personal details in the admin UI, or custom code updates a contact through the API.
- A **member signs in** on the live site – your project's member sign-in flow must be extended to call `IProfileSignInService.TryConnectMemberWithProfile`. See [Connect members with profiles on sign-in](#connect-members-with-profiles-on-sign-in).

When attempting to merge profiles, the system evaluates the [configured identities](#configure-identity-resolution-rules) in order of their priority. The system goes through the following steps for each identity:

1. Retrieves the identity value for the profile that triggered the merge.
2. If the identity value is not empty or null, searches for other profiles that share the same identity value.
3. When a match is found, checks all **Immutable** identity columns across both profiles for conflicts.
4. If no immutable conflicts exist, the profiles are merged. Otherwise, the merge is blocked.
5. If a match is not found, the system moves to the next identity.

> **Note:** **Identity value comparison**
>
> Identity matching is **case-sensitive**. For example, _user@example.com_ and _USER@example.com_ are treated as different values and don't trigger a merge.

For more details and examples, see the following sub-sections:

- [What happens during a merge](#what-happens-during-a-merge)
- [Role of identity priority](#role-of-identity-priority)
- [Identity value mutability](#identity-value-mutability)
- [Conditions that prevent profile merging](#conditions-that-prevent-profile-merging)

### What happens during a merge

On a successful merge, data from across all profile-related entities and all profile [activities](https://docs.kentico.com/documentation/developers-and-admins/digital-marketing-setup/customer-data-platform.md#activity-logging) are combined:

- In case of value conflicts, the values are taken from the profile that triggered the merge. The merge does not occur if a conflict occurs for an **Immutable** identity column.
- Empty values are always populated if the other profile's value is not empty.
- The verification status of profiles remains valid when either of the merged profiles is verified. For example, if an anonymous (unverified) profile is merged with a verified profile, the result is a verified profile.

The result of the merge is a single profile. The other merged profiles no longer exist as separate entities in the system.

> **Note:** **Profiles created based on legitimate interest**
>
> Some profiles represent untracked visitors and are added as a result of [activities logged based on legitimate interest](https://docs.kentico.com/documentation/developers-and-admins/digital-marketing-setup/customer-data-platform.md). For example, the system creates such profiles when a visitor submits a form or registers as a member without giving consent to be tracked.
>
> If this type of profile triggers the merge process and an identity match with a "full" profile is found, the standard priority for value conflicts is reversed and the full profile has precedence. The legitimate interest profile is merged "into" the full profile.

### Role of identity priority

The [priority](#reorder-identities) of identities determines the sequence in which the system evaluates identities during the merge process – from the highest priority (lowest number, i.e., _Priority 1_) to the lowest priority.

When a match is found for a given identity, the system attempts a merge immediately. If the merge is blocked (e.g., due to an [immutable](#identity-value-mutability) conflict), the system continues with the next identity.

The system checks **all** immutable identity columns for conflicts, regardless of their priority. As a result, identity order has the most significant impact when using **mutable** identities.

**Example: Priority impact for mutable identities**

Case 1 – Two identities are configured:

- _ContactEmail_ (_Priority 1_, mutable)
- _ContactCustomExternalIdentifier_ (_Priority 2_, mutable)

The system finds a match on _ContactEmail_, but a conflict on _ContactCustomExternalIdentifier_. Because the matching identity has higher priority, the **merge proceeds** and the _ContactCustomExternalIdentifier_ is taken from the profile that triggered the merge.

Case 2 – The same identities have reversed priority:

- _ContactCustomExternalIdentifier_ (_Priority 1_, mutable)
- _ContactEmail_ (_Priority 2_, mutable)

The system finds a match on _ContactEmail_, but a conflict on _ContactCustomExternalIdentifier_. The matching identity has lower priority than the identity with a conflict, so the **merge is blocked**.

### Identity value mutability

Each identity has a **mutability** setting that determines whether the identity column acts as a hard constraint during profile merging.

- **Mutable** – the column value can differ between the two profiles without blocking the merge. After the merge, the resulting profile retains the value from the profile that triggered the merge (i.e., the profile that was most recently updated).
- **Immutable** – if both profiles have a non-empty value in this column and the values differ, the merge is **blocked**. If one of the values is null (empty), the merge proceeds. The immutability check applies across all configured immutable identities.

**Example: Immutable identity with conflicting values**

Two identities are configured:

- _MemberEmail_ (_Priority 1_, mutable)
- _ContactEmail_ (_Priority 2_, immutable)

The following profiles trigger the merge process:

- Profile A: _MemberEmail_ = _shared@example.com_, _ContactEmail_ = _alice@example.com_
- Profile B: _MemberEmail_ = _shared@example.com_, _ContactEmail_ = _bob@example.com_

The system finds a match on _MemberEmail_. However, the immutability check detects that both profiles have different non-null values in the immutable _ContactEmail_ column. The merge is **blocked**.

**Example: Mutable identity with conflicting values**

Same configuration, but _ContactEmail_ is set to mutable instead.

- Profile A: _MemberEmail_ = _shared@example.com_, _ContactEmail_ = _alice@example.com_
- Profile B: _MemberEmail_ = _shared@example.com_, _ContactEmail_ = _bob@example.com_

The system finds a match on _MemberEmail_. Because _ContactEmail_ is mutable, the differing values don't block the merge. The profiles are merged and the resulting profile retains the _ContactEmail_ value from the profile that triggered the merge.

**Example: Immutable identity with one empty value**

Same configuration, _ContactEmail_ is immutable.

- Profile A: _MemberEmail_ = _shared@example.com_, _ContactEmail_ = _alice@example.com_
- Profile B: _MemberEmail_ = _shared@example.com_, _ContactEmail_ is empty (null)

The merge **proceeds** – null values are not considered a conflict, even for immutable identities.

### Conditions that prevent profile merging

The following conditions prevent the system from merging two profiles:

- **Immutable identity conflict** – both profiles have different non-null values in any column configured as an immutable identity.
- **Different member entities** – both profiles are linked to different members (different member IDs). Profiles with different members can never merge.
- **Different customer entities** – both profiles are linked to different customers (different customer IDs). Profiles with different customers can never merge.
- **Merge already in progress for the same profile** – the system is already processing a merge for the current profile. This prevents recursive merge cycles.

> **Note:** **Member and customer identity constraints**
>
> Profiles that reference **different** member entities can never be merged, regardless of which identity triggered the match. The same applies to profiles referencing different customer entities.
>
> These are implicit constraints that take precedence over all configured identity resolution rules and are safeguards against losing verified data provided during registration or purchases.

## Connect members with profiles on sign-in

> **Warning:** **Experimental API**
>
> Identity resolution and the [customer data platform](https://docs.kentico.com/documentation/developers-and-admins/digital-marketing-setup/customer-data-platform.md) feature as a whole are currently in preview mode.
>
> All related API is [marked as experimental](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/attributes/general#experimental-attributes) and usage will result in warnings when compiling your project. The warnings are treated as errors for reporting purposes. To use the code, you need to [suppress](https://learn.microsoft.com/en-us/dotnet/fundamentals/syslib-diagnostics/experimental-overview#suppress-warnings) the warnings.

Visitors can access your website using different devices and the [profile](https://docs.kentico.com/documentation/developers-and-admins/digital-marketing-setup/customer-data-platform.md#profile-tracking) may not always be tracked in the browser session. On sites with [registration and authentication functionality](https://docs.kentico.com/documentation/developers-and-admins/development/registration-and-authentication.md), developers can connect the current profile with the [member account](https://docs.kentico.com/documentation/business-users/members.md) and trigger the profile merging process.

This allows you to merge profiles created by connections from new devices with the member's existing profile, which already contains data and logged activities from previous interactions.

To connect the current member with the current profile:

1. Edit your project's sign-in logic, for example a [sign-in controller](https://docs.kentico.com/documentation/developers-and-admins/development/registration-and-authentication/forms-authentication.md#sign-in-and-sign-out).
2. Get an instance of the `IProfileSignInService` interface (available in the `Kentico.CustomerDataPlatform.Web.Mvc` namespace).
3. Call the `IProfileSignInService.TryConnectMemberWithProfile` method.

```csharp title="SignInController.cs"
using Kentico.CustomerDataPlatform.Web.Mvc;

public class SignInController(IProfileSignInService profileSignInService) : Controller
{
    [HttpPost]
    public async Task<IActionResult> SignIn(SignInViewModel model, CancellationToken cancellationToken)
    {
        // ... Sign-in logic

        // Connects the signed-in member with the current visitor profile
        // Also triggers profile merging based on identity resolution rules
        await profileSignInService.TryConnectMemberWithProfile(cancellationToken);

        return RedirectToAction("Index", "Home");
    }
}
```

The method:

- Gets the currently signed-in member from the HTTP context.
- Attempts to get the current visitor profile from the _CMSCurrentProfile_ cookie (available if the visitor has given [consent to be tracked](https://docs.kentico.com/documentation/developers-and-admins/digital-marketing-setup/customer-data-platform/consent-development-cdp.md) and has the required [cookie level](https://docs.kentico.com/documentation/developers-and-admins/data-protection/cookies.md)).
- Links the member to the profile.
- Triggers the merging process for the current profile.

The method returns `true` if both the current member and profile are available and were successfully linked. For example, the value is `false` if the visitor has not given consent to be tracked and the current profile is not available in the _CMSCurrentProfile_ cookie.

The result of the profile merging does not affect the method's return value – the current profile may or may not be merged with other profiles based on the [identity resolution rules](#configure-identity-resolution-rules) configured for the project.
