Наш стек сквозной аналитики для SaaS-сервиса: коннекторы, хранилище, BI и как мы сводили данные

от автора

Привет, на связи Дмитрий Шестаков. Мы в агентстве собираем сквозную аналитику для онлайн-сервисов с длинным циклом сделки, и почти каждый проект начинается с одной и той же сцены: Директ показывает одно число заявок, Метрика другое, CRM третье, и все три системы уверены в своей правоте. Ниже разберу наш стек как он есть — какие слои данных нужны, по каким ключам они связываются, чем забираем выгрузки, где спотыкались сами. С замерами реального проекта, где расход в Директе за период превысил полтора миллиона рублей. Если вы отвечаете за окупаемость трафика SaaS-сервиса, схема переносится почти без изменений.

Почему три системы дают три разных числа по одной кампании

Расхождение цифр — не баг конкретного счетчика, а следствие того, что каждая система отвечает на свой вопрос. Директ атрибутирует конверсии последнему переходу из Директа и считает их в собственном окне. Метрика по умолчанию живет по последнему значимому переходу и видит цели, а не сделки. CRM оперирует сделками и до момента интеграции вообще не в курсе, что такое кампания: пока метки не приехали вместе с заявкой, в поле источника у сделки пусто. Три честные системы, три разных вопроса, три разных ответа.

На длинном цикле все это усиливается. Типичный путь клиента B2B SaaS: клик по горячему коммерческому запросу, две недели тишины, возврат через брендовый поиск, еще через неделю заявка со статьи в блоге. По последнему клику вся заслуга уедет брендовой кампании.

Хотя привел человека совсем другой канал.

Сводка по контексту в Яндекс DataLens: миллионы показов вверху воронки превращаются в сотни форм и заявку около 10 тысяч рублей

Сводка по контексту в Яндекс DataLens: миллионы показов вверху воронки превращаются в сотни форм и заявку около 10 тысяч рублей

десятки тысяч кликов, сотни отправленных форм, заявка около 10 тысяч рублей. Клиент смотрит на такую сводку и задает единственный вопрос, на который она не отвечает: а что из этих форм дошло до оплаты? Отчет рекламного кабинета в этом месте разводит руками. Дальше начинается настройка сквозной аналитики.

Архитектура: четыре слоя данных и ключи связывания

Стек аналитики, который мы собираем онлайн-сервисам, устроен без магии: четыре слоя данных плюс BI поверх. Каждый слой закрывает свой участок пути от показа до оплаты.

Слой

Источник

Ключ связывания

Что дает

Расходы

Reports API Директа

CampaignId

спенд, показы, клики по кампаниям

Поведение

Logs API Метрики

ClientID, utm-метки

визиты, цели, отправки форм

Обращения

коллтрекинг (у нас Callibri)

подменный номер, визит

звонки и чаты с источником

Сделки

CRM

контакт, ID сделки

квал, продажа, сумма

Как это сшивается. Метрика хранит ClientID и utm каждого визита. Коллтрекинг привязывает звонок к конкретному визиту через подменный номер, и звонок получает те же метки, что и заявка с формы. CRM принимает метки вместе с обращением и дальше живет своими статусами: обращение, квал, продажа. А расходы цепляются к остальным слоям через идентификатор кампании. Мы кладем CampaignId прямо в utm_campaign при разметке ссылок: названия кампаний люди переименовывают, идентификатор переживает всех.

Слабое звено почти всегда на стыке обращений и сделок: заявка с метками пришла, а сделку менеджер завел руками, и источник потерялся. Прежде чем строить витрины, проверьте именно этот стык. Иначе BI будет красиво визуализировать дыру в данных.

Коннекторы: чем забираем расходы, визиты и обращения

Расходы тянем из Reports API Директа, пятая версия. Тело запроса на отчет по кампаниям за период:

{ «params»: { «SelectionCriteria»: { «DateFrom»: «2026-06-01», «DateTo»: «2026-06-30» }, «FieldNames»: [«CampaignId», «CampaignName», «Impressions», «Clicks», «Cost»], «ReportName»: «spend_by_campaign_june», «ReportType»: «CAMPAIGN_PERFORMANCE_REPORT», «DateRangeType»: «CUSTOM_DATE», «Format»: «TSV», «IncludeVAT»: «YES» } }

