Я настраивала сквозное отслеживание UTM в трех компаниях. Каждый раз ломались одни и те же пять вещей в одном и том же порядке, и каждый раз решение было одинаковым: поднять шаблонизацию на уровень кампании, опустить пересылку конверсий на сервер и поставить между ними контрольный прогон. Это большая часть того, о чем этот пост. Остальное - чек-лист QA, который отлавливает то, о чем вы даже не подумали бы сломать.
Если вы еще не уверены, что делает каждый из пяти тегов, объяснение параметров UTM - тот ввод в тему, на котором строится этот конвейер.
Customer Data Platform для этого не нужна. Она понадобится вам в какой-то момент, если ваша проблема атрибуции превратится в «сшить четыре анонимных касания на трех устройствах в один путь клиента», но для случая, который я вижу чаще всего - «последовательно размечать каждую исходящую ссылку, фиксировать клик, пересылать конверсию в Meta и GA4 на сервере и пережить Safari», - URL-шортенер с шаблонами плюс API конверсий справляется с задачей. Ниже - рабочая версия с обозначенными сценариями отказа, которые мне доводилось видеть.
Что идет не так с отслеживанием UTM
Маркетологи, с которыми я работаю, не плохи в UTM. Проблема в том, что инструменты по умолчанию делают простым однократный ввод UTM, сложным - соблюдение единообразия во всей организации и невозможным - исправление после запуска. Четыре сценария отказа встречаются снова и снова.
Расхождение. Один человек вводит utm_source=newsletter, другой - utm_source=Newsletter, третий - utm_source=email. Полгода спустя ваш канал «newsletter» разбит на девять вариантов строки в GA4. Разобраться с этим постфактум - упражнение из серии «регулярка и молитва». У исходного скрипта urchinTracker(), который ввел это соглашение - продукт веб-аналитики Urchin, предшественник Google Analytics, ненадолго ставший открытым исходным кодом в 2003 году до поглощения, - тоже не было слоя шаблонов. Соглашение всегда звучало как «вводите единообразно»; инструментарий никогда этого не навязывал.
Ручная разметка в масштабе. Кампания с листовками, включающая 80 коротких ссылок по четырем региональным магазинам, - это 320 URL, которые нужно вписать вручную, вставить в таблицу, скопировать в шортенер и надеяться на лучшее. У половины из них окажется неверный utm_content. Никто не замечает, пока кампания не идет уже две недели.
Пробелы в серверных конверсиях. Пиксель срабатывает на странице благодарности, GA4 его фиксирует, Meta его фиксирует, и вы расходитесь по домам. Затем Safari выпускает очередную версию ITP, число установок блокировщиков рекламы растет, и заявленные конверсии падают на треть. Примечания к выпуску ITP 2.3 от Apple подробно разбирают именно этот механизм: декорирование ссылок ограничивается, document.referrer обрезается, и любой поток аналитики, зависящий от выполнения браузером стороннего JS, незаметно деградирует. Конверсии по-прежнему происходят на вашем сервере. Просто они не доходят до рекламных площадок.
Отсутствие контрольного прогона. Первая конверсия, проходящая через новый конвейер, - это первый реальный покупатель. Если что-то настроено неверно, вы узнаете об этом три дня спустя, когда алгоритм оптимизации уже успел забрать бюджет у кампании, которая на самом деле работала.
Этот пост решает первые три проблемы шаблонами, массовым импортом и серверной пересылкой, а четвертую - шагом проверки, который легко пропустить и дорого пропускать.
UTM-шаблоны рабочего пространства и кампании
Шаблоны поднимают проблему согласованности выше по стеку. Вы определяете соглашение о разметке один раз на уровне рабочего пространства, накладываете переопределения для конкретных кампаний там, где это оправдано, и позволяете каждой ссылке наследовать эти настройки. Для опечатки просто не остается места.
Сначала задайте значения рабочего пространства по умолчанию. Литеральные значения фиксируют переменные, которые никогда не меняются для вашей организации (utm_medium = email для кампаний рассылок); плейсхолдеры заполняются из payload ссылки в момент создания:
curl -X PUT \
https://api.elido.app/v1/workspaces/1/utm-template \
-H "Authorization: Bearer $ELIDO_TOKEN" \
-d '{
"utm_source": "{{ channel }}",
"utm_medium": "{{ medium }}",
"utm_campaign": "{{ campaign }}",
"utm_content": "{{ creative }}",
"utm_term": "{{ audience.segment }}"
}'
Несколько деталей, которые здесь важны:
- Плейсхолдеры заполняются в момент создания ссылки, а не в момент клика. В ваш инструмент аналитики попадает то, что было задумано на момент создания ссылки, а не то, что вычислило назначение ссылки в момент клика. Это сильно упрощает восстановление по журналу аудита, когда что-то выглядит неправильно спустя полгода.
- Неизвестные плейсхолдеры моментально приводят к ошибке. Если в вашем массовом импорте отсутствует колонка
creative, а шаблон рабочего пространства ссылается на{{ creative }}, API возвращает 422 с именем неразрешенной переменной. Никакого тихого частичного применения. - Полный справочник шаблонов, включая плейсхолдеры
link.tag.<name>, которые читаются из массива тегов ссылки (полезно для мультитенантных агентств, которым нужно встраивать идентификатор клиента в каждый URL), - в руководстве в документации.
Затем наложите шаблон кампании. Кампании наследуют настройки рабочего пространства и заменяют то подмножество, что специфично для кампании:
curl -X POST \
https://api.elido.app/v1/campaigns \
-H "Authorization: Bearer $ELIDO_TOKEN" \
-d '{
"name": "Spring 2026 - DACH",
"utm_template": {
"utm_campaign": "spring_2026_dach",
"utm_term": "{{ audience.locale }}"
}
}'
Все, что не задано в кампании, наследуется от значений рабочего пространства по умолчанию. Двухуровневое наслоение покрывает большинство реальных организационных структур: общие соглашения на уровне рабочего пространства, специфичные для команды или сезона переопределения на уровне кампании. Если вы ловите себя на желании добавить третий уровень наследования, это тревожный звоночек - обычно это значит, что две кампании на самом деле должны быть одной кампанией с более умными значениями плейсхолдеров.
То, от чего отказываются переопределения на уровне отдельной ссылки: переопределение срабатывает независимо от шаблона. То, что они сохраняют: переопределение фиксируется в журнале аудита вместе с автором, временной меткой и разницей между разрешенным и итоговым значением. Спустя полгода, когда кто-то спросит, почему у одной ссылки из кампании на 200 ссылок стоит utm_term=manual_override, вы сможете ответить.
Массовый импорт из Sheets - workflow, которым реально пользуется большинство маркетологов
Маркетологи не сидят весь день в curl. Бриф кампании приходит в виде таблицы с целевыми URL и метаданными кампании, дедлайн запуска - пятница, и вопрос в том, как превратить эту таблицу в 200 коротких ссылок, чтобы никто не вводил одну и ту же строку UTM 200 раз.
Имена колонок CSV совпадают с именами плейсхолдеров из вашего шаблона (без учета регистра). Колонки, которые Elido не распознает, отбрасываются с предупреждением, а не копируются молча - это осознанное решение. Молчаливое копирование - это способ получить utm_brand_color в GA4 из-за того, что кто-то добавил колонку для внутренней заметки.
destination_url,channel,medium,creative
https://shop.example.com/de,newsletter,email,hero_a
https://shop.example.com/fr,newsletter,email,hero_a
https://shop.example.com/de,paid_social,meta,carousel_v2
https://shop.example.com/fr,paid_social,meta,carousel_v2
Отправьте это как multipart:
curl -X POST \
https://api.elido.app/v1/links/bulk \
-H "Authorization: Bearer $ELIDO_TOKEN" \
-F "csv=@launch_q2.csv" \
-F "campaign_id=cmp_8a2f"
Этот поток проверки дает вам две вещи, которых нет в интерфейсе создания ссылок по одной:
- Фиксация по принципу «все или ничего». Одна плохая строка прерывает всю загрузку и возвращает номера проблемных строк вместе с причиной -
row 47: unresolved variable {{ creative }}гораздо лучше в качестве ошибки, чем обнаружение в 16:00 в пятницу, что 47 из ваших 200 ссылок разрешились в строку-плейсхолдер. - Предпросмотр перед запуском. Строка предпросмотра массового импорта в дашборде показывает разрешенный URL, включая отрисованную строку запроса
utm_*, до фиксации. Посмотрите на вторую ссылку, чтобы убедиться, что шаблон сделал то, что вы ожидали, затем посмотрите на последнюю ссылку, чтобы убедиться, что строки дальше по файлу не разъехались. Два взгляда, одна минута.
Если у вашей таблицы нет стабильной структуры - порядок колонок гуляет, заголовки переименовываются, - endpoint массового импорта станет неприятным опытом. Исправление не в нашем инструментарии; исправление - взять на себя обязательство по схеме CSV для брифов кампаний и относиться к расхождению схемы как к ошибке процесса. Мы обсуждаем этот паттерн шире на странице решений для маркетологов.
Серверная пересылка конверсий в Meta CAPI и GA4
Атрибуция только по пикселю теряет 20-40% конверсий из-за Safari ITP, блокировщиков рекламы и баннеров согласия. Цифра варьируется по отраслям - DTC-электронная коммерция оказывается на верхней границе диапазона, B2B SaaS - на нижней, - но каждое измерение, которое я видела после выхода iOS 14, ставит надежность пикселя заметно ниже отметки в 95%, на которую рассчитывают рекламные платформы. Алгоритм оптимизации получает более шумные входные данные, и ваш CPA выглядит хуже, чем есть на самом деле.
Документация Conversions API от Meta прямо об этом говорит: серверные события - то, что вам нужно, пиксель на стороне браузера - лишь дополнение. Measurement Protocol GA4 утверждает то же самое. Оба протокола принимают одинаковую форму: серверное событие с деталями конверсии, event_id для дедупликации и, в идеале, хешированные идентификаторы пользователя, чтобы платформы могли сшить конверсию с известным посетителем.
Механика, которая закрывает этот разрыв, чисто техническая. Три шага.
Шаг первый - зафиксируйте click_id. Каждый ответ редиректа Elido несет заголовок X-Elido-Click-Id. SDK для TS / Python / Go выводят его в объекте ответа редиректа; сырой HTTP тоже работает:
curl -sI https://elido.me/launch | grep -i click-id
# X-Elido-Click-Id: clk_01HYZ7T8WV6KQX3M
Сохраните его в собственном (first-party) cookie на странице назначения (elido_click_id, TTL 90 дней - достаточно долго, чтобы покрыть типичный цикл оценки SaaS-продукта, и достаточно коротко, чтобы соответствовать рекомендациям ePrivacy). Считайте его обратно при оформлении заказа.
Шаг второй - подключите назначения. Отправьте PUT с учетными данными для площадок, в которые хотите пересылать данные. Работает любое подмножество; отсутствующие площадки молча пропускаются:
curl -X PUT \
https://api.elido.app/v1/workspaces/1/conversion-forwarding \
-H "Authorization: Bearer $ELIDO_TOKEN" \
-d '{
"meta_capi": {
"pixel_id": "1234567890",
"access_token": "EAA…",
"test_event_code": null
},
"ga4_mp": {
"measurement_id": "G-ABC123",
"api_secret": "abc_def_ghi"
}
}'
Mixpanel - не назначение для конверсий. Интеграция Elido с Mixpanel пересылает каждый клик по короткой ссылке как событие link_click, и подключается она отдельно в разделе Integrations.
Шаг третий - отправьте конверсию POST-запросом. Когда срабатывает заказ, отправьте событие с click_id и деталями заказа. event_id - это ваш ключ идемпотентности:
curl -X POST \
https://api.elido.app/v1/conversions \
-H "Authorization: Bearer $ELIDO_TOKEN" \
-d '{
"click_id": "clk_01HYZ7T8WV6KQX3M",
"event_name": "purchase",
"event_id": "ord_98231",
"value": 89.00,
"currency": "EUR",
"user": {
"email": "[email protected]",
"phone": "+4915123456789",
"external_id": "cust_5128"
}
}'
Поля идентичности пользователя хешируются по SHA-256 перед пересылкой в Meta и GA4 - это то, что требуют обе платформы. Контекст UTM извлекается из строки клика, которая совпадает с click_id, поэтому пересланное событие несет исходную атрибуцию кампании, даже если пользователь час бродил по сайту, прежде чем оформить заказ. Полная механика, включая обработку возвратов и переключатель модели мультитач-атрибуции, - в руководстве по пересылке конверсий.
Это закрывает большую часть разрыва. Остается небольшая дыра - посетители, блокирующие cookie click_id, или пришедшие путем, минующим Elido, - но для кампаний, в которые вы реально направляете трафик, вы перешли от «надежности пикселя 60-80%» к «серверной надежности 95%+».
Три граничных случая, в которых вас спасет журнал аудита
Шаблоны и пересылка покрывают штатный сценарий. Случаи ниже проявляются на третьей неделе любой нетривиальной кампании, и правильный ответ на все них лежит в журнале аудита и панели конверсий - а не в попытке спроектировать более изощренный шаблон.
Один случай не попал в этот список, потому что от него нельзя защититься шаблоном: клик, который приходит без referrer и с параметром кампании, который вы не задавали. Именно так ведут себя ИИ-ассистенты, и статья отслеживание трафика от ChatGPT разбирает, что с этим делать.
Возвраты. Сработала конверсия покупки, клиент вернул товар неделю спустя, и ваша заявленная выручка теперь завышена на 8%. Решение - отправить POST с тем же event_id и event_name: "refund". Meta и GA4 трактуют это как отрицательную конверсию по отношению к исходной. Причина, по которой event_id устроен именно так: идемпотентность на уровне ID события означает, что вы не сможете задвоить и сам возврат. Полный паттерн задокументирован в разделе про граничные случаи руководства по пересылке конверсий - у возвратов, частичных возвратов и магазинных кредитов немного разная форма.
Промахи click_id. Срабатывает конверсия с click_id, который не совпадает ни с одним известным кликом - опечатка, истек срок хранения, неверное рабочее пространство. Конверсия все равно фиксируется за рабочим пространством, но пересылается с пустым контекстом UTM. Это сделано намеренно: атрибуция «в общую корзину» полезнее, чем отбрасывание конверсии, а флаг click_id_unknown в журнале аудита позволяет отфильтровать неатрибутированную часть при формировании отчетов. Если эта часть превышает 5% конверсий, что-то не так с тем, как вы сохраняете click_id на странице назначения - обычно дело в атрибуте SameSite cookie или в области действия пути.
Конверсии, приходящие с опозданием. Сделка в B2B SaaS закрывается спустя 47 дней после исходного клика. Срок хранения кликов в Elido по умолчанию - 30 дней, так что к моменту срабатывания конверсии клик уже устарел, и вы попадаете в описанный выше случай промаха click_id. Есть два решения в зависимости от вашего цикла продаж: увеличить срок хранения до 90 дней на уровне рабочего пространства (тариф Pro и выше) либо зафиксировать click_id в долгоживущем собственном идентификаторе (колонка original_click_id в записи вашего клиента), чтобы можно было сшить его обратно в момент конверсии, даже если cookie уже нет. Мы видели оба паттерна в продакшене.
Журнал аудита показывает разницу между разрешенным и итоговым UTM по каждой ссылке, код ответа пересылки по каждому назначению и каждой конверсии, а также состояние сопоставления click_id с конверсией. Когда алгоритм оптимизации забирает бюджет у кампании, которая выглядит слабой, именно журнал аудита позволяет сказать «нет, с кампанией все в порядке, мы потеряли три дня пересылки из-за ротированного api_secret GA4». Загляните в него.
QA перед запуском - контрольный прогон всего конвейера
Не позволяйте первой конверсии, прошедшей через это, оказаться реальным покупателем. Цена получасового контрольного прогона целиком ложится на вас; цена неверно настроенного конвейера - на алгоритм оптимизации, который два дня будет забирать бюджет у вашей лучшей кампании, прежде чем вы это заметите. Асимметрия плохая.
Три шага по порядку.
Контрольный прогон массового импорта. Endpoint массового импорта принимает параметр запроса dry_run=true. Он выполняет проверку, разрешает шаблоны и возвращает потенциально созданные ссылки без фиксации. Откройте ответ в любом JSON-просмотрщике; разрешенный URL каждой строки виден. Выборочно проверьте 3-5 строк: вторую ссылку, последнюю ссылку и любые строки, где были переопределены значения рабочего пространства по умолчанию. Убедитесь, что строка запроса utm_* в точности соответствует тому, что указано в брифе кампании.
Тестовый режим пересылки конверсий. Meta CAPI принимает параметр test_event_code, который направляет событие во вкладку Test Events в Events Manager вместо продакшена. Задайте его в конфигурации пересылки рабочего пространства, отправьте 10-20 тестовых конверсий и убедитесь, что они дошли. Та же идея для GA4: задайте debug_mode: true на событиях и проверьте в DebugView. Оба варианта работают в реальном времени. Смысл не в том, чтобы выборочно убедиться, что API работает; смысл в том, чтобы поймать неверно настроенный pixel_id или api_secret, который был ротирован, но нигде не обновлен.
Сквозная проверка. Кликните по одной из ваших реальных коротких ссылок в чистой сессии браузера. Понаблюдайте за кликом на панели последних кликов в дашборде Elido. Представьте, что вы что-то купили - отправьте POST-запросом конверсию purchase с этим click_id из терминала. Убедитесь, что конверсия появилась в Meta Test Events и GA4 DebugView с прикрепленным правильным контекстом UTM. Весь цикл занимает меньше 10 минут, когда вы проделали это один раз.
После того как все три шага пройдены, уберите test_event_code, задайте debug_mode: false и запускайтесь. Первого реального покупателя будет ждать чистый конвейер.
Когда вам на самом деле понадобится CDP
Шаблоны плюс массовый импорт плюс серверная пересылка покрывают большую часть пути. Есть класс проблем, где этого недостаточно, и обращение к CDP - правильное решение.
Сшивание идентичности между устройствами. Посетитель кликает по ссылке на телефоне, не конвертируется, возвращается с компьютера, регистрируется. Вы хотите, чтобы оба касания были приписаны одному и тому же человеку. Отслеживание UTM плюс click_id работает на уровне касания; слой идентичности пользователя, который объединяет два касания в один путь, - как раз то, для чего создана CDP (Segment, mParticle, RudderStack). Elido хранит до 30 дней кликов на посетителя и поддерживает атрибуцию по последнему касанию, первому касанию или позиции внутри этого окна, но сшивание между устройствами требует графа идентичности, который мы сознательно не эксплуатируем.
Персонализация с латентностью меньше 100 мс. Если вы рендерите страницу назначения на основе предыдущих касаний посетителя в реальном времени - подтягивая когорту из feature store и меняя заголовок героя - вам нужно разрешение идентичности прямо рядом с рендерингом. Это территория CDP или, чаще, платформы экспериментов вроде PostHog или LaunchDarkly, надстроенной поверх.
Мультитач-атрибуция в масштабе. Атрибуция по последнему касанию подходит для большинства кампаний. Если у вашего цикла продаж шесть касаний за четыре месяца и вам действительно нужно засчитать каждое из них, вы попадаете на территорию, где начинает иметь значение атрибуция по цепи Маркова или по значению Шепли. Elido поддерживает атрибуцию по последнему касанию, первому касанию и позиции; что-то более изощренное требует инструмента с полноценным графом идентичности и слоем моделирования.
Для всего остального - а «все остальное» это большинство маркетинговых команд, с которыми я работала, - паттерна «шаблоны плюс массовый импорт плюс серверная пересылка» достаточно. Настройте шаблон рабочего пространства один раз, шаблон кампании под каждый запуск, конфигурацию пересылки один раз на каждую интеграцию с платформой и запускайте контрольный прогон перед каждым запуском. Если вы сделаете все четыре вещи, у вас будет более выстроенный UTM-конвейер, чем у 80% маркетинговых команд, которые я проверяла.
Постройте это один раз, прогоняйте контрольную проверку перед каждым запуском и переходите к следующей кампании.
По теме в блоге
- Объяснение параметров UTM: пять тегов и как они работают
- Серверное отслеживание GA4 через уровень редиректа
- Объяснение бескукиной атрибуции: что все еще работает в 2026 году
- Массовый импорт коротких ссылок из Google Sheets (реальный workflow кампании)
- Атрибуция кликов после Safari ITP: что все еще работает в 2026 году
- Как отслеживать клики по ссылкам: что можно и что нельзя увидеть
- Бесплатный конструктор UTM: создавайте отслеживаемые URL кампаний
- Что такое CTR и как его повысить
Попробуйте Elido
Вставьте URL - получите короткую ссылку
Без регистрации. Ссылка живёт 30 дней. Зарегистрируйтесь, чтобы оставить её навсегда.
Бесплатно, без регистрации · 2 в день