Разработка интеграции Битрикс24 через REST API
REST API Битрикс24 — одна из самых документированных частей платформы, но интеграции на нём всё равно регулярно «ломаются»: токены протухают в 01:00 ночи, batch-запросы возвращают частичные ошибки, а лимит в 2 запроса в секунду начинает работать именно тогда, когда нужно срочно синхронизировать 5000 контактов. Разработка надёжной интеграции — это не просто «вызвать метод и записать ответ».
Модель авторизации: OAuth2 против вебхуков
Для постоянных интеграций используется OAuth2. Битрикс24 выдаёт access_token (TTL 1 час) и refresh_token (TTL 14 дней). Ключевая точка отказа — обновление токена: если два параллельных процесса одновременно обнаружат протухший access_token и оба пойдут его обновлять — один из refresh_token инвалидируется и интеграция «падает». Решение: обновление токена через Redis-локку или блокировку на уровне БД.
// Паттерн атомарного обновления токена через Redis
$lock = $redis->set("b24:token_refresh:{$portalId}", 1, ['NX', 'EX' => 10]);
if (!$lock) {
// Другой процесс уже обновляет — ждём
usleep(500000);
return $this->getToken($portalId);
}
try {
$newTokens = $this->requestNewToken($refreshToken);
$this->storeTokens($portalId, $newTokens);
} finally {
$redis->del("b24:token_refresh:{$portalId}");
}
Для простых сценариев без необходимости работать от имени конкретного пользователя — входящий вебхук. URL вида https://domain.bitrix24.ru/rest/1/{token}/method.json со статическим токеном проще, но не привязан к пользователю и не обновляется.
Работа с лимитами
Облачный Битрикс24: 2 запроса в секунду, не более 50 в batch. Коробочный — настраивается в /bitrix/.settings.php ключом throttle_controller.
Для массовых операций — только batch. 50 методов в одном HTTP-запросе с зависимостями через $result[N]:
$batch = [
'contacts' => 'crm.contact.list?start=0&select[]=ID&select[]=NAME',
'deal_1' => 'crm.deal.get?id=$result[contacts][0][ID]',
];
При превышении лимита API возвращает ошибку QUERY_LIMIT_EXCEEDED. Правильная стратегия: exponential backoff — ждём 1с, 2с, 4с. Не ломимся повторно немедленно — это ухудшает ситуацию.
Ключевые группы методов
CRM: crm.lead.*, crm.deal.*, crm.contact.*, crm.company.*. Особенность: пользовательские поля имеют префикс UF_CRM_ для лидов/сделок или произвольный для контактов/компаний — тип и ID поля нужно запрашивать через crm.userfield.list.
Задачи: tasks.task.*. Поле UF_* в задачах — через task.userfield.getlist. Чеклисты — отдельные методы task.checklistitem.*.
Диск: disk.file.*, disk.folder.*. Загрузка файла — через multipart POST на специальный URL, который сначала нужно получить методом disk.folder.uploadfile.
Пользователи: user.get, user.add, user.update. Фильтрация по DEPARTMENT — ID отдела, не его название.
Обработка пагинации
Большинство методов списка возвращают максимум 50 записей и поле next с курсором. Правильный обход:
$start = 0;
do {
$response = $b24->call('crm.deal.list', ['start' => $start, 'filter' => $filter]);
$items = $response['result'];
// обработка $items
$start = $response['next'] ?? null;
} while ($start !== null);
Для больших списков (>10 000 записей) start работает медленно — offset-пагинация деградирует. Вместо неё используем фильтрацию по ID > last_id и сортировку по ID ASC.
Работа с полями типа «список» и «привязка»
Поля типа «Привязка к элементу CRM» (crm_entity) возвращают массив даже если привязка одиночная. При обновлении — передаём массив. Поля типа «Список» — через числовой ID значения, не через его отображаемое имя. Список значений — crm.status.list?filter[ENTITY_ID]=STATUS_ID.
Синхронизация и идемпотентность
Каждая запись внешней системы должна иметь mapped ID в Битрикс24. Стандартный подход: используем поле UF_CRM_EXTERNAL_ID (или аналогичное кастомное поле) для хранения внешнего идентификатора. Перед созданием — проверяем crm.deal.list?filter[UF_CRM_EXTERNAL_ID]=ext123. Если нашли — обновляем, не нашли — создаём. Это защищает от дублей при повторном запуске синхронизации.
Обработка ошибок и мониторинг
API возвращает ошибки в поле error + error_description. Типичные:
| Ошибка | Причина | Решение |
|---|---|---|
QUERY_LIMIT_EXCEEDED |
Превышен лимит 2 рпс | Exponential backoff |
expired_token |
access_token протух | Обновить через refresh_token |
ERROR_CORE |
Ошибка на стороне Битрикс24 | Повтор через 30–60 сек |
ACCESS_DENIED |
Прав недостаточно | Проверить права приложения/пользователя |
NOT_FOUND |
Объект удалён | Удалить маппинг во внешней системе |
Все вызовы API логируем: метод, параметры (без токенов), статус ответа, время выполнения. При error rate > 5% за 5 минут — алерт.
Этапы разработки
| Этап | Содержание | Срок |
|---|---|---|
| Проектирование | Карта данных, выбор методов, модель маппинга | 3–5 дней |
| OAuth2 и управление токенами | Авторизация, хранение, ротация | 2–3 дня |
| Ядро синхронизации | CRUD-операции с Битрикс24, пагинация | 1–2 недели |
| Обработка лимитов и ошибок | Rate limiting, retry, circuit breaker | 3–5 дней |
| Тестирование | Юнит-тесты, интеграционные тесты на sandbox | 1 неделя |
| Мониторинг | Логирование, метрики, алерты | 2–3 дня |
Суммарно: 4–8 недель в зависимости от количества синхронизируемых сущностей и направлений передачи данных.







