GA4 Measurement Protocol возвращает статус 2xx почти на все, что вы в него отправите: корректное событие, событие с ошибкой в названии, событие без client_id, придуманный секрет. Поэтому код статуса бесполезен для отладки. Чтобы отладить вызовы GA4 Measurement Protocol, отправьте то же тело запроса на сервер валидации по адресу /debug/mp/collect, прочитайте возвращаемые им validationMessages, исправьте названные проблемы и только затем подтвердите поступление в DebugView или Realtime.
Этот последний шаг важнее, чем многие ожидают. Почему? Сервер валидации не проверяет ваш API-секрет, поэтому тело запроса может пройти проверку, получить 204 от настоящей конечной точки и все равно не попасть в ваш ресурс. Я видел, как команда потеряла на этом целую неделю, прежде чем кто-то догадался еще раз скопировать секрет.
Если вы подключаете серверные события для отслеживания кампаний, в базовом руководстве отслеживание UTM от начала до конца рассказано, что должно быть в ссылке до всех этих действий. Эта статья о моменте, когда вы отправляете событие, а оно нигде не появляется.
Почему Measurement Protocol отвечает 2xx на все
В справочнике протокола Google сказано прямо: конечная точка возвращает статус 2xx, если HTTP-запрос получен, и не возвращает ошибку, если тело запроса некорректно или данные не обработаны. Сбор данных выполняется по принципу «отправил и забыл». Ваш сервер не ждет обработки.
Мы проверили это сами. POST-запрос на /mp/collect с телом {"garbage":true}, поддельным Measurement ID и выдуманным секретом вернулся с HTTP 204 и пустым телом. Ровно так же, как безупречное событие.
Логика повторных попыток, основанная на кодах статуса, ловит сетевые сбои. И ничего больше. Она не скажет вам, что GA4 отбросил ваши события. Для этого нужна вторая конечная точка.
Как использовать сервер валидации по адресу /debug/mp/collect
Сервер валидации Measurement Protocol находится на том же хосте. Та же строка запроса, то же тело:
curl -s -X POST \
"https://www.google-analytics.com/debug/mp/collect?measurement_id=G-XXXXXXXXXX&api_secret=YOUR_SECRET" \
-H "Content-Type: application/json" \
-d '{"events":[{"name":"session_start","params":{"firebase_x":1}}]}'
Он отвечает кодом 200 и JSON-телом вместо пустого. В этом тестовом теле три проблемы, и сервер сообщает о первой найденной:
{
"validationMessages": [
{
"fieldPath": "client_id",
"description": "Measurement requires a client_id.",
"validationCode": "VALUE_REQUIRED"
}
]
}
Добавьте client_id, и далее он выдаст NAME_RESERVED для session_start; переименуйте событие, и следующей станет префикс firebase_. В каждом сообщении есть fieldPath, понятное человеку описание и код. Среди задокументированных Google кодов: VALUE_INVALID, VALUE_REQUIRED, NAME_INVALID, NAME_RESERVED, VALUE_OUT_OF_BOUNDS, EXCEEDED_MAX_ENTITIES и NAME_DUPLICATED.
Пустой массив, "validationMessages": [ ], означает, что структура корректна. Ничто, отправленное на /debug/mp/collect, не сохраняется. Проверяйте его при разработке сколько угодно, но помните: отладочный вызов никогда не доказывает, что данные поступили.
Чего сервер валидации не проверяет
Большинство руководств пропускают эту часть. На странице Google проверка событий прямо сказано, что сервер валидации не проверяет api_secret. В нашем тесте 22 сентября 2026 года он не проверил и Measurement ID: G-FAKE123 с секретом nonsense вернул пустой массив validationMessages.
Неверный секрет проходит. Как и отозванный, секрет из другого потока данных или опечатка в G-. API-секрет Measurement Protocol - самая частая причина, которую я вижу при ситуации «корректное тело запроса, данных нет», и подтвердить ее можно только увидев поступившее событие.
Второй пробел - режим валидации. По умолчанию сервер работает в режиме RELAXED, и в нем пропустил две вещи, которые запрещают собственные ограничения Google: событие с 26 параметрами и значение параметра из 120 символов. Добавьте "validation_behavior": "ENFORCE_RECOMMENDATIONS" в отладочное тело, и оба не пройдут, с EXCEEDED_MAX_ENTITIES и VALUE_TOO_LONG. Я всегда проверял бы в строгом режиме, даже если в рабочей среде остается нестрогий режим. В этом разница между проверяющим инструментом и формальным штампом.
Как увидеть серверные события в GA4 DebugView и Realtime
Когда тело запроса прошло валидацию, отправьте его на настоящую конечную точку и проследите за поступлением. Для серверных событий подходят два представления, но не стандартные отчеты, поскольку они могут отставать на 24-48 часов.
Для DebugView нужна активация для каждого события. В руководстве по проверке Google требует "debug_mode": 1 (или true) в параметрах события и положительный engagement_time_msec. Отображаются только события с этим флагом, поэтому пакет, в котором он отсутствует у одного события, выглядит наполовину пустым. Откройте «Администратор», затем DebugView, и подождите минуту.
Для Realtime ничего дополнительно не нужно. Прокрутите до карточки «Количество событий по названию события» и найдите свое событие. Google отмечает, что session_id и engagement_time_msec важны для отображения активности пользователя в Realtime, поэтому, если событие прошло валидацию, но Realtime пуст, сначала проверьте именно эти два параметра.
Еще одна оговорка из того же руководства: для веб-потоков там сказано, что корректное событие использует client_id, который gtag.js уже применял. Синтетические ID все равно учитываются, каждый как отдельный пользователь, но они никогда не присоединяются к сеансу браузера. В отчете, построенном вокруг сеансов, это выглядит как длинный хвост пользователей с одним событием, который невозможно объяснить, пока не узнаешь их источник. Подробнее об этом в следующем разделе. Если не хватает не событий, а данных кампании, в статье UTM-параметры не отображаются в GA4 разобрана сторона этой проблемы в DebugView.
Распространенные ошибки в теле запроса и ответы валидатора
Большинство сломанных событий укладывается в несколько типичных схем. Вот они вместе с ответом сервера валидации, который мы получили, отправив каждую из них 22 сентября 2026 года:
| Ошибка | Ответ валидатора (режим по умолчанию) | Исправление |
|---|---|---|
В теле нет client_id | VALUE_REQUIRED для client_id | Отправьте значение _ga или собственный стабильный ID |
Событие названо session_start | NAME_RESERVED | Переименуйте: first_visit, user_engagement зарезервированы |
У параметра префикс firebase_ | NAME_RESERVED для events.params | Не используйте префиксы _, firebase_, ga_, google_ |
Событие названо Link Click | NAME_INVALID | Буквы, цифры и _; начинайте с буквы |
| 26 параметров или значение из 120 симв. | Пустой массив (строгий режим это ловит) | Не более 25 параметров и 100 символов в значении |
timestamp_micros старше 72 часов | Пустой массив (строгий режим отклоняет) | Расслабленный режим переписывает на 72 часа назад |
Нет engagement_time_msec | Пустой массив | Укажите положительное число, иначе Realtime может быть пуст |
Две строки заслуживают пояснения. Согласно справочнику, префикс ga_ зарезервирован, однако при нашей проверке валидатор принял ga_session_id в обоих режимах, поэтому не считайте пустой массив разрешением. А ограничение значения в 100 символов постоянно затрагивает полные URL назначения: посадочная страница с пятью UTM-метками часто оказывается длиннее.
Сам client_id - более тонкий случай. Любая строка проходит расслабленную валидацию, но строгий режим отклонил и c1, и elido-12-4711 с сообщением "It should be in _ga; в руководстве по серверному отслеживанию GA4 это связывание подробно объяснено.
Как это используют пересылка в GA4 и проверка подключения Elido
Elido пересылает клики по коротким ссылкам в GA4 на стороне сервера. В карточке GA4 в разделе «Интеграции» вы указываете Measurement ID и API-секрет Measurement Protocol, после чего каждый клик в этом рабочем пространстве становится событием link_click:
{
"client_id": "elido-12-4711",
"events": [
{
"name": "link_click",
"params": {
"workspace_id": 12,
"link_id": 4711,
"slug": "spring-26",
"country": "DE",
"device": "mobile",
"destination": "https://shop.example/spring?utm_source=newsletter",
"engagement_time_msec": 100
}
}
]
}
client_id имеет вид elido-<workspace>-<link>, поэтому каждый клик по одной ссылке воспринимается как один и тот же пользователь GA4, и ни один из них не присоединяется к сеансу браузера. Это честный компромисс работы без cookie: итоги и разбивка по slug, стране и устройству работают, а количество пользователей и воронки сеансов - нет. Страна и устройство являются обычными параметрами события. Сначала зарегистрируйте их как специальные параметры. А destination длиннее 100 символов упирается в ограничение из таблицы выше, поэтому вместо него создавайте отчеты по slug или link_id.
Кнопка проверки подключения следует рекомендуемому в этой статье порядку:
Сначала она отправляет синтетический link_click с флагом elido_test: true на /debug/mp/collect. Если validationMessages не пуст, проверка завершается ошибкой и показывает описания Google дословно. Если массив пуст, то же событие по-настоящему отправляется на /mp/collect. Под кнопкой отображается ответ поставщика (HTTP-статус, отладочная конечная точка с вашим Measurement ID, но никогда не секретом, и тело ответа Google), а также примечание, что Measurement Protocol не проверяет API-секрет.
Зеленый результат означает «корректно, и Google получил запрос». Не «событие есть в вашем ресурсе». Тестовое событие содержит debug_mode: 1 и elido_test: true, поэтому оно отображается в DebugView как link_click; Realtime тоже работает. Если вам нужны события кликов в GA4 без тега на каждой посадочной странице, создайте рабочее пространство и сначала укажите в карточке GA4 тестовый ресурс.
Порядок отладки GA4 Measurement Protocol, который работает
Когда события GA4 не появляются, действуйте в таком порядке и останавливайтесь на первой ошибке:
- Отправьте тело запроса на
/debug/mp/collect, задав дляvalidation_behaviorзначениеENFORCE_RECOMMENDATIONS. Исправьте каждое сообщение. - Еще раз скопируйте API-секрет из «Администратор», «Потоки данных», вашего веб-потока, «API-секреты Measurement Protocol». Проверьте, что он относится к тому же потоку, что и ID
G-. - Отправьте одно событие на
/mp/collectсdebug_mode: 1и две минуты наблюдайте за DebugView. - Уберите флаг и проверьте Realtime, затем дайте стандартным отчетам день или два.
На шаге 2 заканчивается большая часть моих собственных отладок. Страница Google устранение неполадок начинается с тех же трех вопросов: правильный ли секрет, все еще ли он действителен, скопирован ли он без ошибок. Когда цифры наконец поступают, но все равно не совпадают с количеством кликов по ссылкам, статья клики по коротким ссылкам и сеансы GA4 объясняет расхождение, а серверное отслеживание конверсий рассматривает события конверсии, которые обычно идут следом. Та же привычка сначала проверить, затем подтвердить применима и к другим получателям данных на странице отслеживание конверсий.
Другие материалы блога
- Серверное отслеживание GA4 через перенаправления - учетные данные, структура тела запроса и связывание client_id.
- Mixpanel или GA4 для аналитики ссылок - какой инструмент должен хранить данные о кликах.
- Отслеживание ссылок в Mixpanel - та же пересылка, направленная в Mixpanel, с ее собственной особенностью: 200 на что угодно.
- UTM-параметры не отображаются в GA4 - версия этой проблемы отладки, связанная с данными кампании.
- Серверное отслеживание конверсий - GA4, Meta CAPI и TikTok рядом.
Частые вопросы
Как отлаживать события GA4 Measurement Protocol?
Отправьте то же тело запроса на https://www.google-analytics.com/debug/mp/collect вместо /mp/collect. Сервер валидации вернет массив validationMessages с названием поля, описанием проблемы и кодом, например NAME_RESERVED или VALUE_REQUIRED. Пустой массив означает, что структура корректна. Затем отправьте настоящее событие с debug_mode, равным 1, и убедитесь в DebugView, что оно пришло.
Почему мои события Measurement Protocol не отображаются в GA4?
Обычно причина в неверном или отозванном API-секрете, Measurement ID от другого потока, отсутствии client_id или слишком ранней проверке стандартных отчетов. Конечная точка возвращает 2xx во всех этих случаях, поэтому код статуса ничего не говорит. Проверьте тело запроса, затем вручную перепроверьте секрет и смотрите Realtime или DebugView, а не отчеты, которые могут запаздывать на день или больше.
Проверяет ли сервер валидации GA4 API-секрет?
Нет. В документации Google сказано, что сервер валидации не проверяет api_secret, а в нашем тесте 22 сентября 2026 года он также принял Measurement ID, не принадлежащий ни одному ресурсу. Пустой массив validationMessages означает только, что JSON правильно сформирован. Соответствует ли секрет потоку, можно подтвердить только увидев событие в GA4.
Появляются ли события, отправленные в /debug/mp/collect, в отчетах GA4?
Нет. Сервер валидации проверяет тело запроса и отбрасывает его, поэтому ничего из отправленного туда не попадет в отчеты, Realtime или DebugView. Чтобы увидеть событие в DebugView, отправьте его на обычную конечную точку /mp/collect с параметром debug_mode, равным 1, и положительным engagement_time_msec, как описано в руководстве Google по проверке.
Какой client_id нужно отправлять через GA4 Measurement Protocol?
Для веб-потока Google ожидает client_id, созданный тегом GA4 на вашем сайте, то есть значение из cookie _ga, чтобы серверные события присоединялись к сеансу браузера. В режиме проверки по умолчанию пройдет любая строка, но более строгий режим ENFORCE_RECOMMENDATIONS отклоняет ID не в формате число.число. Выдуманный ID все равно учитывает события, но никогда не присоединяется к сеансу браузера.
Сколько параметров может быть у события Measurement Protocol?
25 параметров на событие и 25 событий на запрос; имена до 40 символов, значения до 100 символов для обычного ресурса или до 500 для GA4 360. В нашем тесте режим проверки по умолчанию не отметил ни 26-й параметр, ни значение из 120 символов, а добавление validation_behavior со значением ENFORCE_RECOMMENDATIONS в отладочный запрос отметило их.
Попробуйте Elido
Вставьте URL - получите короткую ссылку
Без регистрации. Ссылка живёт 30 дней. Зарегистрируйтесь, чтобы оставить её навсегда.
Бесплатно, без регистрации · 2 в день