Как обнаружить, что интеграция передаёт только часть данных

Сверка полноты данных между источником и получателем интеграции
Содержание 10 разделов

Пагинация, лимиты API, часовые пояса, округления и «успешный» HTTP-ответ, за которым прячется потерянная информация

Почему «всё работает» не значит «всё передалось»

Стандартный мониторинг интеграции отвечает на вопрос «выполнился ли запрос». Он смотрит на HTTP-код, на факт завершения задачи, на отсутствие исключений в логе. Вопрос «действительно ли все записи оказались на другой стороне» — это уже не мониторинг доступности, а сверка данных, и её реализуют куда реже, чем банальный health-check.

Разрыв между «запрос успешен» и «данные полные» проявляется по-разному, но у него методологически одна причина, которую хорошо формулирует материал о рассинхронизации API-интеграций: пагинация становится ненадёжной именно тогда, когда она перестаёт быть частью одного запроса-ответа и превращается в часть более крупной системы — с ретраями, параллельными нагрузками и изменяющимися данными в процессе выгрузки [1]. Похожая логика применима и к лимитам, и к часовым поясам, и к округлениям: по отдельности каждый механизм работает штатно, а проблема возникает на стыке — когда предположения одной системы не совпадают с предположениями другой.

Для бизнеса это означает конкретный практический риск: отчётность, начисления, остатки на складе или статус заявки могут расходиться с реальностью не потому, что кто-то ошибся при вводе данных, а потому что интеграция между CRM, 1С, банком, маркетплейсом или государственной системой незаметно потеряла часть записей ещё на этапе передачи.

Пять типовых мест, где интеграция теряет данные

1. Пагинация: страница потеряна, а вызов зелёный

Большинство API отдают данные постранично, чтобы не возвращать за один запрос десятки тысяч записей. Проблема начинается не с самой пагинации, а с условия, по которому клиент решает, что страницы закончились.

Частая ошибка — прекращать запросы, когда сервер вернул страницу короче максимального размера, вместо того чтобы ориентироваться на явный флаг «есть ли следующая страница». На интеграциях с Xero это приводило к пропуску последней порции записей ровно на границе размера страницы: если аккаунт содержит, например, 100 счетов при лимите страницы в 100 записей, первый запрос отдаёт все 100 без признака следующей страницы, и некоторые реализации ошибочно считают выгрузку завершённой; при 101 счёте вторая страница физически существует, но не будет запрошена, если логика останавливается по признаку «страница пришла неполной», а не по явному флагу продолжения [2].

Второй источник потерь — оффсетная пагинация на изменяющихся данных. Пока клиент проходит страницу за страницей, в источник могут добавляться или удаляться записи, и это сдвигает нумерацию: часть строк из-за смещения не попадает ни на одну из запрошенных страниц. NetSuite, например, возвращает в первом ответе оценочное количество записей, и если во время обхода часть транзакций удаляется, эта оценка перестаёт быть точной — интеграция может завершить пагинацию раньше времени, оставив пробел, который проявится при сверке, но не появится ни в одном логе ошибок [2]. Технический разбор причины хорошо резюмирует: корень большинства багов пагинации — использование оффсета на изменяемых данных, и переход на курсорную или keyset-пагинацию устраняет большинство таких сценариев [3].

Есть и более прикладной случай: сборка данных не по документации, а «как получилось». В одном из открытых репозиториев обёртка над API получала только первую страницу результатов по умолчанию (лимит — 30 элементов), и любой запрос с большим количеством файлов или коммитов молча возвращал неполный набор — без единой ошибки [4].

Как обнаружить: сверить итоговое количество полученных записей с ожидаемым (счётчиком в самом API, если он есть, или подсчётом по источнику напрямую); логировать не только факт запроса каждой страницы, но и явный признак «это была последняя страница»; отдельно тестировать выгрузку на объёме, кратном размеру страницы, и на объёме на единицу больше — именно на границе чаще всего и рвётся логика [2].

2. Лимиты и троттлинг: запрос не упал, он просто пропал

Ограничение частоты запросов (rate limiting) — это не авария, а штатный ответ провайдера API: «технически я могу обработать твой запрос, но не сейчас» [5]. Проблема в том, что для интеграции, которая не обрабатывает это состояние отдельно, HTTP 429 выглядит как рядовая неудача, которую можно просто пропустить и продолжить со следующей записью.

