Conceptos básicos

Las reglas que comparten todos los endpoints: filtros, definiciones de métricas, salida en JSON y CSV, caché, códigos de error y versionado.

Filtros y parámetros comunes

  • project_id obligatorio para todos los endpoints con ámbito de proyecto.
  • metrics o metric: CSV con mentions, citations, responses, mention_rate (or visibility), citation_rate, ai_visibility_score, avg_position, avg_mention_position, sentiment_very_positive, sentiment_positive, sentiment_neutral, sentiment_negative, sentiment_very_negative, net_sentiment
  • granularity: day|week|month (las semanas empiezan en lunes)
  • Ventana de tiempo: o bien range (días) o from y to (ISO8601). Si envías to, from es obligatorio. Valores por defecto con from/to: si falta from = hace 30 días (inicio del día); si falta to = ahora (fin del día).
  • Filtros: model, collection_id (ID de tag), prompt (ID de prompt), country_code, language_code, competitors (IDs en CSV)
  • include_project (por defecto true): establece false para excluir tu proyecto (devuelve solo competidores).

Definición de métricas

Estas semánticas están alineadas 1:1 con la interfaz de Resumen.

  • mentions: sumas diarias de mentions_count. Para week/month calculamos el TOTAL DEL PERÍODO (de lunes a domingo en las semanas) y repetimos ese mismo total para todos los días del período. Si el total de un período es 0, «arrastramos» el último total de período distinto de cero (arrastre persistente).
  • citations: recuento a nivel de respuesta que incluye las citaciones visibles y las referencias a fuentes en segundo plano. Cada actor cuenta como máximo una vez por respuesta. Usa el mismo comportamiento de total del período y arrastre persistente que las menciones.
  • responses: número total de ejecuciones de prompt (llamadas de API a los LLM). Usa el recuento de ejecuciones del proyecto, independientemente del actor. • day: suma diaria. • week/month: total del período (sin arrastre persistente; los días con 0 ejecuciones muestran 0).
  • Tasa de mención mention_rate (también aceptado como visibility): porcentaje por actor, usando las ejecuciones del proyecto como denominador con los mismos filtros (mentions_count / prompt_executions_count × 100). • day: calcula la proporción diaria. • week/month: calcula la proporción de sumas del período (Σ menciones / Σ ejecuciones) y repite ese valor para todos los días del período. Si el denominador del período es 0, arrastra el último valor no nulo.
  • citation_rate: porcentaje de respuestas que incluyen una citación visible o en segundo plano para el actor (citations_count / prompt_executions_count × 100). • day: proporción diaria. • week/month: proporción de sumas del período con arrastre persistente, igual que la visibilidad.
  • AI Visibility Score ai_visibility_score: métrica de visibilidad ponderada por posición que tiene en cuenta la prominencia de la mención. Usa ponderación recíproca por posición (posición 1 = 100%, posición 2 = 50%, posición 3 = 33%, etc.). Las puntuaciones más altas indican tanto más menciones como mejor posicionamiento. • day: calcula la puntuación ponderada diaria / ejecuciones. • week/month: proporción de sumas del período con arrastre persistente, igual que la visibilidad.
  • avg_position: posición media de las citaciones visibles. Las citaciones en segundo plano no tienen posición visible y quedan excluidas. • day: media diaria excluyendo los nulos. • week/month: media dentro del período (ignorando los nulos) y después se propaga (arrastra) el último valor conocido a los días sin datos, igual que el suavizado del gráfico de Resumen.
  • avg_mention_position: posición media de la marca cuando aparece mencionada en las respuestas de IA (posición 1 = primera mención, posición 2 = segunda, etc.). Cuanto más baja, mejor. • day: media diaria excluyendo los nulos. • week/month: media dentro del período con arrastre persistente.
  • Métricas de sentimiento sentiment_very_positive,sentiment_positive,sentiment_neutral,sentiment_negative,sentiment_very_negative: para cada actor y día, porcentaje de sentimientos de esa categoría sobre todos los sentimientos de ese actor. • day: proporción diaria (bucket_count / total_sentiments * 100). Los días sin sentimientos devuelven null. • week/month: calculamos una proporción de sumas del período (Σ bucket / Σ total * 100) y repetimos ese porcentaje para todos los días del período. Si el denominador del período es 0, arrastramos el último valor no nulo (arrastre persistente), igual que el suavizado del Resumen.
  • Puntuación de sentimiento neto net_sentiment: para cada actor y día, calculamos una puntuación en [-100, 100]: ( (very_positive + positive) − (negative + very_negative) ) / total_sentiments × 100. • day: usamos los porcentajes diarios de cada categoría (las métricas sentiment_*) y calculamos net = (pos+very_pos) − (neg+very_neg). • week/month: la puntuación hereda las mismas semánticas de agregación y suavizado que las categorías de sentimiento, porque se calcula a partir de esas series.

En /metrics/summary, total es una suma para las métricas de recuento y una media para avg_position, avg_mention_position y net_sentiment.

Formatos de salida para herramientas de BI

