El endpoint y la variante de la UE
POST https://www.google-analytics.com/mp/collect?measurement_id=G-XXXX&api_secret=… es el endpoint de recogida documentado. Google también documenta https://region1.google-analytics.com/mp/collect para el tráfico procedente de la UE; Track usa el host region1 por defecto, de modo que las peticiones se originan y terminan en la UE.
El measurement_id es público (está en tu snippet de gtag). El api_secret se crea en Administrar → Flujos de datos → Secretos de API de Measurement Protocol y va en el almacén cifrado.
El cuerpo
{
"client_id": "1234567890.1700000000",
"user_id": "u_42",
"timestamp_micros": 1767225600000000,
"non_personalized_ads": false,
"consent": { "ad_user_data": "GRANTED", "ad_personalization": "DENIED" },
"user_data": { "sha256_email_address": ["<hash>"] },
"events": [{ "name": "purchase", "params": { "transaction_id": "A1001", "value": 129.9, "currency": "EUR", "items": [{ "item_id": "SKU-1", "price": 99.9, "quantity": 1 }], "engagement_time_msec": 100 } }]
}Límites según la referencia: como máximo 25 eventos por petición, 25 parámetros por evento, nombres de evento de hasta 40 caracteres y timestamp_micros con una antigüedad máxima de 72 horas. Los nombres que empiezan por google_, ga_ o firebase_ están reservados.
client_id es lo que todo el mundo olvida
GA4 vincula los eventos de servidor a las sesiones mediante client_id, el valor almacenado en la cookie _ga (GA1.1.<random>.<timestamp> → client_id = "<random>.<timestamp>"). Sin el client id real, los eventos de servidor forman sus propios usuarios huérfanos e inflan el número de usuarios.
Track lee la cookie _ga en el navegador cuando se ha dado el consentimiento de analítica, la envía con cada evento como ID de proveedor y la usa como client_id en las entregas al Measurement Protocol. Cuando no existe ningún valor _ga (fuentes puramente de servidor), deriva un pseudo client id estable a partir del ID anónimo, para que los eventos al menos se agrupen por visitante.
Siempre dice que sí: valida en el endpoint de depuración
El endpoint de producción devuelve 2xx para todo lo que sea sintácticamente aceptable. La única forma de conocer los problemas semánticos (tipos de parámetro desconocidos, nombres reservados, client id ausente) es el endpoint de depuración /debug/mp/collect, que responde con validationMessages. En modo de prueba, Track envía cada evento primero al endpoint de depuración y solo lo reenvía cuando la lista está vacía, de modo que un mapeo roto falla de forma visible en el asistente en lugar de hacerlo en silencio en producción.
Lo que el Measurement Protocol no puede hacer
- No crea sesiones por sí mismo; las vistas de página deben venir del gtag en el navegador.
- No tiene datos de geolocalización, dispositivo ni campaña a menos que los envíes; la mayoría de los equipos envían solo compras, reembolsos y eventos de backend.
- Los informes en tiempo real necesitan
engagement_time_msec(cualquier valor positivo) para que el usuario cuente como usuario con interacción. - La atribución a campañas sigue dependiendo de la sesión del navegador a la que pertenece el
client_id.
El reparto pragmático: gtag para vistas de página e interacciones, Measurement Protocol para la compra autoritativa con transaction_id (GA4 deduplica las compras por ID de transacción), los reembolsos y los eventos de backend.
Campos de consentimiento
Envía consent.ad_user_data y consent.ad_personalization derivados de las finalidades del visitante y establece non_personalized_ads: true cuando falte el consentimiento de marketing. El consentimiento de analítica es imprescindible para que el evento se envíe siquiera: el destino GA4 necesita en Track la finalidad de analítica, no la de marketing.
Lista de comprobación
- Pendiente: Measurement ID en el destino, API secret en el almacén cifrado
- Pendiente: client id de
_gacapturado con consentimiento de analítica - Pendiente: Las compras llevan
transaction_id; las compras de navegador y de servidor lo comparten - Pendiente: La validación de depuración pasa en modo de prueba
- Pendiente: Eventos confirmados en DebugView con los parámetros esperados