Наблюдение из практики автоматизации точно описывает эффект: 429 — это не сбой, автоматизация продолжает работать, она просто пропускает конкретный запрос; если это не залогировано и не видно явно, о том, что данные не синхронизировались, никто не узнает — в панели всё выглядит здорово, а ошибка сидит в самих данных [6]. Похожий сценарий фиксируют и специализированные средства мониторинга: индикаторы аптайма остаются зелёными, счётчик ошибок — низким, а по факту сервис в это время был «тихо отрезан» от стороннего API на десятки минут — без единого падения, только 429 вместо 500 [7].

Отдельная сложность в том, что лимиты бывают многослойными: по числу запросов в минуту, по объёму данных, по параллельным соединениям — и превышение любого из них выглядит одинаково с точки зрения кода ответа, но требует разной реакции.

Как обнаружить: отдельно считать долю ответов 429 (и вообще нестандартных кодов) как самостоятельный класс инцидентов, а не смешивать с 5xx; хранить неотправленные из-за лимита запросы в очереди для повторной отправки вместо того, чтобы просто идти дальше; ограничивать автоматические ретраи разумным числом попыток и обязательно эскалировать в явную ошибку, если все попытки исчерпаны, вместо тихого пропуска записи [5] [6].

3. Часовые пояса: данные на месте, но не там, где их ищут

Часовой пояс — один из немногих источников потерь, где данные физически существуют в системе, но не находятся при выборке за период, потому что запрос и хранилище по-разному интерпретируют границу суток.

Показательный разбор одной такой ошибки: функция получала правильное смещение для летнего времени зимой и неправильное — летом, потому что не учитывала переход на летнее время для конкретной даты запроса, а брала текущее смещение на момент выполнения кода. Тесты, которые запускались зимой, проходили; синхронизации данных периодически теряли записи или подтягивали не тот диапазон дат — в зависимости от того, в какой период действия летнего/зимнего времени выполнялся запрос [8].

Похожий эффект возникает и без ошибок в коде — просто из-за архитектуры системы. В отчётности Jira и Atlassian Analytics нет единого «часового пояса Jira»: разные части системы используют разную логику, и один и тот же таймстамп, скажем, 23:30 UTC, может относиться к «сегодня» для одного пользователя и к «завтра» — для другого, в зависимости от того, какой слой интерпретирует момент времени: группировка по дню в отчёте, поиск по JQL, начинающий отсчёт с полуночи в настроенном часовом поясе, или преобразование в локальное время на дашборде [9]. С банковскими и CRM-интеграциями фиксируется тот же класс проблем: если часовой пояс во внешней системе не совпадает с часовым поясом источника, записи получают некорректные метки времени, а переход на летнее/зимнее время добавляет ещё один слой рассинхронизации, который внешняя система может не обрабатывать автоматически [10].

Отдельный, более редкий, но показательный случай — переход на летнее время создаёт сутки из 23 или 25 часов, и если интеграция использует строковое представление времени как ключ в словаре или в качестве уникального идентификатора записи, вторая «01:00» в 25-часовых сутках может перезаписать первую — час данных теряется физически, а не просто «не находится» [11].

Как обнаружить: сверять суммарное количество записей за период по UTC-времени и по локальному времени отдельно и сравнивать результат; для дат без явного времени (например, только «дата документа») отдельно проверять, к какому часовому поясу привязана эта дата на обеих сторонах интеграции; при выгрузке использовать уникальный идентификатор события (эпоху в секундах), а не строковое представление локального времени, там, где событие должно быть однозначно различимо [11] [9] [10].

4. Округления: количество записей совпадает, суммы — нет

Если количество записей на входе и выходе совпало, это ещё не значит, что данные передались без потерь: обзор практики сверки данных отдельно фиксирует случай, когда количество записей совпадает, а итоговые суммы — нет, и это указывает не на пропавшую запись, а на ошибку преобразования: округление, конвертацию валюты, усечение типа данных или несогласованную обработку часовых поясов, — то есть на что-то, что меняет значение поля, не меняя число записей [12].

