Migrating data from a third-party CRM to Bitrix24

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
    1173
  • 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
    745
  • 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

Data Migration from a Third-Party CRM to Bitrix24

Switching from Salesforce, HubSpot, Pipedrive, or a custom-built CRM to Bitrix24 is not simply a matter of exporting a CSV and importing it. Every CRM has its own data model, relationship logic, and field semantics. Bitrix24 does too. The primary goal of migration is to preserve entity relationships and retain the historical value of the data.

Bitrix24 Data Structure

Before migrating, you need to understand where data lands. Key entities in Bitrix24:

Entity DB Table REST API
Contacts b_crm_contact crm.contact.*
Companies b_crm_company crm.company.*
Leads b_crm_lead crm.lead.*
Deals b_crm_deal crm.deal.*
Activities (calls, emails) b_crm_activity crm.activity.*
Custom fields b_uts_crm_* crm.*.userfield.*

Relationships: a contact is linked to a company via b_crm_company_contact; a deal is linked to a contact via b_crm_deal_contact.

Migration Tools

Bitrix24 REST API — the official and most reliable method. Supports batch requests (batch), which is critical when transferring thousands of records:

$batchCalls = [];
foreach ($contacts as $contact) {
    $batchCalls['create_contact_' . $contact['id']] = [
        'method' => 'crm.contact.add',
        'params' => [
            'fields' => [
                'NAME'       => $contact['first_name'],
                'LAST_NAME'  => $contact['last_name'],
                'EMAIL'      => [['VALUE' => $contact['email'], 'VALUE_TYPE' => 'WORK']],
                'PHONE'      => [['VALUE' => $contact['phone'], 'VALUE_TYPE' => 'WORK']],
                'COMPANY_ID' => $companyMapping[$contact['company_id']] ?? null,
                'UF_CRM_SOURCE_ID' => $contact['id'], // Preserve source ID
            ],
        ],
    ];
}

// Send batch (up to 50 requests at a time)
$result = $b24->callBatch(array_slice($batchCalls, 0, 50));

Direct DB write — unavailable for Bitrix24 Cloud. For the on-premise edition it speeds up bulk imports, but requires manual index rebuilding and careful handling of triggers.

Field Mapping: The Most Labor-Intensive Step

Every source field must be mapped to a Bitrix24 field. Example mapping from HubSpot:

HubSpot Bitrix24 Notes
firstname + lastname NAME + LAST_NAME Split
email EMAIL[0].VALUE Type: WORK
phone PHONE[0].VALUE Normalize
company COMPANY_ID Create company separately
lifecyclestage STATUS_ID Map stages
hs_lead_status Custom field UF_CRM_HS_STATUS
createdate DATE_CREATE Only via direct SQL (on-premise)

Non-standard HubSpot fields are moved to Bitrix24 custom fields (UF fields). These must be created in advance via crm.contact.userfield.add.

Entity Creation Order

Order matters because of referential integrity:

  1. Companies (no upstream dependencies for contacts and deals)
  2. Contacts (link to companies)
  3. Deals (link to contacts and companies)
  4. Activities — calls, emails, tasks (link to deals/contacts)
  5. Comments and history — via crm.timeline.comment.add

After creating each entity, save the mapping: source_id → b24_id. This is needed to attach dependent objects.

$mappingFile = 'migration_map.json';
$mapping = json_decode(file_get_contents($mappingFile), true) ?: [];
$mapping['contacts'][$sourceContact['id']] = $b24ContactId;
file_put_contents($mappingFile, json_encode($mapping));

Handling Duplicates

Third-party CRMs frequently contain duplicate contacts — the same person registered under different email addresses. Deduplicate in the source before migrating. Strategies:

  • Hard: one unique email = one contact. Duplicates are merged.
  • Soft: transfer all records, then use the built-in Bitrix24 deduplication tool (Contacts → Duplicates).

The soft strategy is recommended — it preserves all data and lets managers handle deduplication during normal work.

Activity History: Calls and Emails

Migrating communication history is optional but valuable. Calls from the source → crm.activity.add with type CALL:

$b24->call('crm.activity.add', [
    'fields' => [
        'OWNER_TYPE_ID' => 3, // 3 = contact, 2 = deal
        'OWNER_ID'      => $mapping['contacts'][$call['contact_id']],
        'TYPE_ID'       => 2, // Call
        'SUBJECT'       => 'Call on ' . date('d.m.Y', strtotime($call['created_at'])),
        'DESCRIPTION'   => $call['notes'],
        'START_TIME'    => $call['created_at'],
        'END_TIME'      => $call['ended_at'],
        'DIRECTION'     => $call['direction'] === 'inbound' ? 1 : 2,
        'COMPLETED'     => 'Y',
    ],
]);

Migration Quality Control

After the transfer, a mandatory reconciliation:

# Source
SELECT COUNT(*) FROM hubspot_contacts WHERE is_deleted = 0;
# → 12 847

# Bitrix24
SELECT COUNT(*) FROM b_crm_contact WHERE DELETED = 'N';
# → 12 839  ← 8 records missing — investigate

Discrepancies are logged and analyzed: they are typically duplicates or records with invalid data (empty email, malformed phone number).

Timelines

Data Volume Timeline
Up to 5,000 contacts + deals without history 1–2 weeks
5,000–50,000 records + basic activities 3–6 weeks
50,000+ records + full communication history 2–4 months

A successful migration means managers open Bitrix24 the next day and see the complete history of client relationships — as if they had always worked there.