Setting Up Automatic Lead Import from VK Ads into Bitrix24
VK Lead Ads is the primary lead generation tool on VKontakte for the B2C segment. Unlike Facebook, VK provides several mechanisms for receiving leads: webhooks via VK Callback API, a Leads API for polling, and direct integration through VK Mini Apps. For automatic lead delivery into Bitrix24, the webhook via Callback API is the optimal approach.
VK Callback API for lead forms
In the VKontakte community settings: "Management → API → Callback API" — add a server with the handler URL.
Server verification:
$data = json_decode(file_get_contents('php://input'), true);
// Server confirmation
if ($data['type'] === 'confirmation') {
echo VK_CONFIRMATION_STRING; // string from Callback API settings
exit;
}
// Signature verification
if ($data['secret'] !== VK_CALLBACK_SECRET) {
http_response_code(403);
exit;
}
Processing a new lead (event lead_forms_new):
if ($data['type'] === 'lead_forms_new') {
$lead = $data['object'];
$leadId = $lead['lead_id'];
$formId = $lead['form_id'];
$groupId = $lead['group_id'];
$userId = $lead['user_id'];
$adId = $lead['ad_id'] ?? '';
$utmData = $lead['utm'] ?? [];
// Form field answers
$answers = $lead['answers'] ?? [];
$fields = [];
foreach ($answers as $answer) {
$fields[$answer['key']] = $answer['answer'] ?? '';
}
// Create lead in Bitrix24
$this->createBitrix24Lead($leadId, $formId, $fields, $utmData, $adId);
echo 'ok'; // VK expects the string 'ok' in the response
exit;
}
Retrieving full data via Leads API
The Callback API for lead forms delivers user answers directly in answers. To get data about the user themselves (name, phone from their profile, if permission was granted) — an additional VK API request is needed:
public function enrichLeadWithUserData(int $userId, string $accessToken): array
{
$response = $this->vkApi->call('users.get', [
'user_ids' => $userId,
'fields' => 'photo_100,city',
]);
$user = $response['response'][0] ?? [];
return [
'first_name' => $user['first_name'] ?? '',
'last_name' => $user['last_name'] ?? '',
'vk_profile' => "https://vk.com/id{$userId}",
];
}
Mapping VK Lead Forms fields to Bitrix24
VK uses standard keys for common fields: first, last, name, phone, email. Custom questions have arbitrary keys defined when the form was created.
public function createBitrix24Lead(
string $vkLeadId,
int $formId,
array $fields,
array $utm,
string $adId
): void {
// Standard fields
$name = trim(($fields['first'] ?? '') . ' ' . ($fields['last'] ?? ''))
?: ($fields['name'] ?? 'VK Lead');
$phone = $fields['phone'] ?? '';
$email = $fields['email'] ?? '';
$b24Fields = [
'TITLE' => 'VK Lead Ads: ' . date('d.m.Y H:i'),
'NAME' => $name,
'PHONE' => [['VALUE' => $phone, 'VALUE_TYPE' => 'MOBILE']],
'EMAIL' => [['VALUE' => $email, 'VALUE_TYPE' => 'WORK']],
'SOURCE_ID' => 'ADVERTISING',
'SOURCE_DESCRIPTION' => 'VK Lead Ads',
'UF_CRM_VK_LEAD_ID' => $vkLeadId,
'UF_CRM_VK_FORM_ID' => $formId,
'UF_CRM_VK_AD_ID' => $adId,
'UF_CRM_UTM_SOURCE' => $utm['source'] ?? 'vk',
'UF_CRM_UTM_CAMPAIGN' => $utm['campaign'] ?? '',
'UF_CRM_UTM_MEDIUM' => $utm['medium'] ?? 'cpc',
];
// Custom form fields — added as a comment
$customFields = array_diff_key($fields, array_flip(['first','last','name','phone','email']));
if (!empty($customFields)) {
$b24Fields['COMMENTS'] = implode("\n", array_map(
fn($k, $v) => "{$k}: {$v}",
array_keys($customFields),
array_values($customFields)
));
}
$this->b24->call('crm.lead.add', [
'FIELDS' => $b24Fields,
'PARAMS' => ['REGISTER_SONET_EVENT' => 'Y'],
]);
}
Multiple communities and forms
If a company manages several VKontakte communities or uses multiple lead forms for different products, each group_id and form_id can be mapped to a specific pipeline and responsible manager in Bitrix24:
$routingConfig = [
['group_id' => 123456, 'form_id' => 111, 'pipeline_id' => 1, 'assigned_by' => 5],
['group_id' => 123456, 'form_id' => 222, 'pipeline_id' => 3, 'assigned_by' => 8],
['group_id' => 789012, 'form_id' => 333, 'pipeline_id' => 2, 'assigned_by' => 11],
];
The configuration is stored in a table or JSON file and can be updated without a deployment.
Deduplication and phone-based verification
VKontakte users sometimes submit the same form multiple times. Deduplication is based on vk_lead_id (unique VK ID), which is stored in a custom field. Before creating a lead:
$existing = $this->b24->call('crm.lead.list', [
'filter' => ['UF_CRM_VK_LEAD_ID' => $vkLeadId],
]);
if (!empty($existing)) return; // already created
Scope of work
- Callback API setup in the VKontakte community
- Handler development: verification, field mapping, lead creation
- Custom fields in Bitrix24 for VK attributes
- Routing config for multiple communities/forms
- Deduplication by vk_lead_id and phone
- Error logging, webhook delivery monitoring
Timeline: 3–5 days for a single community. Up to 2 weeks with complex routing and multiple forms.