Техническая причина в большинстве таких случаев — использование чисел с плавающей точкой (float/double) для денежных величин там, где нужен тип с фиксированной точностью. Число 100,45 не представимо в двоичной системе с плавающей точкой точно, и при многошаговых вычислениях (сложение, распределение скидки, конвертация валюты) такие погрешности накапливаются, а не компенсируют друг друга [13]. Отдельная рекомендация из практики финансовых расчётов — округлять только на последнем шаге вычислений, после того как все промежуточные операции выполнены с максимальной доступной точностью, а не на каждом шаге отдельно: рассинхронизация правил округления между разными частями процесса — частая причина расхождений в итоговых суммах [14].

Как обнаружить: сверять не только количество записей, но и контрольные суммы по ключевым числовым полям (сумма, количество, итог) — это стандартный элемент методологии сверки данных наряду со сверкой по количеству записей [15]; при интеграции с финансовыми и учётными системами (в том числе 1С) проверять, какой тип данных используется для сумм на обеих сторонах обмена, а не полагаться на визуальное совпадение значений в интерфейсе.

5. HTTP 200 при фактической ошибке операции

Это, вероятно, самый коварный случай: код ответа сообщает об успехе, а операция внутри — нет.

Практика нормализации ошибок сторонних API описывает это прямо: реальная ошибка спрятана внутри массива errors в теле ответа, и стандартные средства мониторинга, которые следят за 5xx-ответами, полностью «слепы» к таким сбоям; Slack, например, тоже может вернуть 200 OK с телом {"ok": false, "error": ...} [16]. Разбор инцидентов в производственных системах формулирует последствие для эксплуатации ещё жёстче: если API возвращает 200 OK для ошибок бизнес-логики, ошибок валидации и даже перехваченных серверных исключений, дашборд мониторинга покажет 100% доступности, даже если система полностью не работает; всплеск ошибок вида «пользователь не найден» не вызовет стандартный алерт по HTTP 5xx, и команда не узнает о проблеме до жалоб клиентов [17].

Встречается и «мягкая» версия того же паттерна на уровне бэкенда: ошибки, возникающие внутри обработчика (например, сбой стороннего сервиса или хранилища), перехватываются внутренним блоком try/except, логируются или возвращаются через колбэк, но не пробрасываются наружу — в результате внешний маршрут API остаётся в неведении, что что-то пошло не так, и отвечает 200 OK со статусом «в обработке» даже тогда, когда операция реально завершилась ошибкой [18].

Как обнаружить: проверять не только код ответа, но и структуру и содержимое тела ответа на соответствие ожидаемой схеме успешного результата — если поля, которые должны быть в успешном ответе, отсутствуют или содержат сообщение об ошибке, это повод считать операцию неуспешной независимо от кода [19]; логировать пару «код ответа + тело ответа» вместе, а не только код; для критичных операций (платежи, отправка документов, создание записей в учётной системе) добавлять отдельную проверку по факту — например, последующий запрос, подтверждающий, что запись действительно появилась там, куда её должны были передать.

Российская специфика: 1С, банковские API и одиннадцать часовых поясов

Для интеграций внутри России эти пять источников потерь накладываются на несколько дополнительных особенностей.

1С как одна из сторон обмена. Обмен с 1С часто строится не как разовая синхронизация, а как обмен только изменёнными данными по планам обмена — и здесь особенно важны версионирование API, отдельные пути для чтения и записи, встроенные механизмы ограничения скорости и обязательный журнал статусов отправки и приёма с возможностью повторной доставки [20] [21]. Указанные ранее проблемы пагинации и лимитов проявляются в обмене с 1С так же, как и в любой другой интеграции, но добавляется риск двусторонней синхронизации: если правила двустороннего обмена не описаны заранее, интеграция может создавать дубли и перезаписывать данные при расхождении между системами [22].

Одиннадцать часовых поясов. Для бизнеса с филиалами или клиентами в разных регионах России ошибки часовых поясов, описанные выше, не абстрактный сценарий из зарубежной практики, а ежедневная рабочая ситуация: документ, оформленный по местному времени в одном регионе, при выгрузке в центральную систему учёта может «переехать» на другую календарную дату, если обмен не фиксирует явно, в каком часовом поясе указано время документа.

