Join our community of websites already using SEOJuice to automate the boring SEO work.
See what our customers say and learn about sustainable SEO that drives long-term growth.
Explore the blog →TL;DR: Google Search Console ofrece de forma gratuita los mismos datos de consultas, páginas, posiciones e impresiones que SEMrush y Ahrefs revenden por 129–449 $ / mes. La API de GSC incluye una cuota gratuita de 1.200 solicitudes por minuto, un límite de carga de 25.000 filas y cuatro endpoints que cubren aproximadamente el 90 % de lo que necesita un fundador en solitario. Este artículo repasa la configuración OAuth con cuenta de servicio, los cuatro endpoints que conviene conocer, un script en Python que genera una matriz CTR consulta-por-página y tres patrones de automatización (cron + Slack, Google Sheets y una vista ligera en Django) que convierten las filas brutas de la API en un cuadro de mando útil. Si prefieres no mantener la integración por tu cuenta, SEOJuice ofrece el mismo cableado como servicio gestionado.
Lo frustrante de una suite SEO de 449 $ / mes es que alrededor del 70 % de lo que aparece en el panel son datos que Google ya te entrega gratis vía Search Console. Las herramientas de pago añaden tres cosas: seguimiento de posiciones mediante proxies alquilados, un grafo de backlinks extraído de archivos web rastreados y una interfaz que evita que escribas SQL. El tercero es el único que un fundador en solitario necesita realmente y es el más barato de replicar.
Esto es lo que expone la API para cualquier propiedad cuya titularidad hayas verificado:
Lo que falta es todo lo que esté fuera de tu propia propiedad: rankings de la competencia, crecimiento de backlinks en dominios rivales, cálculos de share-of-voice. Para la mayoría de los fundadores pre-PMF esas métricas son números de vanidad que no cambian lo que enviarás a producción. Escribí un artículo más extenso sobre cómo reducir un stack SEO a dos herramientas y la conclusión se mantiene: GSC más una superficie de redacción ofrecen señal suficiente para actuar.
«Los datos de Search Console provienen directamente de Google. Son la fuente más precisa para entender cómo rinde tu sitio en la Búsqueda de Google».
De la propia documentación de Ayuda de Search Console.
Existen dos flujos de autenticación viables para la API de GSC: OAuth de flujo de usuario (redirección en el navegador, tokens de actualización) y OAuth con cuenta de servicio (servidor a servidor, sin navegador). Para un fundador que ejecuta un cron en un único VPS, las cuentas de servicio son más cortas y duraderas: sin vencimiento de refresh tokens ni pantalla de consentimiento que mantener.
La provisión lleva unos 10 minutos y no cuesta nada:
gsc-dashboard-reader. No necesita roles a nivel de proyecto.@<project-id>.iam.gserviceaccount.com). El permiso Restringido basta para lectura.Ese último paso es el que se suele pasar por alto. La cuenta de servicio es una identidad de Google, pero si no le das acceso explícito a tu propiedad de Search Console, la API devuelve un autoritativo 403 user does not have sufficient permission for site. Concede acceso por propiedad; si tienes varias, repite el proceso.