Здесь две грабли, и на обе мы в свое время наступили. Первая: IncludeVAT ставим YES, иначе расход в витрине не бьется с бухгалтерией, и клиент резонно спрашивает, куда делись 20 процентов. Вторая: Cost приходит в микрорублях. Забудете поделить на миллион — получите дашборд, где спенд SaaS-сервиса за месяц выглядит как бюджет небольшой страны. Выглядит эффектно, доверия не добавляет.

Визиты и цели удобнее забирать не из готовых отчетов Метрики, а из Logs API: он отдает сырые визиты построчно, без агрегации и сэмплирования. Для сведения хватает полей ym:s:visitID, ym:s:clientID, ym:s:UTMCampaign, ym:s:goalsID и даты визита. Обращения выгружаем из API коллтрекинга уже с привязанным визитом и метками, причем Callibri отдает заодно класс обращения — лид, спам, нецелевой звонок. Это экономит ручную разметку на стороне CRM.

Дальше слои встречаются в обычном SQL. Упрощенно связка расходов с квалами выглядит так:

SELECT d.campaign_id, sum(d.cost) AS spend, count(DISTINCT c.deal_id) FILTER (WHERE c.stage_qualified) AS quals FROM direct_spend d LEFT JOIN metrika_visits v ON v.utm_campaign = d.campaign_id::text LEFT JOIN crm_deals c ON c.client_id = v.client_id GROUP BY 1;

Боевой запрос длиннее: дедупликация обращений, окно атрибуции, словарь кампаний. Принцип тот же — расход и сделка встречаются через визит. И отдельно про звонки: без коллтрекинга они в схему не попадают вовсе, потому что звонок не оставляет utm. Подмена номера возвращает ему визит со всеми метками, после чего отслеживание лидов по телефону ничем не отличается от форм.

Хранилище и BI: Roistat или витрина на DataLens

Когда выгрузки налажены, наступает развилка. Готовая система сквозной аналитики вроде Roistat или Calltouch с коробочными интеграциями — или своя витрина на Яндекс DataLens поверх тех же выгрузок.

Критерий

Готовый сервис

Витрина на DataLens

Запуск

дни, интеграции из коробки

недели, коннекторы пишем сами

Модель квалификации

в рамках логики вендора

любая своя

Стоимость владения

абонплата, растет с объемом

время аналитика, сам DataLens в базовом объеме бесплатен

Данные

живут у вендора

витрины остаются у вас

Мы чаще собираем на DataLens, и причина прикладная: модель квалификации у B2B SaaS почти всегда нестандартная, а витрины при сборке остаются у клиента. Готовую систему берем, когда каналов один-два, цикл короткий и результат нужен на этой неделе. Спорить, что из этого правильнее, можно бесконечно, поэтому просто скажу, как решаем мы: если в компании есть человек, способный прочитать SQL, берите витрину.

Пара слов про само хранилище, раз оно вынесено в заголовок. Слои держим в реляционной базе: подойдет Postgres, на больших объемах визитов — ClickHouse. Сырые выгрузки складываем как есть, отдельным шагом собираем материализованные витрины: расход и заявки по кампаниям по дням, обращения со сделками, когорты по дате первого касания. DataLens подключается уже к витринам, минуя сырье. Дашборд остается быстрым, и логика сведения живет в SQL, где ее можно прочитать и проверить, а не в настройках чартов.

Сквозной дашборд на DataLens: бюджет, квалы, продажи и конверсии по этапам. Названия кампаний и выручка скрыты

Сквозной дашборд на DataLens: бюджет, квалы, продажи и конверсии по этапам. Названия кампаний и выручка скрыты

Теперь замеры. Проект — SaaS-сервис с длинным циклом сделки, данные обезличены. Расход в Директе за период около 1,58 млн рублей. Квалифицированных заявок 107, средняя стоимость квала примерно 14 800 рублей. Продаж 7, конверсия из квала в оплату 6,54 процента. Суммы выручки и ДРР на скриншоте скрыты сознательно: прямая атрибуция за короткое окно на длинном цикле занижает отдачу, потому что часть сделок дозревает уже за границей отчетного периода. Показывать такие цифры без оговорок — верный способ напугать читателя убытком, которого нет.

Что показал разрез заявка против продажи

Самое ценное после сведения слоев — построчное сравнение стоимости заявки и числа продаж по кампаниям.

Отчет по кампаниям: рядом стоимость квалифицированной заявки и число продаж. Названия кампаний скрыты

Отчет по кампаниям: рядом стоимость квалифицированной заявки и число продаж. Названия кампаний скрыты

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

Разбивка по категории таргетинга: целевой спрос выкупается дороже всего, сопутствующий и широкий охват дают заявку дешевле