Банковские и государственные API. Интеграции с банковскими API (например, для выписок и платежей) требуют не только технической настройки обмена, но и организационных шагов — оформления сертификатов электронной подписи, участия единоличного исполнительного органа — и здесь тихая потеря данных особенно дорого стоит: расхождение в выписке или незамеченный статус платежа напрямую влияет на бухгалтерию и казначейство [23]. Похожая логика применима к обмену с любыми государственными системами и маркетплейсами: наличие документированного API не означает, что все операции и объёмы выгрузки работают без ограничений, и это стоит проверять отдельно для каждого конкретного случая, а не считать само собой разумеющимся.

Как встроить контроль в интеграцию: варианты реализации

Обнаружение частичных потерь данных — это не одна функция, а комбинация практик, которые можно внедрять по отдельности или вместе, начиная с самых дешёвых.

Сверка по количеству записей. Простейший и самый дешёвый способ — после каждой синхронизации сравнивать количество записей, полученных из источника, с количеством, реально сохранённых в приёмнике, за тот же период или тот же фильтр. Методология сверки данных отдельно указывает: это только первый уровень проверки, и совпадение количества не гарантирует совпадения значений — нужен как минимум ещё один уровень [24].

Сверка по контрольным суммам и агрегатам. Второй уровень — сравнение сумм, средних, минимумов и максимумов по ключевым числовым полям между источником и приёмником. Это стандартный метод в арсенале инструментов класса ETL-валидации и позволяет заметить именно те расхождения, которые не видны при простом подсчёте записей — округления, потери точности, ошибки трансформации [15] [25].

Явный признак «последней страницы» вместо эвристики по размеру ответа. Для устранения пагинационных потерь стоит опираться на явный флаг продолжения (hasNextPage, cursor, nextpagetoken), который отдаёт API, а не на предположение «если страница пришла короче лимита — данные закончились» [2].

Отдельный класс алертов для «мягких» ошибок. Ответы с кодом 429 и ответы 200 с признаком ошибки внутри тела стоит логировать и мониторить отдельно от привычных 5xx — иначе они остаются невидимыми для стандартных дашбордов доступности [7] [16].

Контроль на границе часовых поясов и объёмов. Отдельно тестировать интеграцию на переходах летнего/зимнего времени и на объёмах данных, кратных размеру страницы плюс единица — именно здесь чаще всего проявляются оба типа проблем [8] [2].

Какой из вариантов выбрать в первую очередь, зависит от того, что конкретно передаётся: для операционных данных (заявки, статусы, остатки) критичнее сверка по количеству записей и явный признак пагинации; для финансовых и учётных данных — сверка по суммам и контроль округлений; для интеграций с внешними API, где часто применяются лимиты — отдельный мониторинг 429 и очередь повторной отправки.

Практические этапы внедрения контроля

  1. Инвентаризация точек обмена. Определить, какие данные, с какой периодичностью и через какой протокол передаются между системами, и какие из них уже могли терять записи незаметно.
  2. Проверка условия окончания пагинации. Проверить код или конфигурацию интеграции на предмет того, как определяется последняя страница выгрузки — по явному флагу или по эвристике.
  3. Отдельный лог для 429 и 200-с-ошибкой. Настроить логирование и алерты для этих двух классов ответов отдельно от обычных сбоев.
  4. Сверка по количеству и по суммам. Добавить регулярную (например, ежедневную или после каждой синхронизации) автоматическую сверку итогов между источником и приёмником.
  5. Тестирование на граничных условиях. Прогнать интеграцию на объёме данных, кратном размеру страницы, на переходе летнего/зимнего времени и на сценарии одновременного изменения данных во время выгрузки.
  6. Документирование ожидаемого поведения. Зафиксировать, какой часовой пояс используется для дат без явного времени, какая точность применяется для денежных величин и как обрабатывается частичный успех операции.

Ограничения, типичные ошибки и риски

Полностью исключить потерю данных нельзя — можно только снизить вероятность и сократить время до обнаружения. Стоит учитывать:

  • Сверка по количеству записей не заменяет сверку по значениям — совпадение числа записей при расхождении сумм встречается регулярно и требует отдельной проверки [12].
  • Автоматические ретраи на 429 без ограничения числа попыток и без явной эскалации при исчерпании попыток создают иллюзию надёжности, а на деле маскируют реальные потери [5].
  • Тестирование интеграции на staging-окружении с малым объёмом данных часто не выявляет пагинационных багов — они проявляются только на объёмах, кратных или превышающих размер страницы, которые редко присутствуют в тестовых базах [1].
  • Сообщение о часовом поясе в документации API может не совпадать с фактическим поведением при пересечении границы летнего/зимнего времени, и это стоит проверять эмпирически, а не полагаться на описание [8].
  • Кеширование ответов, включая ошибочные 200 OK, на уровне CDN или прокси способно продлевать эффект сбоя на часы после того, как исходная причина уже устранена [17].