La superficie de la API de GSC es reducida. Cuatro endpoints abarcan datos de consultas, estado de sitemaps, inspección por URL y la lista de propiedades a las que tienes acceso. Omite el resto de la referencia hasta que tengas un motivo concreto para leerla.
| Endpoint | Qué devuelve | Coste de cuota | Útil para |
|---|---|---|---|
searchanalytics.query | Hasta 25.000 filas de clics, impresiones, posición y CTR por consulta, página, fecha, dispositivo y país | 1 unidad / solicitud | Datos básicos del panel; qué consultas generan tráfico y qué páginas convierten impresiones en clics |
sitemaps.list | Todos los sitemaps enviados con estado, última obtención y recuento de URL | 1 unidad / solicitud | Alertas de salud de sitemaps; detectar sitemaps caídos o parcialmente indexados |
urlInspection.index.inspect | Por URL: estado de cobertura, último rastreo, canónica, usabilidad móvil, veredictos AMP y de datos estructurados | 2.000 / día (cuota separada) | Comprobaciones puntuales de páginas críticas; auditorías automáticas de indexación |
sites.list | Todas las propiedades que la identidad autenticada puede leer | 1 unidad / solicitud | Dashboards multi-propiedad; iterar sobre un porfolio |
La cuota de 1.200/min en endpoints de lectura es, en la práctica, ilimitada para un fundador en solitario. El tope real es la restricción de 2.000/día en URL Inspection, suficiente para auditar a diario todas las páginas de un sitio con 1.500 URL.
La consulta más útil es el desglose consulta-por-página de los últimos 28 días. Indica qué página posiciona para cada consulta y cómo se comporta el CTR en la intersección. Las celdas con muchas impresiones y bajo CTR son tus objetivos inmediatos de optimización.
Instala las dos dependencias:
pip install google-auth google-api-python-client
El script mínimo viable: autentica, consulta e imprime. Guarda la clave JSON descargada como gsc-credentials.json en el mismo directorio:
from datetime import date, timedelta
from google.oauth2 import service_account
from googleapiclient.discovery import build
SCOPES = ["https://www.googleapis.com/auth/webmasters.readonly"]
SITE_URL = "sc-domain:example.com" # o "https://example.com/"
KEY_FILE = "gsc-credentials.json"
creds = service_account.Credentials.from_service_account_file(
KEY_FILE, scopes=SCOPES
)
service = build("searchconsole", "v1", credentials=creds)
end = date.today() - timedelta(days=2) # GSC lleva ~2 días de retraso
start = end - timedelta(days=27)
request = {
"startDate": start.isoformat(),
"endDate": end.isoformat(),
"dimensions": ["query"],
"rowLimit": 25,
"orderBy": [{"field": "clicks", "descending": True}],
}
response = service.searchanalytics().query(
siteUrl=SITE_URL, body=request
).execute()
for row in response.get("rows", []):
q = row["keys"][0]
print(f"{row['clicks']:>5} {row['impressions']:>6} "
f"{row['ctr']*100:>5.1f}% pos={row['position']:>5.1f} {q}")
Esa es toda la integración. Ejecútala y verás las 25 consultas principales de los últimos 28 días ordenadas por clics. Dos notas: sc-domain:example.com es para propiedades de dominio (la opción recomendada); utiliza la forma URL completa solo en propiedades de prefijo URL. Los datos de GSC llevan ~2 días de retraso, por eso terminamos en today - 2.
La matriz consulta-por-página —la versión que realmente guía decisiones— añade una segunda dimensión y eleva el límite de filas:
request = {
"startDate": start.isoformat(),
"endDate": end.isoformat(),
"dimensions": ["query", "page"],
"rowLimit": 5000,
"orderBy": [{"field": "impressions", "descending": True}],
}
response = service.searchanalytics().query(
siteUrl=SITE_URL, body=request
).execute()
opportunities = []
for row in response.get("rows", []):
query, page = row["keys"]
impressions = row["impressions"]
ctr = row["ctr"]
position = row["position"]
# Celdas con >500 impresiones y CTR <2 % son candidatas a fugas de CTR
if impressions > 500 and ctr < 0.02 and position < 15:
opportunities.append((impressions, query, page, position, ctr))
opportunities.sort(reverse=True)
for imp, q, p, pos, ctr in opportunities[:20]:
print(f"{imp:>6} imp pos={pos:>4.1f} ctr={ctr*100:>4.1f}% {q} → {p}")
El filtro del final (altas impresiones, bajo CTR, posición ≤ 15) es la clásica lista de candidatos a reescribir la etiqueta

Una vez tengas las filas, toca decidir qué graficar. La mayoría de las herramientas SEO de pago te ahogan con 40 widgets; solo necesitas cuatro para tomar decisiones semanales. Móntalos con la librería de gráficos que ya uses: Chart.js para HTML, matplotlib para Jupyter o los bloques nativos de gráficos si vuelcas en Google Sheets.