Разбивка по категории таргетинга: целевой спрос выкупается дороже всего, сопутствующий и широкий охват дают заявку дешевле

Еще один разрез, который часто пропускают, — категория таргетинга. Целевой спрос выкупается дороже всего и съедает основную долю расходов, сопутствующие и широкие сегменты приносят заявку дешевле. Без этой части аналитики каналов трафика перераспределение бюджета между сегментами делается наощупь.

Где данные рвутся и что делать с длинным циклом

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

  • Обращения без источника: звонок или заявка пришли, а меток нет. Закрывается коллтрекингом с подменой номера и передачей utm в CRM вместе с обращением.

  • Разные модели атрибуции в разных отчетах. Фиксируем одну модель для всех витрин и проговариваем ее прямо в шапке дашборда, чтобы вопрос почему не сходится с кабинетом закрывался за секунду.

  • Офлайн-конверсии не возвращаются в Директ: сделка закрылась в CRM, а автостратегии продолжают учиться на формах. Лечится передачей конверсий через API Метрики.

  • Переименованные кампании ломают историю. Единственный надежный ключ — CampaignId.

И отдельная ловушка, на которой горят даже аккуратные команды: оценка месяца по продажам того же месяца.

Помесячная сводка: расходы идут ровно, а продажи приходят рывками спустя недели и месяцы после клика

Помесячная сводка: расходы идут ровно, а продажи приходят рывками спустя недели и месяцы после клика

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

Четыре сверки, без которых дашборду нельзя верить

Перед тем как принимать по витрине решения о бюджете, прогоняем четыре сверки. Они ловят большую часть потерь данных.

1. Клики в Директе против визитов с рекламных меток в Метрике за тот же период. Расхождение больше 10-15 процентов — теряются метки или барахлит счетчик.

2. Отправки форм в Метрике против обращений в коллтрекинге. Форм заметно больше — часть заявок приходит без источника.

3. Квалы и сделки на дашборде против ручного пересчета в CRM за неделю. Должны сойтись до штуки.

4. У каждой продажи на витрине есть кампания-источник. Продажи без источника означают дыру в передаче меток.

Дмитрий Шестаков, управляющий партнер

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

Минимальный старт, если стека пока нет

Не собирайте все сразу, надорветесь и забросите. Поставьте цели в Метрике на отправку форм и проверьте utm на всех кампаниях: это бесплатно и закрывает базовую атрибуцию. Подключите коллтрекинг, если часть заявок идет звонками. Заведите ручной свод обращение, квал, продажа по кампаниям хотя бы в таблице. Даже месяц такого свода показывает, где заявки есть, а продаж нет, и через один-два месяца на этих данных станет ясно, хватает ли готового сервиса или пора строить витрину. Так настройка сквозной аналитики идет от простого к сложному и не встает на полгода.

Частые вопросы

Чем сквозная аналитика отличается от связки Метрика плюс Директ?

Связка Метрика плюс Директ заканчивается на цели: вы видите визиты и конверсии, но не видите сделок. Сквозная аналитика добавляет слои обращений и CRM и доводит цепочку от показа до оплаты — появляется стоимость квала и продажи по каждой кампании.

Можно ли собрать все на выгрузках в таблицы, без BI?

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

Обязателен ли коллтрекинг, если все заявки идут через формы?

Нет. Коллтрекинг решает одну задачу — вернуть звонку рекламный источник. Если звонков в воронке нет, слой можно не подключать и добавить позже.

Как передавать офлайн-конверсии обратно в Директ?

Через API Метрики: выгружаете из CRM оплаты с ClientID или телефоном и почтой, загружаете как офлайн-конверсии, в Директе назначаете эту цель ключевой. Автостратегии начинают учиться на оплатах вместо форм — на длинном цикле это заметно меняет закупку.

Почему число лидов в CRM не сходится с конверсиями Директа?

Разные определения и разные окна. Директ считает конверсии по своей атрибуции внутри кабинета, CRM — заведенные сделки, плюс часть обращений приходит без меток. Сверка по CampaignId и utm убирает большую часть расхождения, остаток объясняется потерянными источниками.

Сколько времени занимает настройка сквозной аналитики?

Готовый сервис — от нескольких дней до пары недель. Витрина на DataLens с коннекторами, словарем кампаний и сверками — обычно три-шесть недель, дальше поддержка. Первые выводы по перераспределению бюджета появляются уже через месяц честных данных.

ссылка на оригинал статьи https://habr.com/ru/articles/1068254/