Я настраивала сквозное отслеживание UTM в трех компаниях. Каждый раз одни и те же пять вещей ломались в одном и том же порядке, и каждый раз решение было одинаковым: поднять шаблонизацию на уровень кампании, опустить пересылку конверсий на сервер и добавить между ними контрольный запуск. Это большая часть того, о чем этот пост. Остальное - это контрольный список QA, который выявляет ошибки, о которых вы даже не задумывались.
Вам не нужна Customer Data Platform (CDP) для этого. Она понадобится вам со временем, если ваша проблема атрибуции превратится в «склейку четырех анонимных касаний на трех устройствах в один путь клиента», но для случая, который я вижу чаще всего - «согласованно помечать каждую исходящую ссылку, фиксировать клик, пересылать конверсию в Meta и GA4 на стороне сервера и пережить Safari» - сокращатель URL с шаблонами плюс API конверсий справляются с задачей. Ниже представлена версия, которая работает, с разбором типичных ошибок.
Что идет не так с отслеживанием UTM#
Маркетологи, с которыми я работаю, не плохи в UTM. Проблема в том, что инструменты по умолчанию позволяют легко ввести UTM один раз, но мешают принудительно применять их во всей организации и делают невозможным исправление после запуска. Четыре режима отказа проявляются снова и снова.
Отклонения (Drift). Один человек вводит utm_source=newsletter, другой - utm_source=Newsletter, третий - utm_source=email. Через шесть месяцев ваш канал «newsletter» разделен на девять вариантов строк в GA4. Очистка после факта - это упражнение из серии «regex и молитва». Оригинальный скрипт urchinTracker(), который ввел эту конвенцию - продукт веб-аналитики Urchin от Google, предшествовавший Analytics, на короткое время ставший открытым в 2003 году перед поглощением - также не имел уровня шаблонов. Конвенция всегда заключалась в том, чтобы «вводить данные последовательно»; инструменты никогда не принуждали к этому.
Ручное тегирование в больших масштабах. Кампания с флаерами с 80 короткими ссылками в четырех региональных магазинах - это 320 URL-адресов, которые нужно напечатать, вставить в таблицу, скопировать в сокращатель и молиться. Половина из них получает неверный utm_content. Никто не замечает этого, пока кампания не идет уже две недели.
Пробелы в серверных конверсиях. Пиксель срабатывает на странице благодарности, GA4 подхватывает его, Meta подхватывает его, и вы идете домой. Затем Safari выпускает новую версию ITP, количество установок блокировщиков рекламы растет, и ваши отчетные конверсии падают на треть. Примечания к выпуску Apple ITP 2.3 подробно описывают этот механизм: декорирование ссылок ограничивается, document.referrer обрезается, и любой поток аналитики, зависящий от выполнения стороннего JS в браузере, тихо деградирует. Конверсии по-прежнему происходят на вашем сервере. Они просто не доходят до рекламных площадок.
Отсутствие пробного запуска. Первая конверсия, проходящая через новый конвейер - это первый реальный покупатель. Если что-то настроено неправильно, вы узнаете об этом через три дня, когда алгоритм оптимизации уже перераспределил бюджет с кампании, которая на самом деле работала.
Этот пост решает первые три проблемы с помощью шаблонов + массового импорта + серверной пересылки, а четвертую - с помощью шага проверки, который легко пропустить и пропуск которого обходится дорого.
UTM-шаблоны рабочего пространства и кампаний#
Шаблоны переносят проблему согласованности выше по стеку. Вы один раз определяете свою конвенцию тегирования на уровне рабочего пространства, накладываете переопределения для каждой кампании там, где это оправдано, и позволяете каждой ссылке наследоваться. Для опечаток просто не остается места.
Сначала определите значения по умолчанию для рабочего пространства. Литеральные значения фиксируют переменные, которые никогда не меняются для вашей организации (utm_medium = email для рассылок); заполнители заполняются из данных ссылки во время создания:
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 - рабочий процесс, который действительно используют маркетологи#
Маркетологи не сидят в curl целый день. Бриф кампании поступает в виде электронной таблицы с целевыми URL и метаданными кампании, крайний срок запуска - пятница, и вопрос в том, как эта таблица превращается в 200 коротких ссылок без того, чтобы кто-то вводил одну и ту же строку UTM 200 раз.
Имена столбцов CSV соответствуют именам заполнителей из вашего шаблона (регистр не важен). Столбцы, которые Elido не распознает, отбрасываются с предупреждением, а не копируются молча - это сделано намеренно. Молчаливое копирование - это то, как в итоге в GA4 появляется utm_brand_color, потому что кто-то добавил столбец для внутренней заметки.
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"
Две вещи, которые дает этот поток валидации по сравнению с UI для создания одной ссылки:
- Транзакционная фиксация (All-or-nothing). Одна плохая строка прерывает всю загрузку и возвращает номера проблемных строк вместе с причиной -
row 47: unresolved variable {{ creative }}гораздо лучшая ошибка, чем обнаружение в 16:00 в пятницу, что 47 из ваших 200 ссылок разрешились в строку-заполнитель. - Предпросмотр перед запуском. Строка предпросмотра массового импорта в панели управления показывает разрешенный URL, включая отрендеренную строку запроса
utm_*, до фиксации. Взгляните на вторую ссылку, чтобы убедиться, что ваш шаблон сделал то, что вы ожидали, а затем на последнюю ссылку, чтобы убедиться, что строки в конце файла не «уплыли». Два взгляда, одна минута.
Если ваша электронная таблица не имеет стабильной формы - порядок столбцов меняется, заголовки переименовываются - конечная точка массового импорта будет неудобной. Решение не в наших инструментах; решение в том, чтобы зафиксировать схему CSV для ваших брифов кампаний и рассматривать отклонение схемы как ошибку процесса. Мы обсуждаем более широкую модель на странице решений для маркетологов.
Серверная пересылка конверсий в Meta CAPI и GA4#
Атрибуция только по пикселям теряет 20-40% конверсий из-за Safari ITP, блокировщиков рекламы и баннеров согласия. Число варьируется в зависимости от отрасли - в DTC ecommerce наблюдается верхний предел диапазона, в B2B SaaS - нижний, но каждое измерение, которое я видела после iOS 14, ставит надежность пикселей значительно ниже отметки в 95%, которую предполагают рекламные платформы. Алгоритм оптимизации получает более шумные входные данные, и ваша цена за действие (CPA) выглядит хуже, чем она есть на самом деле.
Документация Meta Conversions API прямо говорит об этом: серверные события - это то, что вам нужно, а пиксель на стороне браузера - лишь дополнение. GA4 Measurement Protocol утверждает то же самое. Оба протокола принимают одну и ту же форму: серверное событие с деталями конверсии, 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, срок жизни 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": {
"project_token": "pm_…",
"service_account": "[email protected]"
}
}'
Шаг третий - 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%+».
Три пограничных случая, в которых вас спасет журнал аудита#
Шаблоны и пересылка справляются с основным сценарием. Описанные ниже случаи проявляются на третьей неделе любой нетривиальной кампании, и правильный ответ на них кроется в журнале аудита + панели конверсий, а не в попытках разработать более сложный шаблон.
Возвраты (Refunds). Сработала конверсия покупки, клиент вернул товар через неделю, и ваш отчетный доход теперь на 8% завышен. Решение состоит в том, чтобы отправить POST с тем же event_id и event_name: "refund". Meta и GA4 рассматривают это как отрицательную конверсию относительно оригинала; Mixpanel записывает это как отдельное событие, которое вы вычитаете в своей воронке. Причина, по которой event_id сформирован именно так: идемпотентность на уровне идентификатора события означает, что вы не сможете дважды посчитать возврат. Полная схема документирована в разделе пограничных случаев руководства по пересылке конверсий - возвраты, частичные возвраты и кредит магазина имеют немного разные формы.
Пропуски click_id. Срабатывает конверсия с click_id, который не соответствует ни одному известному клику - опечатка, истек срок хранения, другое рабочее пространство. Конверсия все равно записывается в рабочем пространстве, но пересылается с пустым контекстом UTM. Это сделано намеренно: общая атрибуция полезнее, чем потеря конверсии, а флаг click_id_unknown в журнале аудита позволяет отфильтровать неатрибутированную часть при составлении отчетов. Если эта часть превышает 5% конверсий, значит, что-то не так с тем, как вы сохраняете click_id на целевой странице - обычно это атрибут SameSite у cookie или область пути (path scope).
Поздние конверсии. Продажа B2B SaaS закрывается через 47 дней после первоначального клика. Срок хранения кликов в Elido по умолчанию составляет 30 дней, поэтому к моменту срабатывания конверсии срок клика уже истек, и вы попадаете в ситуацию с пропуском click_id, описанную выше. Есть два решения в зависимости от вашего цикла продаж: увеличить срок хранения до 90 дней в рабочем пространстве (тариф Pro и выше) или фиксировать click_id в долгоживущем идентификаторе первой стороны (столбец original_click_id в вашей записи клиента), чтобы вы могли связать его во время конверсии, даже если cookie уже нет. Мы видели обе модели в работе.
Журнал аудита показывает разницу между разрешенным и итоговым UTM для каждой ссылки, код ответа пересылки для каждого направления по каждой конверсии и состояние связи между click_id и конверсией. Когда алгоритм оптимизации забирает бюджет у кампании, которая выглядит неэффективной, журнал аудита - это то, что позволяет вам сказать: «Нет, с кампанией все в порядке; мы на три дня потеряли пересылку из-за ротации api_secret в GA4». Посмотрите его.
QA перед запуском - пробный запуск всей цепочки#
Не позволяйте первой конверсии, проходящей через систему, быть реальным покупателем. Стоимость 30-минутного пробного запуска полностью ложится на вас; стоимость неправильно настроенного конвейера ложится на алгоритм оптимизации, который забирает бюджет у вашей самой эффективной кампании в течение двух дней, прежде чем вы это заметите. Эта асимметрия опасна.
Три шага по порядку.
Пробный массовый импорт. Конечная точка массового импорта принимает 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 - правильный выбор.
Склейка идентификаторов между устройствами (Cross-device identity stitching). Посетитель переходит по ссылке на мобильном устройстве, не совершает конверсию, возвращается с десктопа и регистрируется. Вы хотите, чтобы оба касания были атрибутированы одному человеку. Отслеживание UTM + click_id работает на уровне касания; уровень идентификации пользователя, который объединяет два касания в один путь, - это то, для чего созданы CDP (Segment, mParticle, RudderStack). Elido хранит до 30 дней кликов на каждого посетителя и поддерживает атрибуцию по последнему касанию / первому касанию / на основе позиции в этом окне, но для склейки между устройствами нужен граф идентификаторов, которым мы намеренно не управляем.
Персонализация со скоростью менее 100 мс. Если вы рендерите целевую страницу на основе предыдущих касаний посетителя в режиме реального времени - извлекая когорту из хранилища признаков и меняя главный заголовок - вам нужно разрешение идентификаторов в непосредственной близости от рендеринга. Это территория CDP или, чаще, платформ для экспериментов, таких как PostHog или LaunchDarkly, работающих поверх системы.
Многоканальная атрибуция в больших масштабах. Атрибуция по последнему касанию подходит для большинства кампаний. Если ваш цикл продаж включает шесть касаний в течение четырех месяцев и вам действительно нужно начислить кредит каждому из них, вы находитесь на территории, где начинают иметь значение модели цепей Маркова или значений Шепли. Elido поддерживает модели по последнему касанию / первому касанию / на основе позиции; для чего-то более сложного требуется инструмент с полноценным графом идентификаторов и слоем моделирования.
Для всего остального - а под «всем остальным» я подразумеваю большинство маркетинговых команд, с которыми я работала - модели шаблоны + массовый импорт + серверная пересылка вполне достаточно. Настройте шаблон рабочего пространства один раз, шаблон кампании для каждого запуска, конфигурацию пересылки один раз для каждой интеграции с платформой и запускайте проверку перед каждым запуском. Если вы сделаете все четыре шага, ваш UTM-конвейер будет надежнее, чем у 80% маркетинговых команд, которые я аудировала.
Создайте это один раз, проводите пробный запуск перед каждым стартом и переходите к следующей кампании.
Похожее в блоге#
Попробуйте Elido
Вставьте URL - получите короткую ссылку
Без регистрации. Ссылка живёт 30 дней. Зарегистрируйтесь, чтобы оставить её навсегда.
Бесплатно, без регистрации · 2 в день