Setting up duplicate merging in Bitrix24 CRM

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1177
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    747
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    976

Configuring Duplicate Merging in Bitrix24 CRM

Finding duplicates is half the work. The other half is merging them without losing call history, deals, tasks, and custom fields. This is where most companies run into real problems: after a merge, activities disappear, the wrong "master" card is selected, and related deals get reassigned to the wrong record.

The merging mechanism in Bitrix24 operates through the CCrmEntityMerger class — it sequentially transfers related objects, then deletes the absorbed records. Understanding the order of operations is essential to avoid broken references.

Manual Merging via the Interface

Basic workflow: CRM → Contacts → Find Duplicates → select a group → Merge. The system displays cards side by side and prompts you to choose which value to keep for each field in the resulting record.

Pitfalls of manual mode:

  • When merging companies, related contacts are automatically moved to the "master" — verify that you selected the correct one.
  • Files from absorbed cards are transferred, but their original path in b_disk_object changes — any external links to those files will break.
  • Custom fields of type "list" are merged only if the "multiple selection" option is enabled; single values are taken from the master record and the rest are lost.

Configuring Merge Rules

In CRM → Settings → Duplicates → Merge Rules, you define the logic for resolving field conflicts:

Rule Behavior
Master record Value taken from the selected "master" card
More complete Non-empty value is used; on conflict — from master
Merge Applicable for multi-value fields (phones, email)
Most recent by date Value taken from the record with the later modification date

For most use cases the optimal setup is: key identifiers (tax ID, phone, email) — "merge"; status fields (responsible person, stage) — "master record"; text notes — "more complete".

Programmatic Merging via API

Manual mode is unsuitable for bulk database cleanup. REST method for merging contacts:

// Merge: record 1001 absorbs 1002 and 1003
$response = CRest::call('crm.contact.merge', [
    'id'      => 1001,
    'victims' => [1002, 1003],
    'fields'  => [
        'PHONE'          => 'merge',    // merge phone numbers
        'EMAIL'          => 'merge',    // merge email addresses
        'ASSIGNED_BY_ID' => 'primary',  // responsible from master
    ],
]);

For companies, use crm.company.merge in the same way. The method is synchronous; merging more than 5 absorbed records at once may cause a timeout — process in pairs.

Within Bitrix24 at the PHP level (On-Premise):

$merger = new CCrmEntityMerger(CCrmOwnerType::Contact);
$merger->Merge(
    1001,          // master record ID
    [1002, 1003],  // victims
    $fields,       // field rules
    $errorMessage
);

Transferring Related Objects

This is a critical part that is easy to overlook. The following are transferred automatically during a merge:

  • Deals (CONTACT_ID field is updated)
  • Activities: calls, emails, meetings from the b_crm_activity table
  • Tasks via the b_tasks_member relation
  • Timeline (b_crm_timeline)

Not transferred automatically:

  • Relations via custom Smart Process (SPA) blocks — requires a separate update script
  • External relations from third-party integrations (data in custom tables)
  • Open Line chats — history is tied to the line, not to the contact

For Smart Processes, relation updates must be done manually via crm.item.update with the new contactId.

Rolling Back a Merge

There is no built-in rollback. After a merge, absorbed records are marked as deleted (the DELETED=Y flag in b_crm_contact), but remain physically in the database for several days before the recycle bin is cleared.

Recovery window: CRM → Settings → Recycle Bin — absorbed cards land there and are available for restoration for up to 30 days (configurable). After restoration, relations to the master record are not restored automatically — they must be reassigned manually.

Before running any bulk merge, always back up the b_crm_contact, b_crm_company, b_crm_deal tables and the activity tables.