Что учитывать при выборе решения

Не любой из описанных случаев требует отдельной разработки. Если объём данных небольшой, а обмен идёт через готовый коннектор известного сервиса или через 1С:ДиректБанк и аналогичные типовые решения, для начала может быть достаточно настроить регулярную сверку количества записей вручную или через существующие средства мониторинга. Отдельная разработка модуля сверки, контрактных тестов или мониторинга по кодам ответа оправдана, когда: объём передаваемых данных регулярно приближается к границам пагинации или лимитов API; интеграция затрагивает финансовые или учётные данные, где расхождение в суммах напрямую влияет на отчётность; система уже показывала случаи расхождения данных без видимых ошибок в логах.

Команда «Пятого фактора» может изучить существующую схему обмена данными, проверить, как реализована обработка пагинации, лимитов, часовых поясов и кодов ответа, и предложить конкретные доработки — от добавления сверки и явного логирования «мягких» ошибок до пересмотра логики выгрузки на границе страниц. Если интеграция строится с нуля — например, обмен с банковским API, 1С или сторонним сервисом — команда может спроектировать архитектуру обмена с учётом описанных рисков сразу, не дожидаясь, пока расхождение обнаружится постфактум при сверке отчётности.

Вывод

Интеграция, которая не падает, — не то же самое, что интеграция, которая передаёт все данные. Пагинация, лимиты API, часовые пояса, округления и обманчиво успешные HTTP-ответы — это пять разных технических механизмов, но у них общая логика проявления: статус выполнения запроса и фактическое содержимое данных расходятся, а стандартный мониторинг следит только за первым. Единственный надёжный способ заметить это — не полагаться на отсутствие ошибок в логе, а регулярно сверять количество записей и контрольные суммы между источником и приёмником, отдельно отслеживать «мягкие» коды ошибок и явно тестировать интеграцию на границах — по объёму, по времени и по параллельной нагрузке. Чтобы обсудить конкретную интеграцию или получить консультацию, свяжитесь с командой «Пятого фактора» любым удобным способом.

Источники

[1] unified.to — API Pagination: Why It Breaks Multi-Integration Systems (and How to Fix It) — https://unified.to/blog/api_pagination_why_it_breaks_multi_integration_systems_and_how_to_fix_it

[2] apideck.com — API Integration Challenges: What Actually Breaks at Scale — https://www.apideck.com/blog/api-integration-challenges

[3] getknit.dev — Common API Pagination Errors and How to Fix Them (2026) — https://www.getknit.dev/blog/how-to-handle-common-errors-and-invalid-requests-in-api-pagination

[4] github.com — Missing Pagination Handling in Gitea Provider API Wrappers · Issue #2138 · The-PR-Agent/pr-agent — https://github.com/The-PR-Agent/pr-agent/issues/2138

[5] getknit.dev — API Rate Limiting Best Practices (2026): Implementation Guide for Developers — https://www.getknit.dev/blog/10-best-practices-for-api-rate-limiting-and-throttling

[6] abhiman.io — API Rate Limits - How They Break Your Automations — https://abhiman.io/blog/api-rate-limits-explained/

[7] web-alert.io — API Rate Limit Monitoring: 429 Errors and Throttling —https://web-alert.io/blog/api-rate-limit-monitoring-throttling-429-alerting

[8] blog.arkency.com — The timezone bug that hid in plain sight for months — https://blog.arkency.com/the-timezone-bug-that-hid-in-plain-sight-for-months/

[9] community.atlassian.com — Timezones in Jira reporting: why dates look off — https://community.atlassian.com/forums/App-Central-articles/Timezones-in Jira-reporting-why-dates-look-off/ba-p/3205133

[10] medium.com — Salesforce API Timezone. Handling timezones correctly — https://medium.com/@aleksej.gudkov/salesforce-api-timezone-961c17da3bf7