Los endpoints de lectura devuelven JSON anidado por defecto, lo que resulta cómodo para el código pero ilegible para las herramientas de business intelligence. Pasa el parámetro opcional output para obtener los mismos datos como una tabla rectangular que Tableau, Excel, Google Sheets o un cargador de data warehouse puedan consumir directamente.

  • output omitido (por defecto): el JSON anidado documentado para cada endpoint. Sin cambios, por lo que las integraciones existentes no se ven afectadas.
  • output=flat: los mismos metadatos más columns (nombres de columna ordenados), rows (un objeto plano por fila) y row_count.
  • output=csv: las mismas filas que text/csv, con columns como fila de encabezado.

Disponible en /metrics/timeseries, /metrics/summary, /metrics/sov, /metrics/prompt_summary, /metrics/top_sources, la serie /search_console/* y los endpoints /dimensions/* que devuelven listas. Los endpoints cuyo payload no es una única tabla (/metrics/agent_traffic, /metrics/ai_traffic, /search_console/summary, /dimensions/models, /dimensions/locales) rechazan output en lugar de ignorarlo.

/metrics/sov también acepta view=over_time (por defecto), view=current o view=breakdown: su payload contiene varias formas distintas y una tabla solo puede contener una a la vez.

Columnas por endpoint

Endpoint Columns
/metrics/timeseries date, actor_type, actor_id, actor_name, actor_domain, metric, value
/metrics/summary actor_type, actor_id, actor_name, actor_domain, metric, aggregation, total, min, max, last
/metrics/sov date, actor_type, actor_id, actor_name, actor_domain, share
/metrics/sov?view=current actor_type, actor_id, actor_name, actor_domain, share
/metrics/sov?view=breakdown rank, actor_type, actor_id, actor_name, actor_domain, share, others
/metrics/prompt_summary, /metrics/top_sources, /search_console/*, /dimensions/* The keys of the endpoint's own data rows

Ejemplo

GET /api/v1/metrics/timeseries?project_id=1&range=30&metrics=mentions&output=csv

date,actor_type,actor_id,actor_name,actor_domain,metric,value
2025-01-01,project,1,My Brand,mybrand.com,mentions,10
2025-01-01,competitor,2,Competitor A,competitor.com,mentions,5

Notas:

  • Los errores siempre se devuelven como JSON, nunca como CSV, por lo que un fallo nunca se confunde con datos.
  • Los porcentajes se mantienen en la escala bruta de 0 a 100, exactamente igual que en la respuesta JSON.
  • Las celdas de texto que empiezan por un signo igual, más, menos o arroba se escapan para que las hojas de cálculo no las ejecuten como fórmulas.
  • Los endpoints paginados también devuelven sus metadatos de paginación en las cabeceras de respuesta X-Total-Count, X-Page y X-Per-Page, que un cuerpo CSV no puede transportar.
  • La salida plana tiene un límite de 200.000 filas. A partir de ahí, reduce el rango de fechas, solicita menos métricas o usa granularity=week.
  • Los endpoints sin proyección plana rechazan output con ERR_INVALID_PARAM en lugar de ignorarlo.

Caché y GET condicional

Los endpoints de métricas (timeseries, summary, sov, top_sources) admiten GET condicional. Calculamos un ETag a partir de la versión del proyecto y de un hash de tus parámetros de consulta, y usamos el updated_at del proyecto como Last-Modified.

Envía If-None-Match o If-Modified-Since para recibir 304 Not Modified cuando nada haya cambiado.

Errores

Los errores son uniformes y analizables por máquina:

Código HTTP Significado
ERR_MISSING_AUTH 401 Falta el encabezado Authorization o está mal formado
ERR_INVALID_API_KEY 401 Token no reconocido
ERR_REVOKED_API_KEY 403 Clave revocada
ERR_PROJECT_NOT_FOUND 404 project_id no accesible para este usuario
ERR_NOT_FOUND 404 Recurso no encontrado
ERR_INVALID_PARAM 422 Error de validación (consulta el mensaje)
ERR_LIMIT_REACHED 422 Límite de prompts de la cuenta alcanzado
ERR_QUOTA_EXCEEDED 422 Cuota mensual de tareas de GEO Writer superada

Estructura del cuerpo de error:

Casos típicos de 422:

  • invalid metrics: solo se permiten mentions, citations, responses, mention_rate (or visibility), citation_rate, ai_visibility_score, avg_position, avg_mention_position, sentiment_very_positive, sentiment_positive, sentiment_neutral, sentiment_negative, sentiment_very_negative, net_sentiment.
  • invalid granularity: debe ser day|week|month.
  • from/to must be ISO8601, o from is required with to.
  • range is required cuando no se envía ni from ni to.
  • unknown competitor ids: ...: IDs no encontrados en el proyecto.

Versiones y límites de solicitudes

Versión actual: v1. Los futuros cambios incompatibles incrementarán la versión de la ruta (p. ej. /api/v2).

Límite de solicitudes: 300 solicitudes por minuto y clave de API. Contacta con nosotros para cuotas superiores.

Los endpoints de métricas admiten GET condicional (ETag/Last-Modified); consulta Caché y GET condicional.