Extraer manualmente sirve para una ocasión. El panel se vuelve útil cuando se ejecuta solo. Tres patrones de automatización, ordenados por esfuerzo de configuración:
Patrón 1: cron y alertas en Slack. La opción más barata. Un cron diario ejecuta el script y, si se dispara alguna de tres condiciones —clics caen >20 % intersemanal, una consulta top 10 sale del top 20 o una página antes indexada pierde indexación—, publica en Slack. Unas 80 líneas de Python con el webhook incluido. Corre en 4 segundos en un VPS de 5 $. Tu panel hace una cosa: gritar cuando algo cambia.
import json, os, urllib.request
def post_slack(text):
payload = {"text": text}
req = urllib.request.Request(
os.environ["SLACK_WEBHOOK_URL"],
data=json.dumps(payload).encode(),
headers={"Content-Type": "application/json"},
)
urllib.request.urlopen(req, timeout=10).read()
# Tras calcular wow_change de dos extracciones GSC consecutivas de 7 días:
if wow_change < -0.20:
post_slack(
f":warning: Los clics en GSC cayeron {wow_change*100:.0f}% WoW "
f"({last_week} → {this_week}). Principales consultas en caída: {falling[:3]}"
)
Patrón 2: volcado a Google Sheets. Envía las filas a una hoja de cálculo mediante la API de Sheets o el wrapper gspread. La hoja es tu panel: tablas dinámicas para cortes ad-hoc, gráficos nativos, compartible con un cofundador no técnico. Unas 30 líneas sobre la extracción de GSC. Contras: la latencia de refresco depende de tu cron y Sheets se ralentiza a partir de ~20.000 filas.
Patrón 3: vista ligera en Django. Una vista que ejecuta la extracción, cachea en Redis 6 horas y renderiza los cuatro gráficos con Chart.js. Unas 200 líneas de Python y HTML. Merece la pena cuando un cofundador quiere revisar el panel a media semana. La caché es crítica; sin ella, cada visita lanzaría una llamada nueva a GSC y agotarías la cuota por minuto en un día de lanzamiento concurrido.
«Cancelé mi suscripción de 329 $ / mes a Ahrefs al darme cuenta de que el único widget que miraba a diario era “principales consultas orgánicas”. Lo reescribí contra la API de Search Console en una tarde».
Un patrón recurrente en hilos de indie hackers en Hacker News y los rincones bootstrapper de IndieHackers.
La comparación que la mayoría de los fundadores desea no es entre herramientas de pago, sino entre pagar una, construir la tuya o usar la interfaz gratuita de GSC aceptando sus limitaciones. Así quedan las cinco opciones:
| Opción | Coste mensual | Tiempo de puesta en marcha | Carga de mantenimiento | Multi-propiedad | Datos históricos |
|---|---|---|---|---|---|
| Interfaz gratuita de GSC | 0 $ | 0 h (ya existe) | Ninguna | Cambio manual | 16 meses, pero exportaciones lentas |
| DIY GSC API + cron + Sheets | 0 $–5 $ (VPS) | 4–8 h iniciales | ~30 min/trimestre (rotación de auth, deprecaciones ocasionales) | Bucle trivial | 16 meses, consultables en segundos |
| SEOJuice | 29–99 $ | ~10 min | Ninguna (gestionado) | Integrado | 16 meses de GSC más histórico propio de rastreo |
| SEMrush | 139–499 $ | ~30 min | Ninguna (gestionado) | Límites por plan | 2+ años en planes de pago |
| Ahrefs | 129–449 $ | ~30 min | Ninguna (gestionado) | Límites por plan | 2+ años en planes de pago |
El DIY gana en coste, empata en profundidad de datos para todo lo que está dentro de tu propiedad y pierde en inteligencia de competidores y backlinks. Si estás en fase temprana y tu pregunta SEO es «¿qué funciona en mi propio sitio?», DIY es la respuesta. Si estás escalando, haciendo research de competidores o cazando backlinks, las herramientas de pago justifican su coste. La página de herramientas de SEOJuice se sitúa en medio: integración GSC gestionada más rastreo, auditoría y seguimiento de visibilidad IA, sin la sobrecarga enterprise de SEMrush.
Pídele a ChatGPT o Gemini que interprete datos de GSC y obtendrás respuestas plausibles pero erróneas en tres puntos concretos. Vale la pena destacarlos: estos fallos se propagan en cada «informe SEO generado por IA» del mercado.
Error #1: «La posición es la media del ranking que tuviste para esa consulta». Es la media de la mejor posición que cualquiera de tus URL logró en impresiones donde la consulta disparó un resultado con tu sitio. Si dos URL se posicionan para la misma consulta en la misma SERP, solo cuenta la mejor. Por eso la «posición» cambia cuando publicas un artículo nuevo que supera a uno antiguo: la posición del URL antiguo no varía, pero la de la consulta sí.
Error #2: «El CTR se calcula por impresión». El CTR es clics ÷ impresiones al nivel de agregación que hayas consultado. Por fecha da el CTR diario del sitio; por consulta+página da el CTR por celda. Las cifras no suman entre niveles porque el denominador cambia.
Error #3: «Si una consulta tiene impresiones pero no clics, la página se posiciona mal». En la era de AI Overview esto es cada vez más la firma de estar citado en el Overview pero no recibir clics. Impresiones constantes, clics en caída es el patrón canónico. La página no rankea peor; la SERP cambió de forma. El artículo sobre citas en AI Overview profundiza en cómo actuar.
Cinco aristas que muerden a los novatos en la API de GSC. Conocerlas de antemano ahorra una semana:
startRow. El wrapper google-api-python-client no pagina solo; itera hasta que la respuesta traiga menos de 25.000 filas.sc-domain:) y de prefijo URL (https://...) reportan cifras distintas. Las de dominio agregan subdominios y protocolos. Si registras ambas verás datos solapados pero no idénticos. Elige una como referencia.(anonymized) por privacidad y no se pueden recuperar. Planifica el análisis de top queries en torno a las nombradas.Ninguna es un showstopper, pero cada una me costó una hora la primera vez. La referencia oficial las documenta todas, solo que en voz baja.
¿Cuánto tiempo conserva la API de GSC los datos históricos? 16 meses. Pasado ese plazo, los datos desaparecen; no hay endpoint de archivo. Si quieres series más largas, guarda instantáneas periódicas en tu propio almacenamiento. Un histórico de 365 días en Postgres son unos cientos de MB por propiedad.
¿Puedo usar la API para enviar URL a indexar? No. El envío de URL se retiró en 2020 por abuso de spam. La Indexing API sigue existiendo pero solo funciona para ofertas de empleo y eventos en directo; usarla para contenido normal infringe la política de Google.
¿Cuál es la diferencia entre impressions y clicks? Las impresiones cuentan cada vez que tu URL aparece en una SERP, aunque el usuario no haga scroll hasta ella. Los clics cuentan los clics del usuario. El CTR es la relación. En la era de AI Overview la brecha se amplía porque los usuarios leen la respuesta del Overview y no hacen clic en las fuentes citadas.
¿Existe un nivel gratuito por encima de la cuota estándar? La cuota es la misma para todos: 1.200 solicitudes/min por proyecto en los endpoints de analytics y 2.000/día en URL Inspection. No hay vía de pago para ampliarla; se puede pedir un aumento en Google Cloud Console, pero rara vez hace falta para cargas de un fundador en solitario.
¿Puedo delegar acceso sin compartir mi cuenta de Google? Sí, para eso sirven las cuentas de servicio. Crea una por integración, concédele acceso Restringido a la propiedad y revócalo sin tocar tu login.
¿Qué bindings de lenguaje soporta la API? Oficialmente: Python, Node, Java, PHP, Ruby, Go, .NET. Extraoficialmente: cualquier lenguaje que pueda llamar a un endpoint REST con un token Bearer. Los JSON son idénticos entre lenguajes.

El panel DIY compensa mientras los datos que necesitas vivan dentro de tu propiedad. En cuanto la pregunta sea «¿por qué mi competidor me supera?» o «¿quién le enlaza a él y no a mí?», has tocado techo con lo que expone GSC. A partir de ahí la elección es pagar 129–449 $ / mes a SEMrush o Ahrefs por datos de backlinks y competidores, o pagar una herramienta más pequeña como SEOJuice por la misma integración GSC más rastreo, auditoría y seguimiento de visibilidad IA gestionados, normalmente un 15–25 % de lo que cobran las suites enterprise.
Para la mayoría de los fundadores en solitario, el corte está entre 500 $ / mes de MRR y 5 K $ / mes de MRR. Por debajo, constrúyelo tú; el tiempo de ingeniería es más barato que la suscripción y aprenderás los datos en el proceso. Por encima, tu tiempo vale más que mantener rotaciones de auth y reintentos de cuota. Entre medias, depende de cuánto disfrutes programar Python a medianoche.
Otra ruta: construye la versión cron + Slack este fin de semana (seis horas incluida la configuración OAuth), ejecútala un mes y observa qué miras de verdad. Si solo revisas la alerta de «consultas principales en caída» y pasas del resto, has descubierto que solo necesitabas un widget: sigue construyendo o contrata. El artículo sobre estrategias SEO asequibles cubre el playbook de presupuesto reducido.
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [ { "@type": "Question", "name": "¿Cuánto tiempo conserva la API de GSC los datos históricos?", "acceptedAnswer": { "@type": "Answer", "text": "16 meses. Después, los datos desaparecen; no hay endpoint de archivo. Si quieres tendencias a más largo plazo, ejecuta un cron diario que guarde la ventana móvil en tu propio almacenamiento." } }, { "@type": "Question", "name": "¿Puedo usar la API de GSC para enviar URL a indexar?", "acceptedAnswer": { "@type": "Answer", "text": "No. El envío de URL se eliminó en 2020 tras abusos de spam. La Indexing API existe, pero solo admite ofertas de empleo y eventos en directo; usarla para contenido normal viola la política de Google." } }, { "@type": "Question", "name": "¿Cuál es la diferencia entre impresiones y clics en GSC?", "acceptedAnswer": { "@type": "Answer", "text": "Las impresiones cuentan cada vez que una URL aparece en una SERP. Los clics cuentan los clics del usuario sobre la URL. El CTR es la relación. En la era de AI Overview la brecha se amplía porque los usuarios leen la respuesta y no hacen clic en las fuentes citadas." } }, { "@type": "Question", "name": "¿Existe un nivel gratuito por encima de la cuota estándar de la API de GSC?", "acceptedAnswer": { "@type": "Answer", "text": "La cuota es la misma para todos: 1.200 solicitudes/min por proyecto en los endpoints de analytics y 2.000/día en URL Inspection. No hay opción de pago; se puede solicitar un aumento en Google Cloud Console, pero rara vez es necesario para cargas de trabajo de un fundador en solitario." } }, { "@type": "Question", "name": "¿Puedo delegar acceso a GSC sin compartir mi cuenta de Google?", "acceptedAnswer": { "@type": "Answer", "text": "Sí. Para eso sirven las cuentas de servicio. Crea una por integración, concédele acceso Restringido a la propiedad y revócalo sin tocar tu inicio de sesión." } }, { "@type": "Question", "name": "¿Qué bindings de lenguaje soporta la API de GSC?", "acceptedAnswer": { "@type": "Answer", "text": "Oficialmente: Python, Node, Java, PHP, Ruby, Go, .NET. Extraoficialmente: cualquier lenguaje capaz de llamar a un endpoint REST con un token Bearer. Las formas JSON son idénticas entre lenguajes." } } ] } </script>no credit card required
No related articles found.