GA4 no te dice cuándo te está mintiendo. Los números llegan, las filas se ven pobladas, pero por debajo: data muestreada (sampled), filas ocultas por umbrales de privacidad, queries colapsadas en un opaco bucket (other), dimensiones silenciosamente truncadas porque excedieron los límites de cardinalidad. La mayoría de equipos meten GA4 en Sheets y tratan el output como verdad absoluta. No lo es.
Esta guía es para meter data de GA4 en Sheets con la capa de integridad de datos intacta. Tres métodos para extraer (Reports Builder gratis, Apps Script, conector programado), los gotchas específicos de GA4 en cada capa (thresholds de sampling, thresholding de Google Signals, triggers del bucket (other), límites de cardinalidad, retención de 14 meses), y luego — la parte que se salta el resto de internet — los dos dashboards de integridad de datos: un detector de sampling/threshold y un splitter de dimensiones de alta cardinalidad.
Para reporting de paid media (creative testing en Meta Ads, targeting firmográfico en LinkedIn Ads) o velocidad del lado CRM (HubSpot a Sheets para RevOps), tenemos guías separadas. Este post va de la capa de confianza de los datos: ¿cuándo puedes creer lo que GA4 te devolvió? Para las preguntas equivalentes de capa de confianza en búsqueda orgánica (queries anonimizadas, el muro de retención de 16 meses), mira nuestra guía de Search Console a Google Sheets.
Por qué los informes de GA4 mienten (y cómo detectarlo)
Cuatro mecanismos hacen que GA4 devuelva data técnicamente válida pero prácticamente engañosa. Conocer el trigger de cada uno te permite evitarlos por diseño de la query.
1. Sampling. Cuando una query combina dimensiones de alta cardinalidad sobre un rango de fechas largo, GA4 muestrea tus sesiones y extrapola. Las propiedades GA4 estándar pegan sampling alrededor de ~10 millones de eventos por query en Explorations y al threshold equivalente vía Data API (el threshold exacto no está publicado, pero es más bajo que los 1.000 millones de 360). La query devuelve éxito — simplemente no hay aviso en la respuesta API de que los números son estimaciones.
2. Data thresholding (umbral de privacidad). Cuando Google Signals está activado y una fila contiene muy pocos usuarios para considerarse privacy-safe (típicamente menos de 10), GA4 oculta la fila entera. Tu total de sesiones arriba no coincide con la suma de filas abajo. Las propiedades pequeñas pegan más duro — un sitio B2B de nicho con 500 usuarios semanales puede perder más del 30% de filas por thresholding sin ningún aviso visible.
3. El bucket (other). Cada query de GA4 tiene un límite de cardinalidad. Para propiedades estándar, las combinaciones de dimensiones que exceden ~50.000 valores distintos se enrollan en una única fila (other) con los totales sobrantes. Consulta page_path con query strings sobre un año de data y verás que la mayoría de tu tráfico desaparece en (other). Los totales de las métricas son correctos; la atribución por fila está perdida.
4. Drops de cardinalidad en la propia dimensión. Las dimensiones custom configuradas con alta cardinalidad (un user_id, un transaction_id, un session ID único) pegan el límite de cardinalidad de GA4 y dejan de registrarse para nuevos eventos. La Data API sigue consultando el campo, pero con data truncada.
Ninguno tira errores. La query devuelve 200 OK. Pegas en tu dashboard. El dashboard miente. La solución es o diseño de query (rangos de fecha más pequeños, menos dimensiones, paths agregados) o pasar al export GA4 → BigQuery, donde sampling y thresholding no aplican porque consultas raw event data directamente. Pero ese es otro pipeline; este post va de Sheets.
Lo que los cuatro problemas comparten: son detectables desde la respuesta si sabes qué buscar. La Data API devuelve flags de metadata para sampling, conteos de threshold para filas ocultas, y la fila (other) aparece literalmente en los datos. Los métodos abajo explican cómo cada path de extracción expone (u oculta) esos flags.
Método 1: GA4 Reports Builder (add-on oficial gratis)
Este es el add-on de spreadsheet del propio Google. Llama a la GA4 Data API por debajo pero te oculta el código — y oculta también los flags de integridad de datos, que es su mayor debilidad para reporting serio.
Setup: abre una Google Sheet nueva → Extensiones → Add-ons → Obtener add-ons → busca GA4 Reports Builder for Google Analytics → instala → Extensiones → GA4 Reports Builder → Create new report. Elige propiedad, dimensiones, métricas, rango de fechas, clic Create reports, luego Run reports.
Gotchas específicos de GA4 en esta capa:
- No hay indicador de sampling. El add-on no expone el campo
samplingMetadatasque devuelve la Data API. Tu informe se ve limpio mientras la mitad de la data está extrapolada. - No hay conteo de threshold. La Data API devuelve
propertyQuota.thresholdedConcurrentRequestsen metadata, pero el add-on no lo muestra. Las filas ocultas por Google Signals desaparecen en silencio. - El bucket
(other)aparece como fila literal con label(other). Esta sí la puedes ver — pero solo si scroleas la tabla. Si ordenas por sesiones descendente,(other)puede ser la fila superior. - Límite de filas por llamada. La Data API devuelve máximo 100.000 filas por llamada. Reports Builder no pagina; las queries que necesitan más se truncan.
- Sin distinción 360. El add-on no te dice si estás en estándar o 360, lo cual importa porque los thresholds de sampling son 100x diferentes.
Encaja cuando: snapshot trimestral para board en una dimensión alta (channel, source/medium), check semanal de tráfico de propiedad pequeña.
No encaja cuando: cualquier informe donde necesites saber si la data fue muestreada, reporting multi-propiedad, queries que se acercan al límite de cardinalidad (la mayoría de análisis a nivel página).
Método 2: Google Apps Script + GA4 Data API
Para analistas que quieren los metadata de sampling y threshold expuestos. La Data API los devuelve en cada respuesta; solo tienes que leerlos y mostrarlos. Setup: 1–2 horas. Mantenimiento: tuyo, incluyendo manejar el refresh del token OAuth.
Paso 1 — Habilita la API. En Google Sheets, abre Extensiones → Apps Script → Services → Add Google Analytics Data API v1beta. El service gestiona OAuth automáticamente usando tu cuenta de Google.
Paso 2 — Apps Script que expone flags de integridad de datos. Pega en Apps Script:
function pullGA4WithIntegrityFlags() {
const PROPERTY_ID = 'YOUR_PROPERTY_ID';
const request = {
dateRanges: [{ startDate: '30daysAgo', endDate: 'yesterday' }],
dimensions: [
{ name: 'sessionDefaultChannelGrouping' },
{ name: 'date' }
],
metrics: [
{ name: 'sessions' },
{ name: 'totalUsers' },
{ name: 'keyEvents' }
],
// Pide el metadata que señala sampling y thresholding
returnPropertyQuota: true,
keepEmptyRows: false
};
const report = AnalyticsData.Properties.runReport(request, 'properties/' + PROPERTY_ID);
// Inspecciona flags de integridad de datos
const sampled = (report.metadata && report.metadata.samplingMetadatas)
? report.metadata.samplingMetadatas
: null;
const dataLossFromOther = (report.metadata && report.metadata.dataLossFromOtherRow) || false;
const quota = report.propertyQuota || {};
const concurrent = quota.concurrentRequests || {};
const thresholdedReports = (concurrent.consumed || 0);
const sheet = SpreadsheetApp.getActiveSheet();
sheet.clear();
// Fila superior: avisos de integridad de datos
sheet.appendRow(['FLAGS DE INTEGRIDAD DE DATOS']);
sheet.appendRow(['Sampled?', sampled ? 'YES - revisa samplingMetadatas' : 'No']);
sheet.appendRow(['Fila (other) presente?', dataLossFromOther ? 'YES - cardinalidad excedida' : 'No']);
sheet.appendRow(['Threshold concurrent consumido', thresholdedReports]);
sheet.appendRow([]);
// Luego la data
sheet.appendRow(['Channel', 'Date', 'Sessions', 'Users', 'Key events']);
(report.rows || []).forEach(r => {
sheet.appendRow([
r.dimensionValues[0].value,
r.dimensionValues[1].value,
r.metricValues[0].value,
r.metricValues[1].value,
r.metricValues[2].value
]);
});
}Paso 3 — Programa. Apps Script → Triggers → Add Trigger → ejecutar diariamente a las 6 AM. Crítico: las filas superiores muestran flags de integridad de datos para que sepas si confiar en el informe antes de leerlo.
Gotchas específicos de GA4 en la capa API:
- La Data API devuelve metadata de sampling solo si lo pides. Tienes que leer
response.metadata.samplingMetadataspor rango de fechas. Saltarte ese check es por lo que la mayoría de scripts caseros esconden el sampling. dataLossFromOtherRowen response.metadata. Señala que el bucket(other)absorbió filas. Si tu dimensión es de alta cardinalidad (page_path con query strings, URLs completas), este flag es lo que te dice que rediseñes la query.- Los errores de quota vuelven como HTTP 429 con
quotaExceededen el body. Propiedades gratis: 25.000 tokens/día estándar. Propiedades 360: 250.000/día. Breakdowns diarios × muchas propiedades pegan esto rápido. - Retención de 14 meses para propiedades estándar. Si consultas data más vieja que 14 meses, no obtienes nada (sin error, solo filas vacías). Para historia más larga, el export GA4 → BigQuery es el único camino.
- Cap de cardinalidad en custom dimensions. Las dimensiones custom event-scoped paran de registrar nuevos valores después del cap diario de cardinalidad (~50.000 valores distintos). La API sigue consultando el campo — solo con data truncada.
Para contexto del lado dashboard una vez la data aterriza en Sheets, mira nuestra guía de automatización de Google Sheets.
Sáltate la gimnasia de quotas de GA4
Tokens de quota, parseo de metadata de sampling, detección de bucket (other), conteos de threshold. Dataslayer expone todo automáticamente, más otros 50+ conectores (Google Ads, Meta, LinkedIn, HubSpot) en el mismo workbook.
Probar Dataslayer GratisMétodo 3: Conector programado (no-code)
Para equipos reportando GA4 semanalmente en múltiples propiedades, con flags de integridad visibles y uso de quota tracked entre queries.
Dataslayer conecta GA4 a Google Sheets en menos de 10 minutos. Desde Google Sheets: Extensiones → Add-ons → Obtener add-ons → instala Dataslayer. Luego Extensiones → Dataslayer → Abrir, elige GA4, autentícate, elige propiedades, elige métricas + dimensiones (el field picker las categoriza por Acquisition, Engagement, Monetization, Tech, Custom), ajusta rango de fechas, clic Run.
Por qué un conector gana específicamente para trabajo de integridad de datos en GA4:
- Flag de sampling expuesto por query. Cuando la Data API devuelve
samplingMetadatas, el conector lo muestra junto al resultado para que sepas descontar los números. - Detección de bucket (other). Si tu query pegó el límite de cardinalidad, el conector avisa y sugiere dividir el rango de fechas.
- Multi-propiedad agrupado dentro de quota. Sacar 10 propiedades de cliente en un workbook es un bloque de query por propiedad. Cada una respeta su propia quota; no balanceas a mano.
- Conciencia de retención de 14 meses. Las queries para fechas más viejas devuelven un aviso claro en vez de filas vacías silenciosas.
- Exposición de reporting identity. La GA4 Data API usa la identidad que especifiques; el conector por defecto usa
DEVICE_BASED(coincide con el default de API) y te deja cambiar aBLENDED(coincide con el default UI) por query, así la reconciliación entre Sheets y la UI de GA4 es directa.
Precios: Gratis para 1 conector y 1 usuario. Starter $35/mes anual cubre 3 conectores y 1 destino. Advanced $115/mes añade refresh horario, AI Insights, e integración MCP para Claude/ChatGPT (le preguntas a Claude "¿se muestreó nuestra data de GA4 la semana pasada?" y consulta en directo). Pro $345/mes cubre 100+ cuentas por conector. Mira dataslayer.ai/pricing.
El gotcha de GA4 que NINGÚN método resuelve: el export GA4 → BigQuery. Para data sin samplear, sin thresholdear y con cardinalidad completa, tienes que habilitar el export BigQuery en admin de GA4 y consultar BigQuery directamente. Los métodos de este post tiran de la Data API — que es conveniente pero sujeta a los cuatro problemas de integridad de arriba. Si necesitas raw event data, BigQuery es el único camino.
Los 2 dashboards de integridad de datos que merece la pena construir
Una vez la data fluye a Sheets con los flags de metadata expuestos (método Apps Script o conector), aquí están los dos informes que hacen el reporting de GA4 fiable. Ninguno es algo que la UI de GA4 muestre, y ambos requieren la capa de metadata que el Método 1 oculta.
Dashboard 1: Detector de sampling y threshold
La pregunta: entre todos mis informes, ¿cuáles contienen data muestreada, thresholdeada o truncada por (other) — y cuánto del informe está afectado?
Columnas a extraer de GA4:
- Nombre del informe (una fila por query en tu workbook)
samplingMetadatas(por rango de fechas): contienesamplesReadCountysamplingSpaceSizedataLossFromOtherRow(boolean por query)- Total de sesiones (métrica top-level)
- Suma de filas de sesiones en el resultado (suma la columna de métrica)
Cálculos en Sheets:
- Sampling ratio:
samplesReadCount / samplingSpaceSizepor rango de fechas — valores menores a 1.0 significan que la data está muestreada - Threshold ratio:
(total top-level - SUMA(sesiones por fila)) / total top-level— valores mayores a 0 significan filas ocultas por thresholding - (other) ratio:
sesiones_fila_(other) / total_sesiones— valores mayores a 0.05 significan que el límite de cardinalidad está mordiendo - Score de integridad: métrica compuesta, ej.
=SI(O(sampling_ratio<1, threshold_ratio>0, other_ratio>0.05), "WARNING", "OK")
Layout de pivot:
- Filas: nombre del informe (uno por query en tu workbook)
- Columnas: sampling ratio, threshold ratio, (other) ratio, score de integridad
- Formato condicional: rojo cuando score de integridad = WARNING
Qué saca a la luz que la UI de GA4 no:
- "El informe de landing pages tiene 47% de sesiones en el bucket
(other)" → la query es demasiado granular, agrega a páginas top-level - "El informe de retención por cohorte muestra sampling_ratio = 0.34" → solo 34% de la data fue leída; el resto es extrapolada. Mueve esto a un export BigQuery.
- "El informe de segmentos de audiencia tiene threshold_ratio = 0.18" → 18% de filas están ocultas. Propiedad demasiado pequeña para esa segmentación; consolida.
Dashboard 2: Splitter de dimensiones de alta cardinalidad
La pregunta: cuando necesito data a nivel página sobre un rango de fechas largo, ¿cómo divido la query para evitar el límite de cardinalidad y el bucket (other)?
Estrategia: en vez de una query para (page_path, date) × 90 días, divide en muchas queries más pequeñas. Cada query se mantiene bajo el límite de ~50.000 valores distintos. Cose los resultados en Sheets.
Estrategias de splitting:
- Por chunk de fecha. Consulta semanal en vez de mensual. 4 queries por mes, cada una bien bajo el límite.
- Por sección. Filtra por prefijo de
page_path. Consulta/blog/*,/product/*,/pricing/*separadamente, luego cose. - Por fuente de tráfico. Si una sola fuente domina, filtra por
sessionMedium=organic, luego corre separadamente para paid y direct. - Solo landing page. Usa
landingPageen vez depagePath. Cardinalidad más baja porque los usuarios aterrizan en menos URLs únicos que los que navegan.
Cálculos en Sheets:
- Estimado de cardinalidad por query:
=CONTAR.UNICO(columna_page_path)por chunk — marca chunks por encima de 40.000 para dividir más - Sesiones cosidas:
=SUMAsobre todos los chunks para el mismo periodo y combo de dimensión - Fuga de (other): si algún chunk aún muestra
(other), aísla la fecha o sección ofensora y re-divide
Qué permite esto que una sola query no:
- Performance a nivel página sobre 365 días sin perder data en
(other) - Auditorías de contenido donde necesitas el conteo real de sesiones de cada URL, no el bucket enrollado
- Joins fiables con otras fuentes de datos por URL — el join solo funciona cuando cada URL está en su propia fila
Para análisis del lado contenido una vez tienes data sin samplear a nivel URL, mira Por Qué la Atribución de Marketing Está Rota en 2026.
Comparando los tres métodos
| Aspecto | Reports Builder | Apps Script | Conector programado |
|---|---|---|---|
| Tiempo de setup | 5 min | 1–2 hr | Menos de 10 min |
| Coste | Gratis | Gratis | Desde $35/mes |
| Flag de sampling visible | No | Sí (con código) | Sí (automático) |
| Conteo de threshold visible | No | Sí (con código) | Sí (automático) |
| Aviso de bucket (other) | Solo como fila | Vía dataLossFromOtherRow |
Aviso automático |
| Multi-propiedad en una hoja | Un bloque por cada una | Loop en código | Nativo, un bloque por cada una |
| Paginación sobre 100K filas | No (trunca) | Sí (escribe el loop) | Automática |
| Refresh programado | Manual | Triggers Apps Script | Built-in (tier horario) |
| Mantenimiento de código | Ninguno | Owner | Proveedor |
La decisión: para GA4, la respuesta casi siempre involucra la capa de metadata. Si no tienes el flag de sampling, conteo de threshold y aviso de (other) visibles, vas a ciegas. Eso significa Apps Script o conector — y para reporting multi-propiedad, el conector gana solo por la conciencia de quota.
Quirks específicos de GA4 que vale la pena saber
Cinco comportamientos de GA4 que afectan a cada método y cada dashboard:
- Thresholding de Google Signals. Las propiedades con Signals activado ocultan filas que no cumplen el threshold de privacidad (típicamente <10 usuarios). El owner de la propiedad puede apagar Signals para la reporting identity en Admin → Property → Data Settings → Reporting Identity (usa "Device-based" en vez de "Blended"). Solo hazlo si tu política de privacidad lo permite.
- Retención estándar de 14 meses. La data más vieja que 14 meses devuelve filas vacías en propiedades estándar. 360 retiene hasta 50 meses. Para historia más larga, el export GA4 → BigQuery es el único camino.
- La elección de reporting identity cambia los números. La UI de GA4 por defecto es Blended; la Data API por defecto es Device-based. Misma propiedad, mismo rango de fechas, números distintos. Elige una identity en tu query y mantenla en todos los informes.
- La Data API no incluye data real-time. El endpoint estándar
runReportexcluye los últimos 30 minutos por defecto. Para data live usarunRealtimeReport, que tiene su propio set (mucho más pequeño) de dimensiones y métricas. - Los thresholds de sampling estándar vs 360 difieren ~100x. Las propiedades estándar pegan sampling mucho antes. Si tu propiedad está en 360, puedes ignorar muchas preocupaciones de sampling; si no, diseña cada query asumiendo que sampling va a pegar.
Errores comunes y cómo leerlos
Algunos errores aparecen lo bastante como para que reconocerlos ahorre tiempo de debugging.
RESOURCE_EXHAUSTED o HTTP 429 con quotaExceeded: pegaste una quota de Data API — tokens diarios, tokens horarios o requests concurrentes. Propiedades estándar: 25.000 tokens/día. Propiedades 360: 250.000/día. Solución: reducir frecuencia, batches con menos informes por script run, o mover queries pesadas a una hora más tarde cuando la quota se resetea.
INVALID_ARGUMENT en nombre de dimensión o métrica: GA4 deprecia y renombra métricas. conversions fue renombrado a keyEvents en 2025. Las queries antiguas se rompen en silencio. Solución: revisa la referencia del schema de Data API para el nombre actual.
Filas vacías sin error: la propiedad es demasiado pequeña para la combinación de dimensión + thresholding está activado, o el rango de fechas es más viejo que 14 meses, o tu reporting identity devolvió cero usuarios. Revisa el flag de threshold en metadata primero.
Discrepancia con la UI de GA4: la causa más común es reporting identity distinto (UI default Blended vs API default Device-based). Segunda más común: la ventana de procesamiento de 30 minutos de la UI no aplicada aún a la API. Tercera: sampling en un lado y no en el otro para el mismo rango de fechas. Matchea identity y rango de fechas exactamente al reconciliar.
Fila (other) dominando el informe: tu combinación de dimensión excedió el límite de cardinalidad. Solución: divide por chunk de fecha, por sección, o por fuente de tráfico como se describe en el Dashboard 2.
FAQ
¿Cómo sé si mi query de GA4 fue muestreada?
Lee response.metadata.samplingMetadatas. Si samplesReadCount / samplingSpaceSize es menor a 1.0, tu data está muestreada. Reports Builder lo oculta; Apps Script y conectores lo exponen. En 360 los thresholds de sampling son mucho más altos (~100x), así que la mayoría de queries se quedan sin samplear.
¿Por qué mis sesiones de GA4 no cuadran entre Sheets y la UI?
Tres causas comunes: (1) reporting identity distinto (UI default Blended vs Data API default Device-based), (2) thresholding de Google Signals oculta filas en uno pero no en el otro, (3) sampling triggered en la query más grande pero no en la más pequeña. Matchea identity y rango de fechas, y revisa metadata de threshold/sampling.
¿Qué es la fila (other) y por qué es a veces enorme?
GA4 tiene un límite de cardinalidad por query (~50.000 valores distintos de dimensión para propiedades estándar). Cuando tu combinación de dimensión excede eso, todo pasado el límite se enrolla en una sola fila (other) conteniendo los totales sobrantes. Los totales de las métricas son correctos; la atribución por fila se pierde. Solución: divide la query por fecha o por sección para mantenerte bajo el límite.
¿Aplica el sampling a los exports BigQuery?
No. El export GA4 → BigQuery contiene raw event data, no informes agregados. Sampling y thresholding son artefactos del tiempo de agregación; no aplican a eventos raw. Para análisis sin sampling a escala, BigQuery es el único camino. El setup requiere habilitar el export en admin de GA4 y un proyecto de Google Cloud con billing habilitado.
¿Cómo meto más de 14 meses de data de GA4 en Sheets?
No puedes directamente desde la Data API en una propiedad estándar. Las opciones son: habilitar el export GA4 → BigQuery (hacia delante), upgradear a GA4 360 (50 meses de retención), o archivar pulls mensuales de la Data API a una Sheet separada para construir una historia más allá de lo que GA4 retiene.
¿Por qué algunas de mis custom dimensions devuelven data truncada?
Las dimensiones custom event-scoped tienen un cap diario de cardinalidad (~50.000 valores distintos por día en propiedades estándar). Después de pegar el cap, nuevos valores distintos dejan de registrarse el resto del día. Solución: no uses IDs únicos (user_id, transaction_id) como custom dimensions event-scoped — úsalos a nivel user o setup el export BigQuery.
¿Debería usar la GA4 Data API o el export GA4 → BigQuery?
Data API para informes agregados (sesiones, conversiones, channel grouping) hasta los límites estándar de sampling/threshold. BigQuery export para raw event data, joins con otros warehouses, retención a largo plazo, y cualquier análisis que no tolere sampling. Muchos equipos corren ambos: Data API para dashboards semanales, BigQuery para deep dives analíticos.
Conclusión
Tres métodos para meter data de GA4 en Google Sheets existen en un espectro: Reports Builder gratis para snapshots trimestrales en dimensiones altas, Apps Script para analistas que quieren los flags de integridad expuestos vía código, conector programado para equipos corriendo informes semanales multi-propiedad con conciencia de quota y sampling de serie.
Pero los métodos son medios, no el fin. El deliverable son los dos informes de integridad de datos: un detector de sampling/threshold que marca informes en los que no puedes confiar, y un splitter de dimensiones de alta cardinalidad que te deja consultar data a nivel página sin perderla en el bucket (other). Ambos requieren la capa de metadata que Reports Builder oculta — y la mayoría de equipos aceptan lo que GA4 devuelve como verdad, luego construyen dashboards sobre data que ha sido en silencio muestreada, thresholdeada o truncada.
Expón los flags de integridad. Divide la cardinalidad. El conector es una tarde de jueves de setup; la confianza en los datos es algo en lo que vas a confiar cada lunes durante el próximo año. Empieza una prueba gratis de Dataslayer si quieres saltarte el parseo de metadata y llegar a los dashboards más rápido.


.avif)




