CommunityRedacción y edicióngithub.com

bojan-basrak/rankscale-api-skill

Una habilidad de agente no oficial y agnóstica del proveedor para consultar la API REST de visibilidad de marca de Rankscale AI, compatible con Claude Code, Cursor, Codex y otras herramientas de agente.

¿Qué es rankscale-api-skill?

Rankscale API Skill es una habilidad de agente de IA diseñada para permitir a los usuarios, en particular profesionales de SEO, consultar la API REST de Rankscale AI para extraer datos de visibilidad de marca sin necesidad de utilizar el panel de control. Funciona con herramientas de agente populares como Claude Code, Cursor y Codex, lo que proporciona flexibilidad entre plataformas. La habilidad está optimizada para la eficiencia de tokens: descarga respuestas grandes directamente en archivos para ahorrar contexto y utiliza la extracción del lado del cliente mediante herramientas como `node -e` o `jq`. Maneja la autenticación a través de la variable de entorno `RANKSCALE_API_KEY` e incluye un control de límite de velocidad integrado. El documento SKILL.md describe recetas de flujo de trabajo detalladas para identificar marcas, extraer métricas a lo largo del tiempo, análisis de citas, análisis de sentimiento y generación de informes de términos de búsqueda. También documenta numerosas particularidades de la API, advertencias sobre campos en camelCase, riesgos de carga útil por tamaño y valores de respuesta poco intuitivos (por ejemplo, campos `latestRank`). Esta habilidad está diseñada para profesionales técnicos de SEO que necesitan automatizar la extracción de datos para informes, gráficos y análisis personalizados.

Compatible con✓Claude Code✓Codex CLI✓Cursor✓Antigravity✓Gemini CLI
npx skills add bojan-basrak/rankscale-api-skill

Installed? Explore more Redacción y edición skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

API REST de Rankscale

Rankscale es una herramienta de seguimiento de visibilidad de marca impulsada por IA. Solicita a varios modelos de IA (ChatGPT, Gemini, Claude, Perplexity, etc.) los términos de búsqueda rastreados por el usuario, analiza las respuestas e informa con qué frecuencia, dónde y con qué favorabilidad se mencionan las marcas rastreadas.

Esta habilidad llama a la API REST directamente para que el usuario (un profesional de SEO, no un desarrollador) pueda extraer datos en informes, gráficos y análisis personalizados sin tener que navegar por el panel de control.

Configuración

  • Clave API: Se lee de la variable de entorno RANKSCALE_API_KEY. El formato de la clave es rk_<hash>_<idEspacioTrabajo> — el sufijo es un identificador de espacio de trabajo, no un ID de marca, por lo que una clave alcanza cada marca en su espacio de trabajo (peculiaridades §15). Si no está configurada, pide al usuario que la configure una vez: PowerShell setx RANKSCALE_API_KEY "rk_..." (se requiere un nuevo shell para que surta efecto) o pásala por sesión con $env:RANKSCALE_API_KEY = "rk_...". Nunca imprimas la clave en las respuestas ni la escribas en archivos.
  • URL base: https://rankscale.ai (nota: sin prefijo /api — la ruta es /v1/... directamente en el dominio de marketing).
  • Encabezado de autenticación: Authorization: Bearer $RANKSCALE_API_KEY.
  • Límite de velocidad: 200 solicitudes por minuto por clave API. La respuesta lleva X-RateLimit-Limit, X-RateLimit-Remaining y X-RateLimit-Reset (segundos hasta que se reinicie la ventana) — léelos con curl -i si estás haciendo trabajo por lotes. Almacena en caché las respuestas de informes durante 5–10 minutos cuando sea posible.
  • Herramientas disponibles: curl para solicitudes. Para el análisis JSON, usa lo que ofrezca el entorno — node -e "...", jq, o python -m json.tool. Verifica qué hay en PATH antes de asumir; no dependas estrictamente de ninguno de ellos.
  • Sintaxis del shell: los ejemplos a continuación usan expansión de variables estilo bash ($RANKSCALE_API_KEY). En Windows PowerShell eso se convierte en $env:RANKSCALE_API_KEY. Elige el shell que llames — ambos funcionan, pero ten en cuenta la sintaxis.

Patrón de llamada

Cada endpoint devuelve {success: true, data: {...}} en caso de éxito, o {success: false, error: {code, message, details}} en caso de error. Siempre verifica .success antes de leer .data.

