Лимиты API при переносе базы клиентов в CRM: способы проверки перед оплатой тарифа
Перенос клиентской базы в CRM ломается не на красивых полях «имя», «телефон», «ответственный менеджер». Он ломается там, где маркетинговая страница тарифа молчит: на лимитах API, токенах, пакетных методах, заголовках ответа и скучном HTTP 429.

Снаружи это выглядит как «импорт завис». Внутри — интеграция долбит endpoint как ботнет на минималках, получает rate limit, ретраит без паузы и сама себе роет яму.
Мы в лаборатории разбирали такие миграции не раз: база на десятки или сотни тысяч контактов, подрядчик уже выставил счёт, тариф уже оплачен, бизнес ждёт понедельника. Потом выясняется, что CRM пропускает не «сколько угодно», а строго по счётчику. У amoCRM — не более 7 запросов в секунду на одну интеграцию и до 50 запросов в секунду на весь аккаунт. У облачного Битрикс24 для серверных OAuth-приложений — 2 запроса в секунду на приложение на портал. Salesforce и HubSpot честнее: они хотя бы отдают лимиты в заголовках и отдельных endpoint’ах. Но читать эти сигналы надо до оплаты тарифа, а не когда импорт уже дымится.
Почему миграция данных часто упирается в ограничения API
CRM продают как «единое окно для продаж». API продают как «гибкую интеграцию». На практике API — это шлюз с турникетом, а не парадная дверь. И этот турникет щёлкает по своим правилам.
Миграция базы клиентов обычно кажется простой операцией: выгрузили CSV из старой системы, нормализовали телефоны, разложили компании, контакты, сделки, примечания, задачи, файлы, пользовательские поля — и отправили в новую CRM. Вот только каждая сущность редко создаётся одним запросом. Контакт отдельно. Компания отдельно. Сделка отдельно. Связь контакта со сделкой отдельно. Пользовательское поле отдельно. Комментарий отдельно. История коммуникаций — вообще отдельная песня, часто с вложениями и временными метками.
Именно здесь «100 тысяч клиентов» превращаются в 600–900 тысяч API-вызовов. Без малвари, без эксплойтов, без злого хакера. Достаточно плохо написанного импортёра.
Типовые ошибки выглядят так:
1. Один объект — один запрос, без пакетирования.
Разработчик пишет самый прямой код: взять строку, создать контакт, создать сделку, проставить поле. Работает на тестовых 20 записях. Умирает на реальной базе.
2. Нет локального throttling.
Клиентское приложение не ограничивает собственную скорость. Оно просто шлёт запросы, пока сервер не начнёт бить по рукам. Потом все удивляются 429 Too Many Requests. Сюрприз уровня «мы забыли тормоза, но машина быстрая».
3. Повтор запроса без backoff.
Получили 429 — сразу повторили. Получили снова — повторили ещё. Это не отказоустойчивость. Это цифровой таран.
4. Один токен на все процессы.
Импорт контактов, импорт сделок, синхронизация телефонии и веб-формы работают через одну интеграцию. Потом команда миграции честно говорит: «Мы ничего не превышали». Да, вы одни — возможно. А весь аккаунт — уже нет.
5. Покупка тарифа без sandbox-теста.
Самая дорогая ошибка. Сначала платят. Потом читают документацию. Потом пишут в поддержку. Потом ждут. В этот момент бизнес уже считает простой.
Лимит API — это не мелкий шрифт. Это пропускная способность вашей миграции. Не проверили её заранее — купили не CRM, а очередь на вход.
В безопасности мы называем это поверхностью отказа. Не атаки, а отказа. Но последствия похожи: данные не доехали, часть записей задублировалась, часть связей потерялась, токены просрочились, интеграция начала писать мусор, а аудит потом ищет виноватых в логах.
Как до оплаты понять, во что вы упрётесь
Проверка лимитов API при переносе базы в CRM начинается не с письма менеджеру продаж. Менеджер почти всегда ответит что-нибудь бодрое: «У нас мощная платформа, клиенты переносят миллионы записей». Полезность такого ответа примерно как у наклейки «военный уровень шифрования» на роутере из супермаркета.
Нужны технические артефакты:
- документация по rate limit: частота запросов, дневной объём, лимиты на приложение, пользователя, портал или аккаунт;
- правила для OAuth-приложений и refresh token;
- поддержка batch-запросов;
- коды ошибок при превышении;
- заголовки ответа с текущим потреблением;
- endpoint для проверки лимитов;
- условия временного расширения лимитов на период миграции;
- поведение подписки: что происходит с записью и чтением данных после окончания тарифа.
Не все CRM раскрывают всё. Это нормально. Ненормально — платить, не получив хотя бы минимальную картину.
Минимальная математика миграции
Перед тестом надо посчитать не «сколько клиентов», а сколько API-операций реально потребуется. Пример грубый, но рабочий.
| Что переносим | Наивная оценка | Где возникает лишняя нагрузка |
|---|---|---|
| 100 000 контактов | 100 000 запросов | Если нет пакетного создания |
| 40 000 компаний | 40 000 запросов | Плюс поиск дублей перед созданием |
| 120 000 сделок | 120 000 запросов | Плюс связи с контактами и ответственными |
| 300 000 примечаний | 300 000 запросов | Часто идут отдельными endpoint’ами |
| Пользовательские поля | 100 000+ операций | Если значения пишутся после создания объекта |
| Проверка существующих записей | x2 к нагрузке | Если перед каждой записью делается search |
В этой таблице нет экзотики. Только обычная CRM-грязь. Если импортёр делает предварительный поиск дублей по телефону или email перед созданием, количество запросов легко удваивается. Если он ещё и обновляет пользовательские поля отдельными вызовами, можно получить тройной коэффициент.
И дальше начинается арифметика, которую почему-то любят игнорировать. При лимите 2 запроса в секунду вы физически не протолкнёте миллион операций за час. При 7 запросах в секунду — тоже не протолкнёте «быстро», если код не умеет batch и backoff. Железо подрядчика тут не спасает. Сервер CRM всё равно поставит шлагбаум.
Технический аудит: читаем заголовки, а не рекламные обещания
Хорошая CRM при ответе API отдаёт не только JSON с данными, но и служебную информацию. Там часто лежит правда. Не в лендинге, не в коммерческом предложении, а в HTTP-заголовках.
Salesforce позволяет отслеживать потребление API через заголовок Sforce-Limit-Info. Формат может выглядеть как api-usage=25/5000: использовано 25 запросов из 5000. Также есть endpoint /services/data/vXX.X/limits, который возвращает данные по лимитам через REST API. Это нормальная инженерная практика: система показывает счётчик, а не предлагает гадать по кофейной гуще.
HubSpot отдаёт лимиты через заголовки вроде X-HubSpot-RateLimit-Daily и X-HubSpot-RateLimit-Daily-Remaining. При превышении возвращается HTTP 429, а в JSON можно увидеть тип ошибки RATE_LIMIT. Тоже пригодно для автоматизации: импортёр может читать остаток, снижать скорость, планировать паузы.
У amoCRM картина другая по механике: есть конкретные ограничения частоты — 7 запросов в секунду на одну интеграцию и 50 запросов в секунду на весь аккаунт. Превышение даёт HTTP 429, а многократные нарушения могут закончиться блокировкой с HTTP 403. И вот тут «давайте просто запустим десять потоков» превращается в отличный способ устроить себе маленький DDoS по собственному аккаунту.
Битрикс24 в облачной версии для серверных OAuth-приложений ограничивает REST API до 2 запросов в секунду на одно приложение на один портал. Но даёт пакетный метод batch, где можно выполнить до 50 команд в рамках одного запроса. Это не магия, а базовая оптимизация. Кто её не использует при массовом переносе — тот добровольно платит временем.
| CRM | Как смотреть лимиты | Что критично при миграции |
|---|---|---|
| amoCRM | Следить за ответами API и кодами 429/403; учитывать опубликованные ограничения частоты | 7 запросов/с на интеграцию, 50 запросов/с на аккаунт; при повторных нарушениях возможен 403 |
| Битрикс24 облачный | Считать скорость REST-вызовов приложения; использовать batch | 2 запроса/с на приложение на портал; до 50 команд в одном batch-запросе |
| Salesforce | Читать Sforce-Limit-Info; вызывать /services/data/vXX.X/limits | Видно потребление лимитов; для крупных миграций можно открыть case на временное расширение |
| HubSpot | Читать X-HubSpot-RateLimit-Daily и X-HubSpot-RateLimit-Daily-Remaining | При превышении — 429 и RATE_LIMIT; можно строить автоограничение скорости |
Есть простой тест. Создаёте тестовый аккаунт или песочницу, подключаете будущую интеграцию, прогоняете не 10 записей, а репрезентативный кусок: хотя бы несколько тысяч объектов со всеми связями. Смотрите не только «создалось или нет», а логи HTTP: коды, заголовки, задержки, повторы, время обновления токена.
Если подрядчик по миграции не может показать эти логи, он не контролирует процесс. Он просто надеется. Надежда — плохой механизм доставки данных.
OAuth, TLS и токены: где импорт умирает без 429
Не все сбои миграции связаны с rate limit. Часть падает на авторизации и транспортном слое. Это скучно, зато больно.
amoCRM требует для безопасного подключения поддержку TLS 1.1 или TLS 1.2 и авторизацию через OAuth 2.0. При истечении Access Token API возвращает HTTP 401, после чего нужно обновлять токен через Refresh Token. Нормальный импортёр делает это автоматически и прозрачно. Кривой импортёр валится, оставляет половину базы в старом состоянии и пишет в лог «unauthorized». Великолепная диагностика. Почти как «что-то пошло не так».
Здесь есть несколько практических требований к коду миграции:
1. Refresh Token должен храниться безопасно.
Не в Excel, не в чате, не в конфиге на рабочем столе. Секреты миграции — такие же секреты, как ключи продакшена. Через них можно читать и менять клиентскую базу.
2. Обновление Access Token должно быть атомарным.
Если несколько потоков одновременно решат обновить токен, можно получить гонку и пачку 401. Потом разработчик будет ловить фантомов.
3. 401 нельзя путать с rate limit.
Это не «подождать и повторить». Это проблема авторизации. Нужен refresh, проверка scope’ов, статуса приложения и подписки.
4. HTTP 402 тоже надо обрабатывать отдельно.
В amoCRM при окончании подписки запросы на добавление или изменение данных через API блокируются сразу с HTTP 402, но чтение сохраняется 30 дней. Если миграция запланирована на край срока тарифа, это не экономия. Это саботаж календарём.
5. TLS-совместимость надо проверять до запуска.
Особенно если импортёр написан давно, крутится на старом рантайме или использует корпоративный прокси с сомнительными настройками. Безопасники любят такие прокси. Потом ненавидят их в ночь миграции.
Ошибка 401 говорит: «ты не тот». Ошибка 429 говорит: «ты слишком быстрый». Ошибка 402 говорит: «ты не заплатил». Лечить их одним retry — инженерное преступление.
Пакетные методы и endpoint’ы проверки: как не стрелять запросами по одному
Ограничения запросов API CRM не всегда означают, что перенос будет медленным. Часто они означают, что надо перестать писать импортёр как учебный скрипт для стажёра.
Битрикс24 даёт batch до 50 команд в одном запросе. Это меняет экономику переноса. При лимите 2 REST-запроса в секунду на приложение можно отправлять не 2 операции в секунду, а существенно больше команд, если они корректно упакованы. Да, batch не отменяет внутренних ограничений и не делает невозможное возможным. Но он убирает самый тупой расход: сетевой запрос на каждую мелочь.
Salesforce через endpoint /limits позволяет планировать нагрузку по фактическим остаткам. Это удобно для миграции волнами: загрузили пачку, посмотрели лимиты, адаптировали скорость, ушли в паузу, продолжили. HubSpot через daily remaining в заголовках даёт похожую возможность для дневного планирования.
Практически схема должна выглядеть так:
1. Сначала импорт справочников и пользователей.
Ответственные, воронки, статусы, пользовательские поля. Если эти сущности не подготовлены, основной импорт начнёт падать на валидации. И вы будете тратить лимит на мусорные попытки.
2. Потом компании и контакты с идемпотентностью.
У каждой записи должен быть внешний ID из старой системы. Повторный запуск не должен плодить дублей. Без идемпотентности любой 429 превращается в рулетку.
3. Затем сделки и связи.
Связи требуют уже созданных ID в новой CRM. Значит, нужно хранить таблицу соответствий старый ID → новый ID. Не в голове менеджера. В нормальном хранилище.
4. Отдельно примечания, задачи и история.
Эти сущности часто самые объёмные и наименее критичные для первого рабочего дня. Их можно грузить ночью или отдельными волнами.
5. Файлы и вложения — в самый контролируемый контур.
Там другие размеры, таймауты, иногда другие endpoint’ы. И да, там часто всплывает персональная информация, которую внезапно начинают таскать временными ссылками. Красиво горит на аудите.
Импортёр должен иметь собственный rate limiter. Не «поймаем 429 и разберёмся», а заранее настроенную скорость ниже опубликованного лимита. Для amoCRM при лимите 7 запросов в секунду на интеграцию нет смысла ставить ровно 7 и гордо биться об границу. Ставьте запас. Учитывайте сетевые всплески, параллельные процессы, retry и фоновые интеграции аккаунта.
Для всего аккаунта amoCRM ограничение до 50 запросов в секунду означает ещё одну неприятность: даже если ваш импортёр культурный, другая интеграция может жрать общий лимит. Телефония, сайт, формы, BI-выгрузка, чат-боты — весь этот зоопарк не исчезает на время миграции. Его надо инвентаризировать.
Обработка ошибок: 429 — это не баг CRM, а ваш тест на зрелость
HTTP 429 Too Many Requests — самый честный ответ сервера. Он говорит: вы превысили скорость. Не надо спорить с сервером. Надо замедлиться.
Плохая обработка выглядит так: немедленный повтор, затем ещё один, затем параллельный повтор из очереди, затем падение воркера, затем перезапуск, затем повтор всей пачки. В логах — красная икра из одинаковых ошибок. В базе — дубли и пропуски.
Нормальная обработка строится иначе:
- при 429 импортёр ставит паузу и снижает скорость;
- если CRM отдаёт заголовок с остатком лимита или временем сброса, код использует его;
- retry идёт с экспоненциальной задержкой, а не с истерикой;
- операция имеет idempotency key или внешний ID;
- после нескольких отказов пачка уходит в dead-letter очередь, а не ломает весь поток;
- метрики видны оператору миграции: текущая скорость, успешные операции, 401, 402, 403, 429, средняя задержка, остаток лимитов.
Особенно аккуратно нужно относиться к HTTP 403 у amoCRM после многократных нарушений. Это уже не «слишком быстро». Это сигнал, что аккаунт может быть заблокирован на уровне доступа. То есть вы не просто не импортировали данные. Вы ещё и положили рабочий контур.
Коды надо различать жёстко:
| Код | Что означает в контексте миграции | Что делать |
|---|---|---|
| 401 | Access Token истёк или авторизация сломана | Обновить токен через Refresh Token, проверить scope’ы и приложение |
| 402 | Запись заблокирована из-за состояния подписки, для amoCRM — при окончании тарифа | Не ретраить вслепую; проверить оплату и окно миграции |
| 403 | Доступ запрещён; в amoCRM возможен после многократных нарушений лимитов | Остановить импорт, разбирать причину, писать в поддержку |
| 429 | Превышен лимит запросов | Замедлиться, применить backoff, читать заголовки лимитов |
| 5xx | Серверная ошибка или временная недоступность | Повторять ограниченно, с задержкой и сохранением состояния |
Вот здесь безопасность пересекается с эксплуатацией. Плохо написанная миграция ведёт себя как шумный бот: много запросов, мало мозгов, агрессивные повторы. Для внешнего API это почти неотличимо от вредного трафика. Потом корпоративные пользователи удивляются, почему платформа режет доступ. Потому что вы сами выглядите как проблема.
Как проверить лимиты API до покупки тарифа
Проверка должна быть формализована. Не бюрократия ради бюрократии, а нормальная инженерная разведка перед операцией с клиентскими данными.
Шаг 1. Получить документацию именно по вашему типу приложения
У CRM могут отличаться лимиты для пользовательских токенов, серверных OAuth-приложений, marketplace-интеграций, вебхуков и внутренних импортов. Фраза «у нас API быстрый» ничего не значит. Нужна привязка к вашему способу подключения.
Для Битрикс24, например, критично, что речь об облачной версии и серверных приложениях OAuth: 2 запроса в секунду на одно приложение на один портал. Если у вас другой тип интеграции, проверяйте отдельно. Не переносите чужие цифры как заклинание.
Шаг 2. Поднять песочницу или тестовый портал
Без тестового аккаунта вы слепы. В нём надо создать реальные пользовательские поля, воронки, статусы, роли, тестовых пользователей. Иначе вы проверите не миграцию, а игрушечную форму «создать контакт».
Тестовая выборка должна включать:
- контакты с несколькими телефонами и email;
- компании с дубликатами названий;
- сделки в разных воронках;
- пользовательские поля всех типов, которые реально будут в продакшене;
- примечания и задачи;
- записи с ошибочными или пустыми значениями;
- объекты, которые требуют связей между сущностями.
Шаг 3. Включить полный HTTP-лог
Нужны метод, endpoint, код ответа, время ответа, тело ошибки, ключевые заголовки лимитов, ID операции и внешний ID записи. Персональные данные в логах маскируются. Это не обсуждается. Лог миграции не должен становиться второй утечкой клиентской базы. Да, такое тоже видели. Нет, это не «временно».
Шаг 4. Прогнать нагрузку с разными скоростями
Один прогон на малой скорости показывает корректность схемы. Второй — границы. Третий — поведение при ошибках. Цель не в том, чтобы героически выбить 429. Цель — понять, где CRM начинает сопротивляться и как ваш код реагирует.
Для систем с заголовками лимитов фиксируйте остатки. В Salesforce смотрите Sforce-Limit-Info и /limits. В HubSpot — дневные заголовки и Daily-Remaining. Для amoCRM и Битрикс24 считайте скорость и коды ответов, учитывая опубликованные ограничения.
Шаг 5. Посчитать окно миграции
После теста можно оценить реальное время. Не идеальное. Реальное: с паузами, retry, ошибками валидации, обновлением токенов, ночными окнами и фоновыми интеграциями.
Если расчёт показывает, что перенос займёт трое суток, не надо планировать его «вечером в пятницу после работы». Это не DevOps, это азартная игра с персональными данными.
Крупные базы: когда идти в поддержку за расширением лимитов
Для больших миграций иногда разумно просить временное увеличение лимитов. В Salesforce для этого открывают обращение в поддержку на период переноса базы. Это нормальный путь: описать объём, сроки, тип операций, приложение, план нагрузки.
Но не надо превращать это в религию. Нельзя гарантировать, что любая CRM бесплатно и мгновенно расширит лимиты. Некоторые платформы не публикуют точные ограничения для кастомных систем. У некоторых правила поддержки завязаны на тариф, регион, тип клиента и внутреннюю политику. Продажи могут обещать бодрее, чем инженерная поддержка потом разрешит.
Запрос в поддержку должен быть техническим, а не эмоциональным. В нём нужны:
- количество объектов по типам: контакты, компании, сделки, задачи, примечания, файлы;
- ожидаемое число API-операций;
- планируемые даты и окно миграции;
- тип авторизации и приложение;
- текущие лимиты и результаты тестового прогона;
- максимальная планируемая скорость запросов;
- использование batch-методов;
- стратегия обработки 429, 401, 403 и 5xx;
- контакт инженера, который понимает логи, а не пересылает скриншоты.
Если поддержка дала временное расширение, это не отменяет throttling. Это просто поднимает потолок. Удариться головой о потолок можно и на большей высоте.
Что должно быть в решении до того, как вы нажали «оплатить»
Перед оплатой тарифа CRM у вас уже должен быть не красивый роадмап, а технический протокол проверки. Сухой, неприятный, полезный.
Нормальный набор выглядит так:
1. Таблица лимитов по выбранной CRM и типу подключения.
Не общая статья из интернета, а именно ваш сценарий: OAuth-приложение, портал, аккаунт, интеграция.
2. Расчёт количества API-операций.
По сущностям и этапам. С коэффициентом на поиск дублей, связи и повторные попытки.
3. Результаты тестового прогона.
С реальными кодами ответов, заголовками, временем выполнения и ошибками.
4. План throttling и retry.
Какая скорость стоит по умолчанию, как код реагирует на 429, сколько попыток делает, куда складывает неудачные операции.
5. План авторизации.
Где хранится Refresh Token, как обновляется Access Token, что происходит при 401.
6. План подписки и окна работ.
Чтобы не получить HTTP 402 в середине записи и не выяснить, что чтение ещё доступно, а запись уже умерла.
7. План отката и повторного запуска.
Идемпотентность, внешние ID, таблица соответствий, контроль дублей. Без этого повторный импорт превращается в загрязнение CRM.
И да, всё это надо сделать до оплаты тарифа, если тариф покупается именно под миграцию. Иначе вы покупаете не сервис, а неопределённость. Дорогую, медленную, с логотипом CRM.
Финальная позиция простая. Лимиты API при переносе базы в CRM — не второстепенная техническая деталь. Это главный ограничитель проекта после качества самих данных. Проверяйте их в песочнице, читайте заголовки, используйте batch, различайте 401/402/403/429, заранее считайте окно миграции и не верьте обещаниям без логов. Взломщик смотрит на API как на поверхность атаки. Инженер миграции должен смотреть так же. Иначе поверхность атаки превращается в поверхность отказа — уже без всякого взломщика.