API de lectura
Recupere sus estadísticas por programa: paneles internos, informes, exportaciones. Reservada a los planes Pro y Agencia (y a la prueba activa).
Autenticación
Cree un token en Panel → Tokens API y páselo como Bearer:
curl -H "Authorization: Bearer SU_TOKEN" \ "https://quietmetrics.dev/api/v1/stats/qm_pub_XXXXXXXXXXXXXXXXX/summary?period=30d"
Todas las rutas llevan el prefijo /api/v1/stats/{clave_publica_del_sitio}. Un token solo da acceso a los sitios de su cuenta; un sitio que no le pertenece responde 404 (sin fuga de existencia).
Endpoints
| Endpoint | Contenido |
|---|---|
GET /summary |
KPIs del período + período anterior (comparación) |
GET /timeseries |
Serie temporal, un punto por día (curva) |
GET /breakdown |
Valores principales de una dimensión ({label, value}) |
GET /realtime |
Visitantes activos en los últimos 5 minutos ({"visitors": N}) |
Parámetros comunes
period acepta los mismos preajustes que el panel: today, yesterday, 7d, 30d (por defecto), month, last_month, 12m. Las fechas se calculan en la zona horaria del sitio. Un preajuste desconocido recae en 30d.
filters admite los mismos filtros que los clics del panel, en formato dimension:valor, separados por ;:
?filters=country:FR;device:mobile ?filters=page:/precios ?filters=channel:organic;browser:Firefox
dimension (breakdown): page, entry (páginas de entrada), referrer, channel, campaign, country, region, browser, os, device, lang, event. Dimensión desconocida → 422.
limit (breakdown): número de filas, 10 por defecto, 1 000 como máximo.
Ejemplos de respuesta
GET /summary?period=30d:
{ "site": "misitio.es", "period": { "preset": "30d", "from": "2026-06-16", "to": "2026-07-16" }, "filters": {}, "kpis": { "visitors": 4210, "pageviews": 9873, "bounce_rate": 0.47, "avg_duration": 74 }, "previous": { "visitors": 3877, "pageviews": 9145, "bounce_rate": 0.49, "avg_duration": 71 } }
GET /breakdown?dimension=page&limit=3:
{ "dimension": "page", "period": { "from": "2026-06-16", "to": "2026-07-16" }, "data": [ { "label": "/", "value": 3120 }, { "label": "/precios", "value": 1284 }, { "label": "/docs", "value": 977 } ], "capped": { "any": true, "dimensions": [ { "dimension": "page", "days": 2, "days_repaired": 2, "folded_values": 2812, "cap": 2000 }, { "dimension": "referrer", "days": 1, "days_repaired": 0, "folded_values": null, "cap": 500 } ] } }
Límite de cardinalidad (capped)
Cada sitio mide un número limitado de valores distintos por día y por dimensión. Más allá, los valores siguientes se cuentan juntos bajo una única etiqueta: el detalle se agrupa, no se pierde ninguna visita y los totales siguen siendo exactos. breakdown anuncia este estado en la clave capped:
anysiempre está presente ydimensionssiempre es una lista: el esquema no varía según el estado del sitio, así que no hace falta ninguna bifurcación para leerlo.dimensiones la dimensión limitada, no la que usted ha pedido.entryyexitse agrupan por el límitepage;sourceymediumse agrupan por el límitecampaign.dayscuenta los días locales limitados del periodo;capes el umbral más alto realmente aplicado (puede variar si se aplica un aumento a mitad del periodo).folded_values: nullNO significa cero. El número de valores agrupados solo se conoce tras la reconstrucción nocturna, que procesa un día como pronto en D+2.nullsignifica «límite alcanzado, número aún desconocido»;0significa «día reconstruido, ningún valor agrupado». Mostrar0en lugar denulldiría a sus usuarios que no pierden ningún detalle, lo cual es falso.days_repairedindica en cuántos de losdaysdías se conoce el recuento. Sidays_repaired < days,folded_valueses una suma parcial.
summary y timeseries no llevan esta clave: no leen ninguna dimensión y son insensibles al límite.
La exportación CSV del panel lleva el mismo indicador, pero en la cabecera HTTP X-Cardinality-Capped en vez de en el cuerpo del archivo: {"capped":false}, o {"capped":true,"dimension":"page","days":1,"days_repaired":1,"folded_values":2812,"cap":2000} acotado a la única dimensión exportada. El cuerpo del CSV sigue siendo dato máquina puro, sin fila de metadatos: ninguna fila sintética puede así falsear un total ni romper un analizador de número de columnas fijo.
Este límite puede aumentarse para su sitio: escriba al soporte.
Ejemplo PHP
$response = json_decode(file_get_contents( 'https://quietmetrics.dev/api/v1/stats/qm_pub_XXXX/summary?period=7d', false, stream_context_create(['http' => ['header' => "Authorization: Bearer SU_TOKEN\r\nAccept: application/json"]]) ), true); echo $response['kpis']['visitors'];
Errores
| Código | Significado |
|---|---|
401 |
Token ausente, inválido o revocado |
403 |
El sitio es suyo pero su plan no da acceso a la API (o la prueba ha expirado) |
404 |
Sitio desconocido, o perteneciente a otra cuenta |
422 |
Dimensión de breakdown desconocida |
Buenas prácticas
- Guarde en caché del lado cliente: consultar cada hora es más que suficiente. Ahora bien, un día cerrado no queda congelado para siempre: la reconstrucción nocturna vuelve sobre los días limitados y puede recalcular sus agregados hasta dos días después. Prevea, pues, una caché corta o una nueva consulta sobre los dos últimos días; más allá, los valores ya no se mueven.
- Un token por uso (uno para el panel interno, otro para el informe mensual): la revocación sigue siendo quirúrgica.
- Para una exportación puntual, cada vista del panel también se exporta en CSV desde el panel; no hace falta escribir código.
¿No encuentra su respuesta?
El soporte responde en días laborables.