Verifica también warnings. Una respuesta exitosa puede llevar una tercera clave de nivel superior, warnings[], que enumera los campos de solicitud que la API no reconoció e ignoró — a menudo con un "quiso decir" ("Ignored unrecognized field 'startDate'. Did you mean 'isoStartDate'? …"). Está ausente cuando la solicitud fue limpia, por lo que if (json.warnings) es una protección confiable. Una advertencia significa que los números responden a una pregunta diferente a la que se hizo — la API recurre a valores predeterminados para el campo eliminado. Preséntalo al usuario en lugar de tragártelo; esta es la forma más económica de detectar la trampa de camelCase (peculiaridades §1).

Guarda las respuestas JSON sin procesar en un archivo junto al trabajo del usuario (normalmente Rankscale/<endpoint>_<contexto>.json) para que puedan reanalizarse sin volver a llamar a la API. Muestra al usuario un resumen limpio, no el JSON sin procesar, a menos que lo soliciten.

Eficiencia de tokens: la palanca más grande. Para cualquier cosa masiva (multitema, multi-motor, historial completo, o /search-terms-report con includeAnswerTexts), escribe la respuesta directamente en el disco con -o y extrae solo los valores que necesites con node -e. No leas cargas útiles completas de /report en el contexto — un informe filtrado ocupa ~40–50 KB y un barrido de 7 temas es ~300 KB. Extraer escalares/series del lado del cliente los mantiene fuera del contexto y, en extracciones masivas, reduce aproximadamente a la mitad el uso de tokens en comparación con leer las cargas útiles en línea. (Para una métrica única y estrecha, la sobrecarga no vale la pena — simplemente lee la respuesta pequeña.)

Los tamaños de las cargas útiles son extremadamente desiguales: planifica en torno a ellos. Medido en una sola marca:

EndpointVentanaTamaño
/report (filtrado)30d~40–50 KB
/report (filtrado)1 mes calendario~105–110 KB
/citations3m~3.9 MB
/citations uncapped: true1 mes calendario~4.4–5.7 MB
/sentiment30d~9 MB
/sentiment3m~17 MB

El tamaño no escala con la longitud de la ventana — uncapped: true importa mucho más. Una sola solicitud sin límite de un mes resultó ser más grande que una extracción de tres meses con límite, así que no extrapoles el tamaño de 1 mes a partir de la fila de 3m.

/sentiment y /citations nunca son seguros para leer en línea — siempre usa -o para guardar en un archivo y extraer. En llamadas tan pesadas, captura también el estado HTTP (curl -w '%{http_code}'), porque un 502 transitorio llega como un cuerpo HTML que parece una ruta rota pero solo necesita un reintento (peculiaridades §6).

# Bash (Git Bash / WSL / macOS / Linux)
curl -s -H "Authorization: Bearer $RANKSCALE_API_KEY" \
     "https://rankscale.ai/v1/metrics/brands" \
     -o brands.json

curl -s -X POST -H "Authorization: Bearer $RANKSCALE_API_KEY" \
     -H "Content-Type: application/json" \
     -d '{"brandId":"<id>"}' \
     "https://rankscale.ai/v1/metrics/report" \
     -o report.json
# Equivalente en PowerShell
curl.exe -s -H "Authorization: Bearer $env:RANKSCALE_API_KEY" `
     "https://rankscale.ai/v1/metrics/brands" `
     -o brands.json

curl.exe -s -X POST -H "Authorization: Bearer $env:RANKSCALE_API_KEY" `
     -H "Content-Type: application/json" `
     -d '{\"brandId\":\"<id>\"}' `
     "https://rankscale.ai/v1/metrics/report" `
     -o report.json

Nota en PowerShell: usa curl.exe (el alias curl apunta a Invoke-WebRequest, que se comporta de manera diferente), escapa las comillas internas en los cuerpos JSON -d con \", y usa el acento grave ` para la continuación de línea. Invoke-RestMethod también funciona y analiza JSON automáticamente, pero la forma curl mantiene las respuestas consistentes en todos los shells.

El inventario completo de endpoints y las formas de las solicitudes se encuentran en references/endpoints.md. Léelo antes de cualquier llamada de la que no estés seguro. Las sorpresas y advertencias están en references/quirks.md — léelo antes de informar métricas al usuario, porque varias de ellas afectan cómo deben interpretarse los números.

Fuera del alcance: la API de enlaces compartidos. Rankscale publica una segunda API REST para enlaces compartidos públicos de paneles. Utiliza una clave diferente (Configuración → Compartir, no Configuración → Integraciones), por lo que RANKSCALE_API_KEY no se autenticará contra ella. Si el usuario solicita crear o revocar un enlace compartido, dile que es una API separada que esta habilidad no cubre — no adivines sus rutas.

