Собрать самим или взять готовое: честная математика семнадцати интеграций
Разработчик оценивает интеграцию в два дня и почти всегда прав — про первую версию. Считаем, во что она обходится за год, когда источник меняет формат, ставит капчу и банит по IP.
Продакт приносит задачу: «проверять контрагента по ИНН прямо в карточке сделки». Разработчик открывает сайт налоговой, тыкает в форму, смотрит в панель разработчика браузера, видит обычный JSON и говорит: тут работы на два дня. И он не врёт.
В четверг вечером всё действительно работает. Вбиваешь ИНН — прилетает карточка: наименование, адрес, ОКВЭД, руководитель. Демо для продакта проходит на ура.
В понедельник источник начинает отвечать пятисотыми. Во вторник вместо JSON приходит требование пройти проверку картинкой. В среду выясняется, что нужен ещё справочник банков, и он обновляется каждый день. Через месяц кто-то спрашивает, почему сервер съел 29 гигабайт памяти, и вы впервые произносите вслух слова «адресный реестр ФИАС».
Мы прошли этот путь семнадцать раз — по одному на каждый сервис Atlorium. Ниже: что именно приходится держать, во что это обходится за год при честно названных допущениях и в каких случаях писать своё всё-таки правильно. Такие случаи есть, и мы их назовём.
Что начинается после четверга
Первая версия интеграции решает задачу «получить данные». Всё остальное время вы решаете задачу «получать данные каждый день, когда источник этого не хочет». Это две разные работы, и вторая стоит на порядок дороже.
Реестр ЮЛ отвечает не одним запросом, а тремя — и следит за тем, кто спрашивает
- Что происходит
- Источник устроен двухшагово: сначала запрос отдаёт идентификатор задания, потом по этому идентификатору забираются данные. Скачивание выписки добавляет третий шаг. Сессия должна быть живой, заголовок Referer — правдоподобным, повторные обращения с одного адреса получают 400, 500 или проверочную картинку.
- Во что обходится
- Пул российских прокси в аренду, ротация «до успеха» с отдельной cookie-сессией под каждый адрес, локальный кулдаун на заблокированный источником прокси, бюджеты времени на попытку и на весь запрос. У нас это 110 секунд на лёгкий поток и 180 на скачивание выписки — верхние границы, за которыми честный отказ.
- Чем закрывается
- Один GET на /api/egrul/{ИНН}. Прокси, сессии и повторы — наша забота, снаружи их не видно.
Проверочная картинка — это не «прикрутить распознавалку»
- Что происходит
- Картинка числовая, шесть цифр. Токен зашит скрытым полем в HTML диалога. У картинки есть параметр версии рендера: запросишь без него — сервер отдаст другое изображение, чьи цифры не соответствуют ответу для этого токена, и верная на вид разгадка будет отвергнута. Referer должен быть страницей самого диалога, а не страницы поиска.
- Во что обходится
- Каждая из этих трёх деталей находится не чтением документации, а разбором дампа реального браузерного трафика. Плюс подписка на распознаватель, порог уверенности, поведение при неверной разгадке и решение, что делать, когда распознаватель молчит 45 секунд.
- Чем закрывается
- Проверка на нашей стороне. Если источник её всё-таки включил и пройти не удалось — вы получаете 503, и деньги за такой запрос не списываются.
Адресный реестр отдаётся архивом, а не запросом
- Что происходит
- Полная выгрузка ГАР/ФИАС с сайта налоговой — архив от 35 ГБ. Распакованный XML занимает в пять-восемь раз больше: глобальные справочники типов плюс 96 папок регионов, в каждой — по восемь типов объектов. Обновления приходят дельтами, которые надо сливать с основными данными.
- Во что обходится
- Отдельный офлайн-конвейер, отдельная машина с десятками гигабайт свободного места и комфортным объёмом ОЗУ, отдельный движок поиска. И это ещё не гарантия результата: наша первая рабочая версия отвечала на поисковый запрос 175–204 секунды и падала по нехватке памяти при лимите в 16 ГБ. Её пришлось выбросить и переписать целиком.
- Чем закрывается
- Готовая база уже собрана и лежит у нас. Автодополнение адреса — /api/gar/suggest, поиск — /api/gar/search, целевые сто миллисекунд вместо трёх минут.
Сколько это стоит за год
Считаем четыре интеграции: реестр ЮЛ и ИП, адресный реестр, справочник БИК, проверка почты. Все допущения называем вслух — подставьте свои и пересчитайте, арифметика простая.
Допущение 1. Полностью нагруженный час разработчика — 3 000 ₽. Это не зарплата на руки: сюда входят налоги, отпуск, техника, аренда, доля тимлида и доля рекрутинга. Возьмите свою цифру.
Допущение 2. Часы — из нашего опыта, а не из оценки «на глаз». Мы эти интеграции написали, и часть из них — дважды.
| Статья | Часы | Деньги | Что внутри |
|---|---|---|---|
| Реестр ЮЛ/ИП, базовая карточка | 120 | 360 000 ₽ | Двухшаговый протокол, сессии, перебор прокси, проверочная картинка, бюджеты времени, разбор карточки |
| Реестр ЮЛ/ИП, выписка PDF | 60 | 180 000 ₽ | Скачивание выписки, обрезка до нужных страниц, извлечение структуры, сверка того, что разобрана именно та выписка |
| Адресный реестр ГАР/ФИАС | 160 | 480 000 ₽ | ETL из XML, слияние дельт, выбор движка поиска, полнотекстовый индекс, морфология, переписывание первой версии |
| Справочник БИК | 24 | 72 000 ₽ | Разбор XML, суточное обновление, снимок в памяти, мягкая деградация при недоступности источника |
| Проверка почты | 24 | 72 000 ₽ | Обвязка над внешним поставщиком: своей SMTP-проверкой доставляемость нормально не сделать (об этом ниже) |
| Общая инфраструктура | 120 | 360 000 ₽ | Подсистема прокси с ротацией и проверкой живости, слой локального хранения ответов, мониторинг, алерты |
| Разработка, итого | 508 | 1 524 000 ₽ | Примерно три месяца работы одного сильного разработчика |
Это только вход. Дальше начинается владение.
| Статья | За год | Из чего |
|---|---|---|
| Поддержка: 15 часов в месяц | 540 000 ₽ | Источник поменял вёрстку. Источник поменял версию рендера картинки. Прокси-провайдер сменил диапазон портов. Вышла новая полная выгрузка адресного реестра — надо пересобрать базу. Раз в квартал — пожар на смену: сломалось молча, узнали от клиента |
| Инфраструктура: 10 000 ₽ в месяц | 120 000 ₽ | Аренда прокси (нужны и российские, и не российские — требования у источников противоположные), подписка на распознавание картинок, квота внешнего извлекателя структуры PDF, диск и память под адресную базу |
| Владение, итого | 660 000 ₽ в год | Эта строка повторяется каждый следующий год |
Теперь вторая сторона. Оплата по факту — это цена за запрос, умноженная на объём, без абонентской платы, минимального платежа и договора с каждым провайдером отдельно. Точка безубыточности считается одной формулой:
Запросов в год, при которых своё дешевле = Годовая стоимость владения ÷ Цена одного запроса
Своих цифр мы сюда намеренно не подставляем: цены меняются, статья остаётся. Возьмите актуальную цену нужного сервиса на странице тарифов, поделите на неё 2 184 000 ₽ за первый год — и получите свой порог в запросах. Ниже порога разговор окончен. Выше — читайте раздел о том, когда своё оправдано.
Где на самом деле проходит граница
Граница проходит не по слову «интеграция», а по свойствам источника. Мы бы сформулировали её так.
Пишите сами, если источник ведёт себя как файл. Стабильный формат, публикуется по расписанию, не требует авторизации, не банит и не капчит. Справочник БИК ЦБ — ровно такой: один ZIP в сутки, три дня работы, дальше почти ноль поддержки. Если он вам нужен и у вас есть кто-то, кто раз в квартал посмотрит логи, — берите и пишите, это честно дешевле.
Покупайте, если источник ведёт себя как противник. Реестр ЮЛ и ИП не отдаёт данные — он их защищает от автоматизации: двухшаговый протокол, привязка к сессии, проверочная картинка, баны по адресу. Каждое ваше улучшение он рано или поздно встретит своим. Это не разовая работа, это подписка на гонку, оплаченная временем вашей команды.
Считайте отдельно, если источник — это данные, а не запрос. Адресный реестр — не API, а датасет: 35+ ГБ архива, ETL, движок поиска, регулярная пересборка. Если вам нужны единичные проверки адреса — брать всё это себе бессмысленно. Если вы строите поверх реестра аналитику, джойните его со своими таблицами и гоняете по нему тяжёлые выборки — API по одному адресу вам не поможет вообще, и правильный ответ здесь: тащить базу к себе.
Код: четыре источника, один ключ
Всё, что описано выше, снаружи выглядит как один GET с заголовком авторизации. Ключ
в примерах — публичный демо-ключ песочницы: он работает без регистрации и отдаёт
моки — правдоподобные, но сгенерированные данные. Они детерминированы (один и тот же
запрос даёт один и тот же ответ), так что на них можно писать тесты. Реальные данные приходят
с личным ключом. Ответ песочницы помечен заголовком X-Atlorium-Sandbox: true.
curl -H "Authorization: Bearer ak_sandbox_demo_mockdata_v1" \
"https://atlorium.com/api/egrul/7707083893"
import requests
resp = requests.get(
"https://atlorium.com/api/egrul/7707083893",
headers={"Authorization": "Bearer ak_sandbox_demo_mockdata_v1"},
timeout=30,
)
if resp.status_code == 503:
# Внешний источник недоступен. Деньги за такой запрос не списываются.
raise RuntimeError("Реестр временно недоступен, повторим позже")
data = resp.json()
if not data["found"]:
raise ValueError("Организация не найдена в реестре")
if not data["active"]:
print("Внимание: организация не действует —", data["status"])
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", "ak_sandbox_demo_mockdata_v1");
// Таймаут щедрый: источник двухшаговый, и на его стороне возможна проверка.
http.Timeout = TimeSpan.FromSeconds(30);
var resp = await http.GetAsync("https://atlorium.com/api/egrul/7707083893");
if (resp.StatusCode == HttpStatusCode.ServiceUnavailable)
throw new InvalidOperationException("Реестр временно недоступен");
var card = await resp.Content.ReadFromJsonAsync<JsonElement>();
Console.WriteLine(card.GetProperty("fullName").GetString());
{
"found": true,
"inn": "7707083893",
"ogrn": "1027700132195",
"fullName": "ПУБЛИЧНОЕ АКЦИОНЕРНОЕ ОБЩЕСТВО «СБЕРБАНК РОССИИ»",
"shortName": "ПАО СБЕРБАНК",
"status": "Действующее",
"active": true,
"address": "117312, г. Москва, ул. Вавилова, д. 19",
"primaryOkved": { "code": "64.19", "name": "Денежное посредничество прочее" },
"authorizedCapital": 67760844000.0,
"dataDate": "2026-07-13"
}
Тот же вызов на шести языках (Python, TypeScript, Go, Java, C#, PHP) — в репозитории egrul-api-client. Примеры запускаются сразу: ключ в них уже стоит демонстрационный.
Ключевые поля для принятия решения — found (есть ли субъект в реестре) и
active (действует ли он). Отдельный флаг extended=true добирает из
официальной выписки то, чего в базовой карточке нет: у ИП — почту и пол, у ЮЛ — состав
участников и их доли. Это отдельный тариф: за расширенным режимом стоит скачивание PDF,
обрезка до нужных страниц и платное извлечение структуры.
Остальные три источника — тем же ключом, тем же заголовком, тем же форматом ошибок.
KEY="ak_sandbox_demo_mockdata_v1"
# Автодополнение адреса из ГАР/ФИАС (за этим — база, собранная из десятков ГБ XML)
curl -H "Authorization: Bearer $KEY" \
"https://atlorium.com/api/gar/suggest?query=Тагил%20Новострой&limit=7"
# Банк по БИК (справочник ЦБ, обновляется ежедневно)
curl -H "Authorization: Bearer $KEY" \
"https://atlorium.com/api/cbr/044525225"
# Проверка почтового адреса перед сохранением лида
curl -H "Authorization: Bearer $KEY" \
"https://atlorium.com/api/emailvalidation?email=ivan@example.com"
{
"email": "ivan@example.com",
"status": "Valid",
"statusRaw": "valid",
"domain": "example.com",
"mxFound": true,
"catchAllDomain": false,
"freeEmail": false
}
Тот же вызов на шести языках (Python, TypeScript, Go, Java, C#, PHP) — в репозитории gar-fias-address-api-client. Примеры запускаются сразу: ключ в них уже стоит демонстрационный.
Что делать с вердиктом проверки почты — таблица решений. Это ровно те значения, которые
возвращает поле status:
| Значение | Что это | Решение |
|---|---|---|
Valid | Ящик существует и принимает почту | Сохраняем, пишем |
Invalid | Ящика нет либо домен не принимает почту | Не сохраняем: письмо отскочит |
CatchAll | Домен принимает почту на любой адрес — проверить конкретный ящик снаружи нельзя | Сохраняем, но в прогрев рассылки не берём |
SpamTrap | Адрес-ловушка для спамеров | Не сохраняем ни при каких условиях |
Abuse | Владелец раньше жаловался на спам | Сохраняем, но исключаем из рассылок |
DoNotMail | Ролевой ящик, одноразовый домен или токсичный адрес | Для регистрации годится, для рассылки — нет |
Unknown | Почтовый сервер не ответил или применил greylisting | Повторить позже. Такой запрос не тарифицируется — поставщик за него тоже не берёт денег |
Когда своё — правильный ответ
Мы продаём API, и было бы удобно закончить статью на «покупайте всегда». Это было бы неправдой. Есть четыре ситуации, в которых своя интеграция объективно выигрывает, и если вы в одной из них — считайте, а не покупайте.
Очень большой объём. Поделите годовую стоимость владения на цену запроса из тарифов. Выше получившегося порога своя реализация дешевле, и чем дальше, тем заметнее: её стоимость почти не растёт с числом запросов, а оплата по факту растёт линейно. Только считайте всерьёз: в порог входит и поддержка, и инфраструктура, и месяцы, которые разработчик не делал продукт.
Данные не должны покидать ваш контур. Банковская тайна, объекты КИИ, требования регулятора или собственная политика: если сам факт отправки ИНН клиента наружу — нарушение, вопрос закрыт. Никакая экономия этого не перевешивает.
Вам нужна база, а не ответы. Аналитика по всему адресному реестру, джойн ГАР с вашей географией доставки, ночные пересчёты по миллионам строк. Запросный API тут не инструмент — нужен датасет у себя. Кстати, именно так устроены мы: адресная база лежит у нас файлом, потому что для этой задачи другого способа нет.
Источника у нас просто нет. Семнадцать сервисов — это не весь мир. Нужен отраслевой реестр, которого в списке нет, — писать придётся самим, и наш опыт выше подскажет, к чему готовиться.
Чего это не умеет
Покупка API не отменяет зависимость от источника — она переносит на нас работу по её обслуживанию. Если реестр лежит, у нас тоже нет данных: вы получите 503, и деньги за такой запрос не спишутся, но данные из воздуха не появятся. Обещать «100% доступности поверх источника, который сам недоступен» мы не будем.
Мы не гарантируем полноту и юридическую силу сведений госреестров. Отдаём то, что отдал официальный источник, — в том виде, в котором он это отдал. Если в реестре ошибка, она приедет к вам.
Проверка почты отвечает на вопрос о доставляемости: существует ли ящик, принимает ли домен почту,
не одноразовый ли он и не ловушка ли. Читает ли этот ящик живой человек — она не знает, письмо
при проверке не отправляется. Статус CatchAll — это честное «проверить невозможно»,
а не завуалированное «плохо».
Повторный запрос по тому же идентификатору тарифицируется как новый: вы платите за обращение к сервису. Кэш на вашей стороне — законный и правильный способ платить меньше, и мы прямо рекомендуем его тем, у кого сценарий бьёт по одним и тем же ключам.
И арифметика из этой статьи — не универсальный закон. Это наши часы, наша ставка, наш набор источников. У вас может быть дешевле команда, проще требования или уже написанная половина. Формулы выше — чтобы вы посчитали своё, а не поверили нашему.
Частые вопросы
Частые вопросы
Сколько стоит своя интеграция с ЕГРЮЛ?
Первая рабочая версия — действительно два-три дня. Полная реализация с обходом защиты от автоматизации у нас заняла около 120 часов на базовую карточку и ещё 60 на выписку в PDF. При ставке 3 000 рублей за полностью нагруженный час это порядка 540 тысяч рублей, не считая аренды прокси, подписки на распознавание проверочных картинок и последующей поддержки.
Можно ли получать данные из реестра ЮЛ без прокси?
С одного адреса — недолго. Источник агрессивно ограничивает автоматизацию: отвечает ошибками или включает проверочную картинку. Для устойчивой работы нужен пул адресов с ротацией, отдельная сессия под каждый адрес и повтор всего сценария при блокировке. Мы держим именно такую схему, включая временное исключение заблокированного адреса из ротации.
Сколько весит база ФИАС и что нужно, чтобы её развернуть?
Полная выгрузка ГАР с сайта налоговой — архив от 35 гигабайт, распакованный XML занимает в пять-восемь раз больше. Нужен отдельный конвейер подготовки, десятки гигабайт свободного места и достаточный объём оперативной памяти на время сборки. Готовая поисковая база — единицы-десятки гигабайт, и её надо периодически пересобирать под новые выгрузки.
Что дешевле — платить за API или написать своё?
Разделите годовую стоимость владения своей реализацией на цену одного запроса из тарифов. Получится объём в запросах, выше которого своё дешевле. По нашему расчёту стоимость владения четырьмя интеграциями — около 660 тысяч рублей в год после того, как разработка уже оплачена. При небольших и средних объёмах оплата по факту выигрывает с большим отрывом, при очень больших — проигрывает.
Что будет, если внешний источник недоступен?
Запрос завершится кодом 503, и деньги за него не спишутся. Это осознанная политика: клиент не платит за сбой, который произошёл не у него. Данные при этом всё равно не появятся — покупка API снимает с вас работу по обслуживанию источника, но не делает сам источник надёжнее.
Можно ли попробовать до регистрации?
Да. Публичный демо-ключ ak_sandbox_demo_mockdata_v1 работает без аккаунта и без карты: можно скопировать curl из статьи и сразу получить ответ. Он отдаёт моки — правдоподобные сгенерированные данные, детерминированные для одного и того же запроса, поэтому на них удобно писать тесты. Реальные данные приходят только с личным ключом.
Сервисы из этой статьи
Карточка организации по ИНН/ОГРН: реквизиты, статус, руководитель, ОКВЭД, выписка PDF
Реквизиты банков по БИК из справочника ЦБ РФ: корсчёт, регион, SWIFT
Проверка доставляемости адреса: существует ли ящик, MX, catch-all, одноразовый ящик, спам-ловушка, подсказка по опечатке
Попробовать прямо сейчас — без регистрации
Демо-ключ ak_sandbox_demo_mockdata_v1 — публичный и общий для всех.
С ним API отвечает моками: данные правдоподобные, но сгенерированные,
и они не меняются от запроса к запросу — на них удобно писать тесты.
Настоящие данные приходят с личным ключом.
curl -H "Authorization: Bearer ak_sandbox_demo_mockdata_v1" \
https://atlorium.com/openapi/egrul_ru.json