Cuatro fallos medidos sobre los datos de julio 2026, con la evidencia que los demuestra, qué se puede recuperar sin tocar la web y qué hay que arreglar en origen.
| Fallo | Impacto en julio 2026 | ¿Recuperable? | Dónde se arregla |
|---|---|---|---|
| 1 · La campaña no llega a HubSpot | 38 de 88 registros (43%) y 11 de 17 SQL (65%) sin campaña → 19 y 3 tras recuperar por gclid | Recuperado 2026-08-03 · caduca 2026-10-28 | Web + pull mensual |
| 2 · Talento contado como SQL de demand | 1 de 17 SQL en julio · 3 en junio · 0 en mayo | Sí, filtro en el script | Definición de KPI |
| 2b · La excepción de la etiqueta GA4 no bloquea | 8.384 page_view en app pese a estar excluido por hostname | Sí, corrigiendo el trigger | Contenedor GTM |
| 3 · Origen perdido en el salto www → app | 641 de 1.385 registros GA4 como tráfico directo | Parcial | Cross-domain / consent |
| 4 · Clics facturados que no generan sesión | DG_Supply: 8.543 clics → 416 sesiones (4,9%) | — | Determinar causa primero |
En HubSpot, esos contactos tienen hs_analytics_source = PAID_SEARCH (así que sabemos que vienen de Google Ads) pero hs_analytics_source_data_1 = "Auto-tagged PPC" en lugar del nombre de campaña. En el panel de inversión aparecen como Campaña sin resolver: cuentan en el objetivo del canal, pero no se pueden imputar a ninguna campaña ni entrar en ningún CPL por campaña.
Comparando la URL de primer contacto (hs_analytics_first_url) de los contactos que sí resuelven campaña contra los que no, en el mismo mes y con la misma fuente:
| Grupo | n | Lleva hstk_campaign | Lleva _gl= | Tiene gclid guardado |
|---|---|---|---|---|
Resuelven _brand_google_search__ | 45 | 45 / 45 | 0 | sí |
Resuelven pmax_supply_registro_es | 22 | 22 / 22 | 1 | sí |
| No resuelven (Auto-tagged PPC) | 35 | 0 / 35 | 35 / 35 | 35 / 35 |
La correlación es perfecta en los dos sentidos, así que no es casualidad ni una campaña concreta mal configurada.
Todas las campañas de la cuenta llevan la plantilla de seguimiento de HubSpot, que añade a la URL final hstk_campaign (el ID numérico de la campaña), hstk_creative, hstk_network=googleAds y hsa_acc=3453900141. HubSpot resuelve el nombre de campaña leyendo ese parámetro en la URL, no traduciendo el gclid.
Cuando el primer pageview que registra HubSpot no es la landing de la campaña sino una navegación posterior, esa URL ya no lleva los parámetros: solo queda el gclid, que Google propaga. HubSpot entonces sabe que es Paid Search pero no de qué campaña, y escribe el literal "Auto-tagged PPC". El marcador de que la URL es una navegación posterior es _gl=, la decoración que añade el enlazador cross-domain de Google Analytics, presente en los 35 casos fallidos y en ninguno de los 67 que funcionan.
Las páginas donde HubSpot engancha el primer pageview de esos 35 son variadas y muchas no son landings de campaña: /politica-de-privacidad, /we-are-shakers, app.shakersworks.com/login. Cinco de los 35 tienen la primera URL directamente en app.shakersworks.com.
Cargando una landing de campaña con parámetros reales y sin aceptar el banner, el estado del navegador es:
Mientras __hs_do_not_track está puesta, HubSpot no crea hubspotutk ni registra visitas. El seguimiento arranca cuando el visitante acepta el banner, y lo hace desde la página en la que esté en ese momento. De ahí las dos poblaciones:
hstk_campaign → campaña resuelta. Son los 67._gl= y sin parámetros de campaña. Solo queda el gclid → "Auto-tagged PPC". Son los 35.El dato del CRM lo confirma: esos 35 contactos sí tienen historial de navegación en HubSpot (mediana de 7 páginas vistas y 3 visitas), así que no es que HubSpot no les trackee nunca, es que empezó a trackearles tarde. Los 45 que resuelven Brand tienen mediana de 16 páginas y ninguno con cero.
js.hs-analytics.net/analytics/…/6704369.js (HubSpot), gtm.js y gtag/js. En app.shakersworks.com no se ha podido comprobar porque requiere sesión iniciada: queda pendiente ahí.hs_analytics_source_data_2 (c1d25565-f664-4089-9f0a-1734cc1b3a65), identificador que no hemos podido asociar a nada. Pista, no conclusión.shk_* guarda ya fuente, medio, gclid y landing de primera visita — solo falta la campaña — y viaja en el formulario, donde el usuario facilita sus datos de forma consciente. Antes de tocar el orden de carga o el comportamiento pre-consentimiento, validar con un experto humano en privacidad.Los 35 contactos tienen el gclid completo guardado en hs_google_click_id, y la API de Google Ads lo traduce a campaña con el recurso click_view. Verificado con match exacto:
click_view solo devuelve clics de los últimos 90 días, y exige filtrar por un único día. La recuperación de julio 2026 caduca el 2026-10-28; desde el 2026-09-28 se empieza a perder el arranque del mes. Pasado ese plazo el volumen se queda sin campaña para siempre.Implementado en deploy/pull-google-ads.py. Para cada contacto sin campaña que tiene hs_google_click_id se consulta click_view: primero el día de la primera visita que registra HubSpot y, si no hay match, se barre el resto de la ventana (el clic puede ser de días antes de que el visitante aceptara cookies). La campaña recuperada entra en todas las lentes de origen: SQL por campaña, origen supply y panel de inversión y objetivos.
| Lente | Sin campaña | Con gclid | Recuperados | Siguen sin resolver |
|---|---|---|---|---|
| SQL de demand | 11 | 11 | 8 (73%) | 3 |
| Contactos supply | 42 | 27 | 19 (45%) | 23 |
Lo recuperado va casi entero a Brand: 6 de los 8 SQL y los 19 registros de talento son _BRAND_Google_Search__. Los otros dos SQL son SHT_Backend_Enterprise_Q2 y PMax_Supply_Registro_ES. Es coherente con la causa: quien llega por Brand navega más antes de aceptar el banner, así que es la campaña que más volumen perdía.
Efecto en las cifras publicadas: los registros de talento originados por Brand en el CRM pasan de 38 a 57, los SQL de Brand de 1 a 7, y el bloque sin resolver baja de 38 a 19 registros y de 11 a 3 SQL. Los totales del canal no se mueven (88 registros, 17 SQL): esto reparte, no crea volumen.
click_view en el día de la primera visita. Estos últimos requieren el barrido completo de la ventana, que necesita credenciales de la Google Ads API en el entorno del script.El KPI SQL CRM de la pestaña Demand cuenta contactos creados en el mes con lifecyclestage en salesqualifiedlead, opportunity o customer y fuente original Paid Search. Pero el funnel de talento usa el mismo campo lifecyclestage, así que un talento que avanza en su propio ciclo entra en el conteo de SQL de empresas.
Contactos que cumplen la definición de SQL y además tienen lead_status_supply (es decir, son talento):
| Mes | SQL contados | De los cuales son talento | Peso |
|---|---|---|---|
| Julio 2026 | 17 | 1 (lifecycle customer, supply status "Active user", sin empresa) | 6% |
| Junio 2026 | 18 publicados | 3 | 17% |
| Mayo 2026 | 34 | 0 | 0% |
Es el mismo tipo de contaminación que ya corregimos con los contactos de prueba de QA Shakers, y se arregla igual: un filtro en el script. La diferencia es que este cambia un número ya publicado, así que no lo he aplicado: hay que decidir si el SQL de demand excluye a los contactos con lead_status_supply.
PMax_Supply_Registro_ES originó 2 SQL de demand. Los dos aterrizaron en /unirme-a-shakers, una página de talento. Uno es el talento del párrafo anterior; el otro es un contacto de empresa real que llegó por una landing de talento. Por eso su gasto se declara pero no se reparte: el volumen es pequeño y la mitad se explica por el fallo de definición, no por un cruce real de audiencias.Configuración actual de la etiqueta GA4 – Pageview: se activa con el trigger Todas las páginas (Hubspot) (Page View, cuando Page Hostname no contiene app.shakersworks.com) y tiene como excepción App Exclude (tipo Inicialización, Page URL coincide con app\.shakersworks\.com(?!/register/talent)).
Dos problemas, independientes del de HubSpot:
gtm.js) y la excepción es de tipo Inicialización (gtm.init), que ocurre antes y es otro evento distinto. Nunca coinciden, así que la excepción es decorativa: no bloquea ni un disparo.(?!/register/talent) buscaba "excluir app salvo la página de registro de talento", eso no se consigue con una excepción, que solo sabe bloquear. Y tampoco hace falta: el trigger principal ya excluye todo app por hostname. Para incluir /register/talent hay que ampliar el trigger de activación (hostname no contiene app o la ruta empieza por /register/talent), no añadir una excepción.Además la regex no está anclada, así que si alguna URL lleva la propia dirección dentro de un parámetro (un redirect_uri, por ejemplo) puede coincidir por esa segunda aparición y bloquear páginas que no toca.
app por hostname, GA4 registró 8.384 page_view en app.shakersworks.com en julio. Alguien más los está enviando: la propia aplicación, otra etiqueta del contenedor o la medición mejorada de la configuración de GA4. Hay que revisarlo en el contenedor completo, porque implica que la exclusión no tiene el efecto que se busca y puede haber doble medición.Para contexto, así se reparten los eventos por dominio en julio 2026: registro_talent ocurre al 100% en app (1.385 eventos) y supply_form al 100% en www (584). El registro vive en la aplicación y el formulario en la web, así que la continuidad entre dominios es justo lo que decide si el registro se puede atribuir.
El registro de talento termina en app.shakersworks.com, mientras la landing está en www.shakersworks.com. En GA4, de los 1.385 eventos registro_talent de julio, 641 (46%) tienen origen (direct)/(none) y 39 más aparecen como (not set).
_gl= del enlazador cross-domain, y 5 de ellos tienen su primer pageview ya dentro de app. Para dimensionarlo hace falta una prueba de navegación completa (landing en www con parámetros → registro en app) comprobando qué llega a GA4 y a HubSpot en cada paso.Esto es lo mismo que Jose describió como pérdida de tracking entre MQL y producto: mismo salto de dominio, mismo síntoma.
DG_Supply_TierA_AILLM_ES_Prospecting facturó 8.543 clics en julio y GA4 registró 416 sesiones (4,9%). Las otras campañas de la cuenta se mueven entre el 19% y el 61%, así que no es el nivel de pérdida normal por rebote o bloqueo de cookies.
La landing (/unirme-a-shakers) está en www y sí está medida, así que no es un dominio fuera de GA4. Los 416 que llegan se comportan de forma razonable: 68,5% de sesiones con engagement y 293 segundos de media. Es decir, la audiencia que aterriza no es basura; lo que no cuadra es el volumen facturado.
deploy/pull-google-ads.py: los contactos sin campaña que tienen hs_google_click_id se resuelven contra click_view de la Google Ads API y la campaña recuperada entra en todas las lentes de origen (SQL por campaña, origen supply, panel de inversión). Resultado en julio: 8 de 11 SQL (73%) y 19 de 42 contactos supply (45%). Detalle en el fallo 1 y en Salud Operativa de la ficha. Es una capa de reporting: no arregla el CRM, y la ventana de 90 días vence el 2026-10-28.shk_* antes del consentimiento; falta añadir la campaña (de utm_campaign o hstk_campaign) y mandarla como propiedad de contacto en el submit. Es la reparación de raíz del fallo 1 y no depende de cuándo acepte el visitante. Validar el enfoque con un experto humano en privacidad antes de implementarlo./register/talent, va en el trigger de activación. Y averiguar de dónde salen los 8.384 page_view de app que el trigger debería estar excluyendo.lead_status_supply, aplicarlo en el script y reexpresar junio (18 → 15). Cambia un número publicado, así que es decisión de negocio.