Integrating 1C-Bitrix with Callibri

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
    1175
  • 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

1C-Bitrix Integration with Callibri

Callibri is a call tracking and multi-channel analytics platform. Unlike basic Google Analytics, it can stitch a call to a specific traffic source and pass UTM parameters to the CRM. The problem with standard setups: the Callibri script collects data in its own system, while leads from Bitrix forms live in b_form_result, with no connection between them. The manager sees a call but does not know which ad brought the customer. The integration goal is to close the chain: source → action → lead/call → deal in CRM.

Integration Architecture

Callibri provides two mechanisms: a JavaScript API for the client side and a REST API for server-side interaction. A complete Bitrix integration requires both.

Data flow diagram:

Visitor → Callibri JS replaces the number
  → Call is recorded in Callibri
    → Webhook from Callibri (POST to your endpoint)
      → Bitrix handler
        → Create lead/deal in Bitrix CRM
          → Attach UTM parameters to the deal

In parallel, for online forms:

Bitrix form submission
  → JS handler: reads callibri_visitor_uid from cookie
    → Passes uid along with form data
      → Server handler saves uid to lead properties
        → Callibri REST API: request visit details by uid

Configuring the Callibri Webhook

In the Callibri account: Settings → Integrations → Webhook. Enter your handler URL. Callibri sends a POST with a JSON payload on every call, chat, or lead.

Payload structure (key fields):

{
  "call_id": "98765432",
  "call_type": "call",
  "caller_number": "+79161234567",
  "call_date": "2024-03-15 14:23:11",
  "utm_source": "yandex",
  "utm_medium": "cpc",
  "utm_campaign": "brand_kw",
  "duration": 145,
  "is_target": true,
  "visitor_id": "callibri_abc123"
}

The handler in Bitrix — a dedicated component or /local/api/callibri-webhook.php:

