Desarrolladores
Analítica
Visitas de tus blogs y artículos por la API de Blogenia: series por día, semana o mes, ranking de artículos y total de la cuenta con el permiso stats:read.
Cuatro rutas devuelven las visitas de tu cuenta, de un blog o de un artículo, como las APIs de analítica de cualquier herramienta web.
Reglas comunes
Las rutas de analítica comparten estas reglas:
- Fechas.
fromytoson díasYYYY-MM-DDen la zona Europe/Madrid, ambos incluidos. Por defecto, los últimos 30 días; el máximo son 400 días por petición. - Frescura. Los datos los vuelca un proceso que se ejecuta cada 10 minutos.
updatedAtes la hora de la última pasada (ISO 8601 en UTC) y puede sernullsi todavía no se conoce. - Día en curso. El grupo de la serie que contiene hoy aún no ha terminado y lleva
partial: true. - Únicos aproximados.
uniquesApproxse calcula con un identificador anónimo que cambia cada día y sin cookies, así que es una aproximación. No se pueden sumar días como si fueran personas distintas: por eso el total se llamauniquesApproxSum. - Series densas. Los días sin visitas aparecen con
0; no hay huecos. - Caché. Blogenia guarda cada respuesta 60 segundos por organización y parámetros.
Parámetros de consulta comunes
| Nombre | Tipo | Obligatorio | Descripción |
|---|---|---|---|
from | string | No | Primer día, YYYY-MM-DD en Europe/Madrid, incluido. Por defecto, 29 días antes de to (los últimos 30 días). |
to | string | No | Último día, YYYY-MM-DD en Europe/Madrid, incluido. Por defecto, hoy. No puede ser futuro. |
interval | string | No | day (por defecto), week (semanas ISO, empiezan en lunes) o month (meses naturales). Siempre en Europe/Madrid. |
Visitas de toda la cuenta
GET/account/stats
Total y serie de visitas de todos los blogs de la organización.
Permiso necesario: stats:read. Admite from, to e interval.
Campos de la respuesta
| Campo | Tipo | Descripción |
|---|---|---|
from | string | Primer día del rango aplicado. |
to | string | Último día del rango aplicado. |
interval | string | day, week o month. |
totals | object | { views, uniquesApproxSum, articlesPublished }. articlesPublished cuenta los artículos cuya publicación cae en el rango. |
series | array | [{ date, views, uniquesApprox, partial? }]. partial: true solo aparece en el grupo que contiene hoy. |
blogs | array | Visitas por blog en el rango: [{ blogId, name, views }]. |
updatedAt | string | null | Hora del último volcado de estadísticas, ISO 8601 en UTC. |
Respuestas
| Código | Cuándo |
|---|---|
200 | Respuesta devuelta. |
400 | Fechas o parámetros no válidos. Con code: invalid_date (no es una fecha YYYY-MM-DD real), invalid_range (from posterior a to), range_in_future (to es futuro) o range_too_long (más de 400 días). Un parámetro que no existe también da 400. |
401 | Clave ausente, no válida o revocada. |
403 | La clave no tiene el permiso stats:read (code: "insufficient_scope"), tu plan es Free (plan_required) o la organización está suspendida (ORGANIZATION_SUSPENDED). |
429 | Límite del plan superado. Ver Límites de uso. |
curl "https://api.blogelia.com/v1/account/stats?interval=week" \
-H "Authorization: Bearer $BLOGENIA_API_KEY"const res = await fetch('https://api.blogelia.com/v1/account/stats?interval=week', {
headers: { Authorization: 'Bearer ' + process.env.BLOGENIA_API_KEY },
});
if (!res.ok) throw new Error('HTTP ' + res.status);
const body = await res.json();
console.log(body);import os
import requests
res = requests.get(
"https://api.blogelia.com/v1/account/stats",
params={"interval": "week"},
headers={"Authorization": "Bearer " + os.environ["BLOGENIA_API_KEY"]},
timeout=10,
)
res.raise_for_status()
print(res.json()){
"from": "2026-10-06",
"to": "2026-11-04",
"interval": "week",
"totals": { "views": 1840, "uniquesApproxSum": 1315, "articlesPublished": 9 },
"series": [
{ "date": "2026-10-05", "views": 310, "uniquesApprox": 232 },
{ "date": "2026-10-12", "views": 402, "uniquesApprox": 290 },
{ "date": "2026-10-19", "views": 455, "uniquesApprox": 318 },
{ "date": "2026-10-26", "views": 520, "uniquesApprox": 365 },
{ "date": "2026-11-02", "views": 153, "uniquesApprox": 110, "partial": true }
],
"blogs": [{ "blogId": "66f1c0a2b3c4d5e6f7a8b9c0", "name": "Reformas Ejemplo", "views": 1840 }],
"updatedAt": "2026-11-04T14:50:00.000Z"
}Visitas de un blog
GET/blogs/{blogId}/stats
Total y serie de visitas de un blog.
Permiso necesario: stats:read. Admite from, to e interval. La respuesta tiene los mismos campos que la de la cuenta, sin blogs.
Parámetros de ruta
| Nombre | Tipo | Obligatorio | Descripción |
|---|---|---|---|
blogId | string | Sí | Identificador del blog. |
La lista series real trae un punto por cada día del rango; aquí se acorta.
Respuestas
| Código | Cuándo |
|---|---|
200 | Respuesta devuelta. |
400 | Fechas o parámetros no válidos. Con code: invalid_date (no es una fecha YYYY-MM-DD real), invalid_range (from posterior a to), range_in_future (to es futuro) o range_too_long (más de 400 días). Un parámetro que no existe también da 400. |
404 | El blog no existe o es de otra organización. |
401 | Clave ausente, no válida o revocada. |
403 | La clave no tiene el permiso stats:read (code: "insufficient_scope"), tu plan es Free (plan_required) o la organización está suspendida (ORGANIZATION_SUSPENDED). |
429 | Límite del plan superado. Ver Límites de uso. |
curl "https://api.blogelia.com/v1/blogs/66f1c0a2b3c4d5e6f7a8b9c0/stats?from=2026-10-01&to=2026-10-31" \
-H "Authorization: Bearer $BLOGENIA_API_KEY"const res = await fetch('https://api.blogelia.com/v1/blogs/66f1c0a2b3c4d5e6f7a8b9c0/stats?from=2026-10-01&to=2026-10-31', {
headers: { Authorization: 'Bearer ' + process.env.BLOGENIA_API_KEY },
});
if (!res.ok) throw new Error('HTTP ' + res.status);
const body = await res.json();
console.log(body);import os
import requests
res = requests.get(
"https://api.blogelia.com/v1/blogs/66f1c0a2b3c4d5e6f7a8b9c0/stats",
params={"from": "2026-10-01", "to": "2026-10-31"},
headers={"Authorization": "Bearer " + os.environ["BLOGENIA_API_KEY"]},
timeout=10,
)
res.raise_for_status()
print(res.json()){
"from": "2026-10-01",
"to": "2026-10-31",
"interval": "day",
"totals": { "views": 1420, "uniquesApproxSum": 1010, "articlesPublished": 7 },
"series": [
{ "date": "2026-10-01", "views": 38, "uniquesApprox": 29 },
{ "date": "2026-10-02", "views": 51, "uniquesApprox": 40 }
],
"updatedAt": "2026-11-04T14:50:00.000Z"
}Ranking de artículos
GET/blogs/{blogId}/stats/articles
Los artículos de un blog ordenados por visitas en el rango.
Permiso necesario: stats:read.
Parámetros
| Nombre | Tipo | Obligatorio | Descripción |
|---|---|---|---|
blogId | string | Sí | Identificador del blog (en la ruta). |
from | string | No | Primer día, YYYY-MM-DD en Europe/Madrid, incluido. Por defecto, 29 días antes de to (los últimos 30 días). |
to | string | No | Último día, YYYY-MM-DD en Europe/Madrid, incluido. Por defecto, hoy. No puede ser futuro. |
sort | string | No | -views (por defecto, de más a menos visitas) o views (de menos a más). |
limit | integer | No | Artículos a devolver, de 1 a 100 (por defecto 20). |
Campos de la respuesta
| Campo | Tipo | Descripción |
|---|---|---|
from | string | Primer día del rango aplicado. |
to | string | Último día del rango aplicado. |
data | array | [{ articleId, title, slug, url, publishedAt, views }]. publishedAt es null si el artículo ya no está publicado. |
updatedAt | string | null | Hora del último volcado de estadísticas. |
Respuestas
| Código | Cuándo |
|---|---|
200 | Respuesta devuelta. |
400 | Fechas o parámetros no válidos. Con code: invalid_date (no es una fecha YYYY-MM-DD real), invalid_range (from posterior a to), range_in_future (to es futuro) o range_too_long (más de 400 días). Un parámetro que no existe también da 400. |
404 | El blog no existe o es de otra organización. |
401 | Clave ausente, no válida o revocada. |
403 | La clave no tiene el permiso stats:read (code: "insufficient_scope"), tu plan es Free (plan_required) o la organización está suspendida (ORGANIZATION_SUSPENDED). |
429 | Límite del plan superado. Ver Límites de uso. |
curl "https://api.blogelia.com/v1/blogs/66f1c0a2b3c4d5e6f7a8b9c0/stats/articles?limit=5" \
-H "Authorization: Bearer $BLOGENIA_API_KEY"const res = await fetch('https://api.blogelia.com/v1/blogs/66f1c0a2b3c4d5e6f7a8b9c0/stats/articles?limit=5', {
headers: { Authorization: 'Bearer ' + process.env.BLOGENIA_API_KEY },
});
if (!res.ok) throw new Error('HTTP ' + res.status);
const body = await res.json();
console.log(body);import os
import requests
res = requests.get(
"https://api.blogelia.com/v1/blogs/66f1c0a2b3c4d5e6f7a8b9c0/stats/articles",
params={"limit": 5},
headers={"Authorization": "Bearer " + os.environ["BLOGENIA_API_KEY"]},
timeout=10,
)
res.raise_for_status()
print(res.json()){
"from": "2026-10-06",
"to": "2026-11-04",
"data": [
{
"articleId": "66f1c0a2b3c4d5e6f7a8b9c1",
"title": "¿Cuánto cuesta reformar una cocina?",
"slug": "cuanto-cuesta-reformar-una-cocina",
"url": "https://reformas-ejemplo.blogelia.com/cuanto-cuesta-reformar-una-cocina",
"publishedAt": "2026-10-01T09:00:00.000Z",
"views": 612
}
],
"updatedAt": "2026-11-04T14:50:00.000Z"
}Visitas de un artículo
GET/articles/{id}/stats
Total y serie de visitas de un artículo.
Permiso necesario: stats:read. Admite from, to e interval. Los puntos de la serie no llevan uniquesApprox, y totals solo tiene views.
Parámetros de ruta
| Nombre | Tipo | Obligatorio | Descripción |
|---|---|---|---|
id | string | Sí | Identificador del artículo. |
Respuestas
| Código | Cuándo |
|---|---|
200 | Respuesta devuelta. |
400 | Fechas o parámetros no válidos. Con code: invalid_date (no es una fecha YYYY-MM-DD real), invalid_range (from posterior a to), range_in_future (to es futuro) o range_too_long (más de 400 días). Un parámetro que no existe también da 400. |
404 | El artículo no existe o es de otra organización. |
401 | Clave ausente, no válida o revocada. |
403 | La clave no tiene el permiso stats:read (code: "insufficient_scope"), tu plan es Free (plan_required) o la organización está suspendida (ORGANIZATION_SUSPENDED). |
429 | Límite del plan superado. Ver Límites de uso. |
curl "https://api.blogelia.com/v1/articles/66f1c0a2b3c4d5e6f7a8b9c1/stats?interval=month" \
-H "Authorization: Bearer $BLOGENIA_API_KEY"const res = await fetch('https://api.blogelia.com/v1/articles/66f1c0a2b3c4d5e6f7a8b9c1/stats?interval=month', {
headers: { Authorization: 'Bearer ' + process.env.BLOGENIA_API_KEY },
});
if (!res.ok) throw new Error('HTTP ' + res.status);
const body = await res.json();
console.log(body);import os
import requests
res = requests.get(
"https://api.blogelia.com/v1/articles/66f1c0a2b3c4d5e6f7a8b9c1/stats",
params={"interval": "month"},
headers={"Authorization": "Bearer " + os.environ["BLOGENIA_API_KEY"]},
timeout=10,
)
res.raise_for_status()
print(res.json()){
"from": "2026-10-06",
"to": "2026-11-04",
"interval": "month",
"totals": { "views": 612 },
"series": [
{ "date": "2026-10-01", "views": 580 },
{ "date": "2026-11-01", "views": 32, "partial": true }
],
"updatedAt": "2026-11-04T14:50:00.000Z"
}