Recetas de flujo de trabajo

1. Identificar la marca

La mayoría de los endpoints de informes necesitan un brandId. Cuando el usuario nombre una marca ("muéstrame las métricas de Acme"), resuelve el ID primero:

  1. Si Rankscale/brands.json existe en el directorio de trabajo del usuario, léelo.
  2. De lo contrario, llama a GET /v1/metrics/brands y guarda el resultado.
  3. Compara el nombre de la marca del usuario con brands[].name (sin distinción de mayúsculas y minúsculas) y con brands[].brandInfo.names (alias). Si hay múltiples coincidencias, pide al usuario que las desambigüe.

2. Extraer métricas para una marca durante un período

El usuario casi siempre solicita un período de tiempo. Usa timeFrame (camelCase, F mayúscula — la API ignora silenciosamente cualquier otra ortografía) con uno de estos valores preestablecidos documentados: 24h, 7d, 30d, 3m, 1y. Combínalo con aggregation (hourly, daily, weekly o monthly) para el tamaño del bucket. Para ventanas personalizadas, usa isoStartDate + isoEndDate (cadenas de fecha ISO emparejadas); estas anulan timeFrame.

{
  "brandId": "<id>",
  "timeFrame": "30d",
  "aggregation": "daily",
  "includeNotFoundExecutions": true
}

Filtros de informes opcionales (todos aceptan una sola cadena, un array para OR dentro del campo, o "all" para ningún filtro; los filtros se combinan con AND entre campos):

  • selectedTopic — ID de tema, nombre de tema, _orphaned o array
  • selectedTags — etiqueta, __UNTAGGED__ o array
  • selectedEngine — ID de motor (preferido — consulta references/endpoints.md para el catálogo) o nombre descriptivo
  • selectedQuery — cadena de consulta de término de búsqueda exacta o array
  • searchTermId — ID de término de búsqueda individual
  • periodOffset — entero, desplaza la ventana preestablecida hacia atrás N períodos (0 = actual, 1 = anterior, …)
  • userTimezone — zona horaria IANA como Europe/Berlin para los límites diarios locales del usuario
  • includeNotFoundExecutions — booleano, controla si las ejecuciones de "marca no encontrada en la respuesta" cuentan para las métricas (consulta quirks.md)

Lee la respuesta de data.ownBrandMetrics.historicalData.<aggregation> (por ejemplo, .daily cuando solicitaste aggregation: "daily"). Cada array de bucket — visibilityScore, sentiment, mentions, sources, citations, citationCounts, avgPosition, detectionRate, top3, brandNotFound — se ejecuta en paralelo con timestamps.

Tres series de tiempo paralelas se sientan junto a él:

  • data.ownBrandMetrics.topicMetricsData.<aggregation> — por tema
  • data.ownBrandMetrics.engineMetricsData.<aggregation> — por motor; no documentado upstream, y generalmente el corte de mayor valor cuando una ventana agregada parece plana, porque los movimientos a nivel de motor se cancelan entre sí en el total (peculiaridades §25)
  • data.competitorTimeSeriesData.<aggregation> — por competidor, propia marca excluida (peculiaridades §16)

brandNotFound[] es una no señal — se lee true para esencialmente cualquier marca con detección inferior al 100%. Usa detectionRate en su lugar y nunca informes "marca no encontrada" basándote en la bandera (peculiaridades §2).

Presenta una tabla de métricas con estas columnas: Fecha, Visibilidad, Sentimiento, Menciones, Citas, Pos. Promedio, % de Detección, % Top-3. Encima, muestra el resumen instantáneo (valores instantáneos actuales de ownBrandMetrics + el delta de trends).

Rango de marca (por Visibilidad) — vs. competidores. Calcula esto a partir de data.competitorMetrics[] (que incluye la propia marca, marcada isOwnBrand: true): rango = 1 + (recuento de entradas con visibilityScore estrictamente mayor) — los empates no bajan la marca. Esto reproduce el rango del panel. La respuesta también lleva latestRank/avgRank por entrada — estos no son rangos. Verificado el 2026-08-07: devuelven valores no enteros (latestRank: 2.7, avgRank: 2.9) para una marca cuyo rango calculado era 1, por lo que rastrean algo similar a una posición, no un ordinal. Ignóralos. El equivalente own_brand_rank de MCP es igualmente siempre 1 (un pin de visualización). El cálculo ordenado por visibilidad anterior es el método que coincidió con el panel en las pruebas. Los filtros compartidos (selectedEngine, selectedTopic, selectedTags, selectedQuery) funcionan por corte, por lo que puedes clasificar dentro de un solo motor, tema, etiqueta o consulta volviendo a ejecutar filtrado. Ten en cuenta que las entradas de competitorMetrics pueden tener un validMetricsCount diferente al de la propia marca (las líneas base de los competidores usan una ventana más amplia) — el orden aún coincide con la UI. Receta completa — incluido el rango diario a lo largo del tiempo y sus advertencias — en la receta §6 a continuación.