<?php
require_once($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php');

$rawInput = file_get_contents('php://input');
$data = json_decode($rawInput, true);

if (empty($data) || empty($data['caller_number'])) {
    http_response_code(400);
    exit;
}

// Verification via a secret token in the header
$token = $_SERVER['HTTP_X_CALLIBRI_TOKEN'] ?? '';
if ($token !== \Bitrix\Main\Config\Option::get('local.callibri', 'webhook_secret')) {
    http_response_code(403);
    exit;
}

(new \Local\Callibri\LeadCreator())->createFromWebhook($data);

http_response_code(200);
echo json_encode(['status' => 'ok']);

Creating a Lead in CRM from a Call

namespace Local\Callibri;

use Bitrix\Crm\LeadTable;
use Bitrix\Main\Type\DateTime;

class LeadCreator
{
    public function createFromWebhook(array $data): int
    {
        $fields = [
            'TITLE'          => 'Callibri call: ' . $data['caller_number'],
            'PHONE'          => [['VALUE' => $data['caller_number'], 'VALUE_TYPE' => 'WORK']],
            'SOURCE_ID'      => 'CALL',
            'STATUS_ID'      => 'NEW',
            'ASSIGNED_BY_ID' => $this->resolveAssignee($data),
            'UF_CALLIBRI_ID' => $data['call_id'],
            'UF_UTM_SOURCE'  => $data['utm_source'] ?? '',
            'UF_UTM_MEDIUM'  => $data['utm_medium'] ?? '',
            'UF_UTM_CAMPAIGN'=> $data['utm_campaign'] ?? '',
            'UF_CALL_DURATION' => (int)($data['duration'] ?? 0),
            'COMMENTS'       => $this->buildComment($data),
        ];

        $lead = new \CCrmLead(false);
        $leadId = $lead->Add($fields, true, ['DISABLE_USER_FIELD_CHECK' => false]);

        if (!$leadId) {
            \CEventLog::Add([
                'SEVERITY'  => 'ERROR',
                'AUDIT_TYPE_ID' => 'CALLIBRI_LEAD_FAIL',
                'MODULE_ID' => 'local.callibri',
                'DESCRIPTION' => $lead->LAST_ERROR,
            ]);
        }

        return (int)$leadId;
    }

    private function buildComment(array $data): string
    {
        $isTarget = $data['is_target'] ? 'Targeted' : 'Non-targeted';
        return sprintf(
            "Callibri ID: %s\nType: %s\nDuration: %d sec.\nSource: %s / %s / %s",
            $data['call_id'],
            $isTarget,
            $data['duration'] ?? 0,
            $data['utm_source'] ?? '—',
            $data['utm_medium'] ?? '—',
            $data['utm_campaign'] ?? '—'
        );
    }
}

Linking a Visit to a Bitrix Form

Callibri sets a callibri_visitor_uid cookie on the client side. Intercept the form submission and inject the uid as a hidden field.

JavaScript on the page with the form:

document.addEventListener('DOMContentLoaded', function () {
    const forms = document.querySelectorAll('form.bx-form, form[data-bitrix-form]');
    forms.forEach(function (form) {
        const uid = getCookie('callibri_visitor_uid');
        if (uid) {
            const input = document.createElement('input');
            input.type = 'hidden';
            input.name = 'callibri_uid';
            input.value = uid;
            form.appendChild(input);
        }
    });
});

function getCookie(name) {
    const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
    return match ? match[2] : null;
}

On the server in the form handler (OnBeforeIBlockElementAdd or a custom handler):

$callibriUid = htmlspecialchars($_POST['callibri_uid'] ?? '');
if ($callibriUid) {
    // Save to the custom lead field
    $leadFields['UF_CALLIBRI_UID'] = $callibriUid;

    // Request visit details from the Callibri API
    $visitData = (new \Local\Callibri\ApiClient())->getVisitByUid($callibriUid);
    if ($visitData) {
        $leadFields['UF_UTM_SOURCE']   = $visitData['utm_source'] ?? '';
        $leadFields['UF_UTM_CAMPAIGN'] = $visitData['utm_campaign'] ?? '';
    }
}

Lead Deduplication

A common problem: a customer called and then submitted a form. Two separate leads for the same contact.

public function findExistingLead(string $phone): ?int
{
    $phone = preg_replace('/\D/', '', $phone);

    $result = \CCrmLead::GetList(
        ['DATE_CREATE' => 'DESC'],
        [
            'PHONE'      => $phone,
            'STATUS_ID'  => 'NEW',
            '>DATE_CREATE' => (new DateTime())->add('-1D')->format('d.m.Y H:i:s'),
        ],
        false, ['nTopCount' => 1],
        ['ID', 'UF_CALLIBRI_ID']
    );

    if ($row = $result->Fetch()) {
        return (int)$row['ID'];
    }

    return null;
}

If a recent lead is found — update it with the new data rather than creating a new one.

Custom Fields for UTM in CRM

Fields are created via CUserTypeEntity or through the CRM administration interface. Recommended set:

Field code Type Purpose
UF_CALLIBRI_ID string Call/chat ID in Callibri
UF_CALLIBRI_UID string Visitor UID for form stitching
UF_UTM_SOURCE string utm_source
UF_UTM_MEDIUM string utm_medium
UF_UTM_CAMPAIGN string utm_campaign
UF_UTM_TERM string utm_term
UF_CALL_DURATION integer Call duration, seconds
UF_IS_TARGET_CALL boolean Targeted call flag

Scope of Work

  • Register the local.callibri component and set module options
  • Develop the webhook handler with token verification
  • Create custom fields in CRM (lead, deal)
  • Callibri REST API client (fetching visit details)
  • JS form-interception script for passing visitor_uid
  • Lead deduplication logic by phone number
  • End-to-end scenario testing: call → lead with UTM

Timelines: basic integration (webhook → lead) — 1–2 weeks. Full stitching with forms, deduplication, and UTM display on the deal card — 3–4 weeks.