Ограничения API при интеграции CRM: расчет лимитов и защита от сбоев
В июне 2021 года amoCRM ввела общие лимиты на количество запросов к API. Для интеграций это стало не косметическим изменением, а новым правилом эксплуатации: код, который раньше мог бесконечно…
Мстислав Бокарев·Обновлено: 14 июля 2026 г.·14 мин

В июне 2021 года amoCRM ввела общие лимиты на количество запросов к API. Для интеграций это стало не косметическим изменением, а новым правилом эксплуатации: код, который раньше мог бесконечно стучаться в CRM циклом, должен был научиться считать собственную скорость. Возврат HTTP 429 при превышении квоты стал нормальным поведением платформы. При повторных нарушениях возможна эскалация до HTTP 403 и блокировка доступа к API.
Сценарий типичен. Интегратор рассчитывает пропускную способность по среднему значению, не учитывает скользящие окна и суточные квоты, запускает миграцию данных в пятницу вечером. К понедельнику — остановленные вебхуки, пропущенные лиды, тикет в поддержку с просьбой объяснить, почему «вчера всё работало». Причина обычно не в злонамеренности и даже не в слабом сервере. Причина в том, что ограничения API при интеграции CRM были восприняты как справочная строка из документации, а не как часть архитектуры.
Ограничения API — не каприз вендора. Это механизм защиты инфраструктуры от деградации. Каждый CRM-сервер обслуживает множество клиентов и параллельных приложений: телефонию, виджеты, BI-выгрузки, формы, миграции, роботов продаж, синхронизацию складов. Один неоптимизированный скрипт, делающий синхронные вызовы в цикле, способен съесть непропорционально много ресурсов. Rate limiting — тот самый скучный, но необходимый инструмент, который удерживает мультитенантную систему от превращения в общий коридор с затором.
Механика ограничений: почему CRM-системы лимитируют запросы
Rate limiting — стандартный паттерн управления нагрузкой. Он нужен не только для защиты от атак, хотя это тоже важная часть. В CRM он решает более приземлённую задачу: не дать одной интеграции ухудшить работу всего аккаунта или всей платформы.
Есть три базовые модели контроля.
- Фиксированные окна (fixed window). Лимит на N запросов за календарный интервал: секунду, минуту, час, сутки. Реализация простая, но у неё есть известный дефект — «граничный скачок». Если приложение отправило максимум запросов в конце одного окна и сразу максимум в начале следующего, фактическая нагрузка на коротком участке оказывается выше ожидаемой.
- Скользящие окна (sliding window). Лимит считается за плавающий интервал от текущего момента. Не «с полуночи до полуночи», а за последние 24 часа, последние 10 минут или другой заданный период. Такая модель лучше сглаживает пики.
- Leaky Bucket / Token Bucket. Запросы пропускаются через условное «ведро»: либо с фиксированной скоростью, либо при наличии накопленных токенов. Этот подход удобен, когда нужно не просто ограничить сумму за период, а удерживать стабильный поток.
При превышении лимита CRM обычно возвращает HTTP 429 Too Many Requests. Это не загадочный сбой и не повод немедленно повторить тот же запрос ещё десять раз. В корректной реализации клиент читает ответ, смотрит на заголовок Retry-After, если он есть, и делает паузу. Если заголовка нет, приложение всё равно должно перейти в безопасный режим: увеличить задержку, остановить часть некритичных операций, не продолжать долбить endpoint в прежнем темпе.
HTTP 429 — не ошибка приложения в бытовом смысле. Это сигнал: ваша интеграция потребляет больше ресурсов, чем ей сейчас можно. Игнорирование этого сигнала быстро превращает техническое предупреждение в операционный инцидент.
Здесь полезно отделить две вещи: лимит как численное значение и лимит как поведение системы. Число «7 запросов в секунду» или «100 000 запросов за 24 часа» — только верхняя граница. Реальная устойчивость зависит от того, как приложение ведёт себя около этой границы: умеет ли оно замедляться, переносить нагрузку, откладывать задачи, различать критические и второстепенные операции.
Именно на этом обычно ломаются интеграции. Они могут знать лимит, но не жить по нему. В коде нет очереди, нет backoff, нет отдельной обработки 429, нет внутреннего счётчика, нет режима деградации. В спокойный день это незаметно. В день миграции, массовой рассылки, импорта лидов или обновления справочника выясняется, что проверка лимитов запросов API была сделана глазами по документации, а не руками в архитектуре.
Специфика контроля нагрузки в amoCRM и Битрикс24
CRM-платформы ограничивают нагрузку по-разному. Поэтому переносить один и тот же rate limiter между amoCRM, Битрикс24 и Salesforce без адаптации — плохая идея. У них разные модели риска: где-то считают запросы в секунду, где-то процессорное время, где-то суточный API-бюджет и конкурирующие длинные операции.
amoCRM: фиксированные квоты с жёсткой эскалацией
amoCRM применяет сравнительно понятную модель контроля:
- 7 запросов в секунду — лимит на одну интеграцию.
- 50 запросов в секунду — суммарный лимит на весь аккаунт, где учитываются все интеграции вместе.
Превышение первого порога приводит к HTTP 429. Многократные нарушения могут закончиться HTTP 403. Восстановление доступа в таком случае уже не выглядит как обычная автоматическая пауза: часто приходится идти в поддержку и показывать, что интеграция действительно исправлена, а не просто ждёт следующего окна, чтобы снова разогнаться.
Особенность amoCRM — важен не только ваш сервис. На уровне аккаунта суммируются запросы всех интеграций: кастомных скриптов, установленных виджетов, телефонии, внешних форм, маркетплейс-приложений. Если в аккаунте работает несколько активных интеграций, каждая из которых считает себя «небольшой», общий поток может внезапно оказаться на границе аккаунтного лимита.
Именно поэтому фраза «мы делаем всего 5 запросов в секунду» ничего не доказывает. В одиночку — возможно, нормально. В реальном аккаунте, где параллельно идёт импорт, обновляются сделки, работают вебхуки и телефония, эти 5 запросов становятся частью общего бюджета. Если интеграция не умеет замедляться, она не просто рискует собственными операциями — она начинает конкурировать с остальными процессами продаж.
Здесь уместен простой расчёт. Если нужно перенести 20 000 сущностей, а на каждую сущность приложение делает три отдельных вызова — получить, изменить, подтвердить, — это уже 60 000 обращений. При лимите 7 запросов в секунду теоретический минимум составит больше двух часов чистой отправки без учёта повторов, ошибок, сетевых задержек и параллельных интеграций. На практике такой процесс нельзя запускать как бесконтрольный цикл. Нужны очереди, паузы, пакетирование там, где оно доступно, и контроль фактической скорости.
Битрикс24: контроль процессорного времени
Битрикс24 интересен тем, что смотрит не только на количество вызовов, но и на стоимость их выполнения. Правило формулируется через суммарное время работы конкретного метода:
- если суммарное время работы метода превышает 480 секунд за 10-минутный интервал, метод временно блокируется для всех приложений аккаунта.
Это более тонкий и одновременно более неприятный для интегратора механизм. Два запроса к одному и тому же методу могут стоить системе совершенно по-разному. Лёгкое получение карточки по идентификатору — одно. Массовый список с тяжёлым фильтром, большим объёмом данных и неудачной пагинацией — другое.
Вызов crm.lead.list с фильтром по крупной выборке способен съесть заметно больше процессорного времени, чем точечный crm.lead.get. Десять тяжёлых запросов могут приблизить аккаунт к блокировке быстрее, чем сотня лёгких. Поэтому как рассчитать лимиты API для Битрикс24 — это не только арифметика запросов в секунду. Нужно оценивать вес операций.
В Битрикс24 десять тяжёлых запросов с фильтрацией крупных таблиц могут исчерпать лимит быстрее, чем сотня лёгких вызовов. Контроль идёт по процессорному времени, а не по одному лишь количеству обращений.
Есть ещё один неприятный нюанс: блокировка может затронуть не приложение-нарушитель, а метод целиком. Если одно приложение перегрузило метод списка лидов, остальные приложения аккаунта тоже могут столкнуться с отказом по этому методу на период восстановления. Для бизнеса это выглядит странно: «почему сломалась аналитика, если импорт запускали в другом сервисе?» Но с точки зрения платформы метод перегружен, и она защищает общий контур.
Отсюда практический вывод: в Битрикс24 особенно важно избегать тяжёлых списочных операций без необходимости. Лучше чаще хранить локальный state, использовать инкрементальные изменения, аккуратно работать с пагинацией и не пытаться каждый раз «на всякий случай» перечитать весь CRM-мир.
Архитектура лимитов Salesforce: от суточных квот до Bulk API
Salesforce — самая многослойная история в этой тройке. Там лимиты зависят от редакции, лицензий, типа запроса, режима обработки и конкурентности. Это не та платформа, где достаточно поставить sleep между запросами и считать задачу закрытой.
Суточные квоты и скользящие 24 часа
Для Enterprise Edition базовая логика выглядит так:
- 100 000 API-запросов за скользящие 24 часа — базовый лимит.
- +1 000 запросов на каждую пользовательскую лицензию определённых типов.
Если у компании 50 лицензий, суммарный лимит составит 150 000 запросов за скользящие сутки. Важная часть здесь — именно «скользящие». Лимит не обнуляется в полночь. Он считается за последние 24 часа от текущего момента.
Это ломает привычную логику ночных пакетных работ. Нельзя думать так: «сейчас 23:50, добьём квоту, а через десять минут всё обновится». В скользящем окне вчерашняя нагрузка продолжает жить внутри расчёта, пока не выйдет из интервала. Поэтому интеграция должна не просто знать дневную квоту, а видеть динамику потребления: сколько уже использовано, какие задания стоят в очереди, какие процессы запланированы на ближайшие часы.
Конкурентные ограничения
Помимо суточной квоты, Salesforce ограничивает длинные одновременные запросы:
- 25 одновременных длительных запросов продолжительностью более 20 секунд в production.
- 5 одновременных длительных запросов в developer org.
Это защита от другого класса проблем. Можно не превысить суточную квоту, но упереться в конкурентность: слишком много тяжёлых операций выполняется одновременно. Для интеграции это означает, что параллелизм нельзя увеличивать бесконечно. Пять worker-процессов могут быть нормально, двадцать — уже сомнительно, если каждый запускает тяжёлые выборки.
Компактно различия выглядят так:
| Параметр | Enterprise Edition | Developer Edition |
|---|---|---|
| Суточные API-запросы | 100 000 + 1 000 на лицензию | 15 000 |
| Одновременные длинные запросы (>20 с) | 25 | 5 |
| Bulk API — пакетов в сутки | 15 000 | уточняйте в актуальной документации Salesforce |
| Bulk API — записей в пакете | 10 000 | 10 000 |
| Bulk API — размер payload | 10 МБ | 10 МБ |
Таблица полезна не сама по себе, а как напоминание: один и тот же сценарий в production и developer org может вести себя по-разному. Конкретные суточные квоты для developer-среды менялись с обновлениями платформы, поэтому их всегда стоит сверять с актуальной документацией Salesforce перед проектированием интеграции. Тестовый контур чаще упирается в ограничения раньше, и это не всегда баг интеграции. Но если тестовый контур не выдерживает даже уменьшенного профиля нагрузки, production тоже не стоит запускать «на веру».
Bulk API: массовая обработка без иллюзии бесконечности
Для больших объёмов Salesforce предлагает Bulk API. Он предназначен как раз для массовой загрузки, обновления и выгрузки данных:
- до 15 000 пакетов в сутки в production;
- суточная квота пакетов для developer org — уточняйте в актуальной документации Salesforce, она зависит от версии среды и редакции;
- до 10 000 записей в одном пакете;
- до 10 МБ payload на пакет.
Bulk API работает асинхронно: клиент отправляет задачу, сервер обрабатывает её в фоне. Это снимает часть проблем с длинными синхронными запросами, но не отменяет лимиты. Ошибка новичка — считать Bulk API «обходом ограничений». На самом деле это другой бюджет, с другими правилами. Он лучше подходит для миграций и массовых операций, но его тоже надо планировать.
В Salesforce особенно хорошо видно, что превышение квоты API CRM — не одно событие, а целый набор возможных отказов. Можно израсходовать дневной бюджет, можно набрать слишком много длинных запросов, можно неправильно нарезать пакеты, можно получить ошибки при переносе данных из-за payload, конкуренции или повторной отправки без идемпотентности.
Стратегии оптимизации: пакетная обработка и работа с кодом 429
Оптимизация API-интеграции начинается не с героического увеличения серверов. Чаще всего проблема не в том, что приложению мало CPU, а в том, что оно слишком щедро тратит чужой API-бюджет. Правильная стратегия — делать меньше вызовов, делать их тяжелее только там, где это оправдано, и аккуратно распределять нагрузку во времени.
Батчинг как основа экономии лимитов
Пакетные запросы — самый очевидный способ уменьшить расход квот. Битрикс24 предоставляет метод batch, позволяющий объединить до 50 REST-запросов в один HTTP-вызов. При этом с точки зрения интенсивности это один вызов, а не пятьдесят отдельных обращений.
Пример: нужно синхронизировать 500 контактов.
- Без батчинга: 500 отдельных запросов, больше сетевых накладных расходов, выше риск упереться в лимит.
- С батчингом по 50 операций: 10 HTTP-вызовов, меньше накладных расходов, проще управлять скоростью.
Но батчинг — не универсальный молоток. У него есть цена: сложнее обрабатывать частичные ошибки, нужно хранить соответствие между элементом пакета и результатом, нельзя бесконтрольно смешивать критические и некритические операции. Если в одном пакете обновление сделки, создание контакта и изменение пользовательских полей, при ошибке придётся аккуратно разбирать, что выполнилось, что нет, а что можно повторить без риска задвоения.
Нормальная логика оптимизации выглядит так:
1. Разделить операции по типу. Массовое чтение, массовая запись, точечное обновление, служебные запросы к метаданным — это разные потоки, и у них должен быть разный приоритет.
2. Найти повторяющиеся вызовы. Справочники, статусы, поля, воронки и пользователи часто запрашиваются на каждой итерации просто потому, что так было быстрее написать. Их нужно кэшировать.
3. Определить безопасный размер пакета. Максимум из документации не всегда оптимален. Если пакет на пределе часто падает или даёт тяжёлые частичные ошибки, лучше уменьшить размер и получить предсказуемость.
4. Добавить идемпотентность. Повтор запроса после сбоя не должен создавать дубликаты. Особенно при переносе данных: один и тот же внешний идентификатор должен приводить к обновлению той же сущности, а не к созданию новой.
5. Разнести нагрузку по времени. Не отправлять все батчи одновременно. Очередь с контролируемыми worker-процессами почти всегда безопаснее, чем параллельный запуск сотен задач.
Обработка HTTP 429: не ретраить слепо
Критическая ошибка — обрабатывать 429 как обычный временный сетевой сбой. Если приложение получает 429 и немедленно повторяет запрос, оно подтверждает платформе ровно то, что платформа уже поняла: клиент не контролирует собственную скорость.
Правильная последовательность спокойнее и скучнее:
1. Получить HTTP 429.
2. Прочитать Retry-After, если заголовок есть.
3. Приостановить отправку запросов к соответствующему endpoint или ко всей CRM, если лимит общий.
4. Вернуть задачу в очередь с отложенным временем следующей попытки.
5. При повторном 429 увеличить паузу по exponential backoff.
6. После нескольких неудачных попыток зафиксировать инцидент и остановить автоматический повтор для этого класса операций.
Здесь важно не увлечься retries. Повтор — не способ победить лимит, а способ корректно пережить временную недоступность ресурса. Если повторов слишком много, они сами становятся нагрузкой. Особенно это видно при миграциях: один неудачный пакет создаёт новую волну запросов, та получает 429, после чего очередь начинает раздуваться и давить на CRM уже повторными попытками.
Каждый возврат 429 — предупреждение. Каждый 403 — инцидент. Интеграция, которая не различает эти два состояния, рано или поздно сама организует себе простой.
Отдельно стоит говорить о приоритетах. Не все запросы одинаково важны. Создание лида из формы — критическая операция, потеря которой ударит по выручке немедленно. Обновление аналитического поля, ночная сверка справочника или отправка второстепенного статуса — нет. При приближении к лимиту хорошая интеграция должна уметь переходить в режим деградации: сначала останавливать фоновые задачи, оставляя только синхронные пользовательские сценарии. Этот же подход работает при миграциях данных — там, где обычно и возникают ошибки API при переносе данных, связанные с тем, что интегратор пытается залить всё и сразу, не оставляя зазора для оперативной работы аккаунта.
Как избежать блокировки: мониторинг и управление очередями
Лимиты — это граница, за которой начинаются разговоры с поддержкой. Грамотная интеграция должна видеть приближение к этой границе заранее, а не узнавать о ней из отказа endpoint.
Счётчики потребления как часть кода, а не отчёта
Большинство CRM отдают в ответах информацию о текущем потреблении: остаток суточной квоты, число активных конкурентных вызовов, факт приближения к порогу. Эти данные нужно читать и складывать в собственный контур наблюдения, а не выбрасывать в логи «для галочки». В amoCRM это заголовки X-RateLimit-*, в Salesforce — поле Sforce-Limit-Info и API Usage в Organization Limits.
Полезно выделить три уровня тревоги:
- зелёный — использовано меньше 60% бюджета, всё идёт штатно;
- жёлтый — 60–85%, пора снижать скорость, останавливать некритичные батчи, переходить на расширенные интервалы;
- красный — больше 85%, остановить всё, кроме критических операций, и дать окну «остыть».
Без такого градиента интеграция живёт в двух состояниях: «всё хорошо» и «упало». В реальной эксплуатации между ними всегда есть серая зона, в которой и принимаются решения.
Очереди и планировщики вместо бесконтрольных циклов
Если интеграция отправляет запросы из cron-задачи или из обработчика вебхука напрямую, она почти наверняка столкнётся с пиками. Вебхуки приходят пачками: сделка создана, обновлена, переведена по воронке, дополнена товарами, отправлено письмо — это уже пять событий за минуту по одной сущности. Если каждое тянет за собой синхронный вызов API, лимит расходуется быстрее, чем кажется на схеме архитектуры.
Правильный контур выглядит так:
1. Внешний источник события (вебхук, cron, ручной запуск) только кладёт задачу в очередь.
2. Worker-процессы забирают задачи с контролируемой скоростью.
3. Каждый worker ведёт собственный счётчик и умеет приостанавливаться.
4. При получении 429 worker не падает, а уходит в паузу и возвращает задачу в очередь с отложенным временем.
Такая схема даёт два эффекта. Во-первых, нагрузка выравнивается: пики сглаживаются, лимиты расходуются равномерно. Во-вторых, появляется место для принятия решений: можно приостановить worker, изменить приоритет задачи, перенаправить её в другой контур. В архитектуре без очереди любое из этих действий требует переписывания логики обработчика.
Circuit breaker и честная деградация
Если 429 идёт волнами и exponential backoff не помогает, пора включать circuit breaker. Принцип простой: после серии неудачных попыток интеграция временно перестаёт отправлять запросы к проблемному endpoint и переходит в режим «только чтение» или «только локальные операции». Через заданный интервал она пробует один «тестовый» запрос — и по его результату либо возвращается к нормальной работе, либо продлевает паузу.
Это не саботаж и не отказ от интеграции. Это способ не превратить временные трудности платформы в длительный простой собственного сервиса. Когда CRM «отдышалась», имеет смысл продолжить с того места, где остановились, а не продолжать стучаться в заблокированную дверь.
Превентивные практики
Несколько привычек, которые в долгую экономят нервы:
- Тестировать интеграцию не только на корректность ответов, но и на поведение при насыщении лимита. Отдельный тест-сценарий «форсируем 429» должен быть в CI.
- Хранить версию схемы лимитов вместе с кодом. Когда вендор меняет правила, в репозитории должно быть видно, когда именно это зафиксировано.
- Документировать для команды не только «как вызвать метод», но и «сколько раз в минуту это можно делать». Лимиты — такая же часть API, как и формат запроса.
- Не запускать массовые операции в часы пиковой нагрузки аккаунта. Понедельник утром и пятница вечером — плохое время для миграции данных, даже если технически окно свободно.
Ограничения API при интеграции CRM в конечном счёте — это вопрос архитектурной дисциплины. Платформа не враг интегратору, она просто требует считаться с её физикой. Там, где команда принимает эту физику как данность, встраивает лимиты в код, ведёт мониторинг и умеет замедляться, превышение квоты API CRM становится редким инцидентом, а не еженедельным сюжетом. Там, где лимиты остались справочной строкой в Confluence, любая удачная миграция заканчивается разговором с поддержкой.