[11] dev.visualcrossing.com — The Mystery of the 23-Hour Day: Understanding Daylight Saving Time in Weather Data — https://dev.visualcrossing.com/resources/blog/understanding-daylight-saving-time-in-weather-data/

[12] guru99.com — What is Data Reconciliation? Definition, Process, Tools — https://www.guru99.com/what-is-data-reconciliation.html

[13] medium.com — Handling Precision in Financial Calculations in .NET — https://medium.com/@stanislavbabenko/handling-precision-in-financial-calculations-in-net-a-deep-dive-into-decimal-and-common-pitfalls-1211cc5edd3b

[14] enerpize.com — What is the Rounding Error Meaning in Accounting with Examples — https://www.enerpize.com/hub/rounding-error

[15] tricentis.com — What is data reconciliation? A practical guide — https://www.tricentis.com/learn/data-reconciliation

[16] truto.one — 404 Reasons Third-Party APIs Can't Get Their Errors Straight (And How to Fix It) — https://truto.one/blog/404-reasons-third-party-apis-cant-get-their-errors-straight-and-how-to-fix-it/

[17] compiler.today — 200 OK: The 'Success' Response That Was Actually a Critical Error — https://www.compiler.today/api-development/200-ok-the-success-response-that-was-actually-a-critical-error

[18] github.com — Collections endpoints: Silent Failures Causes Incorrect 200 Responses on Error #238 — https://github.com/ProjectTech4DevAI/ai-platform/issues/238

[19] rankpa.com — Experiencing Error Code 200: What It Means and How to Handle It — https://rankpa.com/experiencing-error-code-200/

[20] binavigator.ru — Современная интеграция 1С: REST API, OData и асинхронность — https://binavigator.ru/articles/servisy-1s/sovremennaya-integratsiya-1s-rest-api-1s-shina-i-arkhitektura-besshovnykh-resheniy/

[21] datafinder.ru — Инструменты обмена данными в 1С: выгрузка/загрузка, обмен через API, интеграционные сервисы — https://datafinder.ru/products/sistemy-etl-i-elt/proektirovanie-hranilishcha-dannyh-na-osnove-1s/instrumenty-obmena-dannymi-v-1s-vygruzkazagruzka-obmen-cherez-api-integracionnye-servisy

[22] netlab-com.ru — Интеграция 1С с другими внешними сервисами по API — https://netlab-com.ru/services/integratsiya-1c-s-drugimi-vneshnimi-servisami-po-api/

[23] 5factor.ru — СберБизнес API: выписки, платежи и mTLS — https://5factor.ru/resources/integracziya-sberbiznes-api-s-1s-i-korporativnymi-sistemami

[24] icedq.com — Data Reconciliation Tool | Automate Data Validation with iceDQ — https://icedq.com/data-reconciliation-tool

[25] datagaps.com — Data Reconciliation Best Practices with DataOps Suite ETL Validator — https://www.datagaps.com/blog/data-reconciliation-best-practices/

Быстрые вопросы и ответы

Почему интеграция может возвращать успешный ответ, но терять данные?

Успешный HTTP-ответ подтверждает выполнение запроса, но не полноту результата. Часть записей может потеряться из-за пагинации, лимитов API, фильтров, округления времени или ошибок обработки отдельных объектов.

Как быстрее всего проверить полноту передачи данных?

Сравните количество и контрольные показатели по одинаковым периодам в источнике и приёмнике, затем проверьте пропуски по идентификаторам, времени изменения и страницам ответа API.

Какие метрики нужны для постоянного контроля интеграции?

Полезны число прочитанных, переданных, принятых и отклонённых записей, длительность обработки, отставание по времени, число повторов и размер очереди ошибок.

Поможет ли повторный запуск вернуть потерянные записи?

Только если процесс поддерживает идемпотентность и повторяет точный диапазон. Иначе повторный запуск способен создать дубли или снова пропустить те же данные.

Что должно остаться после диагностики?

Нужны воспроизводимый тест, перечень причин, исправленный алгоритм выборки, автоматическая сверка и оповещение, которое срабатывает до обращения пользователей.

Нужна помощь по этой задаче?
На странице услуги «Контроль качества данных ETL и импортов» указаны состав работ, результат и фиксированная цена.