3. Análisis de citas

/v1/metrics/citations devuelve qué fuentes (sitios, artículos) citan los modelos de IA al responder a los términos de búsqueda del usuario. Útil para comprender qué dominios de terceros influyen en las respuestas de IA sobre una marca.

Campos clave: data.totalCitations, data.uniqueCitations (URL distintas), data.uniqueDomains y data.citationsByDomain[] (cada dominio). En cada entrada de dominio, occurrences es el recuento; el campo citations es el array de URL, no un número — por lo tanto, la participación en citas = occurrences / totalCitations, y las URL principales provienen de aplanar el array de URL de cada dominio y ordenar por occurrences.

Cada objeto URL es {url, normalizedUrl, occurrences, engineAppearances: {<idMotor>: count}, firstSeenAt, lastSeenAt, category, searchTerms[]}. engineAppearances es el único desglose de citas por motor en la API — súmalo en todas las URL de un dominio para responder "qué motores citan nuestro sitio". firstSeenAt/lastSeenAt son el único eco de la ventana que realmente obtuviste. Normaliza normalizedUrl aún más antes del análisis a nivel de página (deja variantes de www./barra diagonal final/consulta distintas), y ten en cuenta que category: "owned" significa "el propio sitio de una empresa", no propiedad de la marca rastreada — los competidores también lo llevan. Consulta quirks.md §13b. data.domainSummary tiene vistas precortadas (topDomainsOverall, topDomainsByEngine, topDomainsByQuery, topDomainsByOwnBrandCitations, topDomainsByCompetitor) — pero estos están limitados (≈20/10 entradas) y topDomainsByCompetitor enumera dominios donde se mencionó a un competidor (incluye sitios neutrales de terceros como Reddit/Booking), así que no lo uses para identificar sitios propiedad del competidor. Consulta quirks.md §13b.

Verifica los límites antes de considerar una lista completa. La respuesta tiene un límite de 5,000 URL únicas y 50 marcas de forma predeterminada. data.paginationInfo informa la verdad — citationsCapped, brandsCapped, responseTrimmed, capBypassed, maxCitations, maxBrands, totalCount vs returnedCount. Pasa uncapped: true (cuerpo o parámetro de consulta) para levantar el límite de URL; no levanta el límite de 50 marcas ni el protector de tamaño de respuesta. deduplicated: true deduplica las rutas de respuesta y agrega data.searchTermsById. Si alguna bandera de límite es true, informa al usuario y reduce la ventana o filtra en lugar de presentar una lista truncada como la imagen completa. Consulta quirks.md §13c.

4. Sentimiento

/v1/metrics/sentiment devuelve agregados de sentimiento a nivel de ventana más nubes de palabras clave para la marca rastreada y cada competidor — no una serie temporal (usa el historicalData.<agg>.sentiment[] de /report para el sentimiento a lo largo del tiempo). Mismos filtros compartidos, más deduplicated: true.

Dos arrays con diferentes alcances: data.brandSentiments[] es solo la marca rastreada; data.companySentiments[] es cada marca detectada, incluida la propia (isOwnBrand: true) — usa este para comparaciones de competidores. brandSentimentsBySearchTerm[] / companySentimentsBySearchTerm[] dan los mismos cortes por término de búsqueda.

Por entrada: avgSentiment (escala 0–100, = totalSentimentScore / sentimentCount), sentimentCount, executionCount, y positiveCount / neutralCount / negativeCount. El sentimiento se divide por fuente — bloques webGrounding* (motores con base web) vs trainingData*, controlado por los booleanos hasWebGrounding / hasTrainingData, con webGroundingSentimentByEngine[<idMotor>] = {sum, count, avg} para puntuaciones por motor.

Dos trampas — lee quirks.md §19 antes de informar algo de esto. (1) `p … [truncado para la traducción]

Skills relacionados