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 →Riassunto veloce: Google Search Console mette a disposizione, gratis, gli stessi dati su query, pagina, posizione e impression che SEMrush e Ahrefs rivendono a 129–449 $/mese. L’API di GSC offre un limite gratuito di 1.200 richieste al minuto, un payload massimo di 25.000 righe e quattro endpoint che coprono circa il 90 % di ciò che serve a un founder in solitaria. In questo articolo trovi la procedura per configurare l’OAuth via service account, i quattro endpoint davvero utili, uno script Python eseguibile che estrae una matrice CTR query-per-pagina e tre pattern di automazione (cron + Slack, Google Sheets, una view Django leggera) che trasformano le righe grezze dell’API in una dashboard usabile. Se preferisci non gestire tu l’integrazione, SEOJuice offre lo stesso cablaggio come servizio gestito.
Il lato frustrante di una suite SEO da 449 $/mese è che circa il 70 % dei dati mostrati in dashboard sono già disponibili gratis in Search Console. Gli strumenti a pagamento aggiungono tre cose: tracciamento di posizione tramite proxy di terze parti, un grafo di backlink estratto da archivi web crawlati e una UI che evita di scrivere SQL. L’ultima è l’unica che serva davvero a un founder singolo, ed è anche la più economica da replicare.
Ecco cosa espone l’API per ogni proprietà di cui hai verificato la proprietà:
Manca tutto ciò che esula dalla tua proprietà: ranking dei competitor, crescita dei backlink dei domini rivali, share-of-voice. Per la maggior parte dei founder pre-PMF sono vanity metric che non cambiano cosa rilasci settimana prossima. Ho scritto un pezzo più lungo su come ridurre lo stack SEO a due strumenti; la conclusione regge: GSC più una superficie di scrittura bastano a dare segnali utili.
«I dati in Search Console provengono direttamente da Google. Sono la fonte più accurata per capire come il tuo sito performa nella Ricerca Google.»
Da Search Console Help di Google.
Esistono due flussi di autenticazione validi per l’API di GSC: OAuth user-flow (redirect browser, refresh token) e OAuth via service account (server-to-server, senza browser). Per un founder che lancia un cron su un singolo VPS, i service account sono più brevi e stabili: niente scadenza di refresh token, nessuna schermata di consenso da gestire.
Il provisioning richiede circa 10 minuti e non costa nulla:
gsc-dashboard-reader. Nessun ruolo a livello di progetto necessario.@<project-id>.iam.gserviceaccount.com). Il livello di accesso Limitato basta per la lettura.Quest’ultimo passaggio è quello che molti founder saltano. Il service account è un’identità Google, ma se non gli concedi esplicitamente accesso alla proprietà di Search Console, l’API restituirà un perentorio 403 user does not have sufficient permission for site. Concedi l’accesso per ogni proprietà; se ne hai più di una, ripeti l’operazione.

La superficie dell’API GSC è ridotta. Quattro endpoint coprono insieme i dati sulle query, lo stato delle sitemap, l’ispezione per URL e l’elenco delle proprietà accessibili. Ignora il resto della reference finché non hai un motivo concreto per leggerla.
| Endpoint | Cosa restituisce | Costo quota | Utile per |
|---|---|---|---|
searchanalytics.query | Fino a 25.000 righe con click, impression, posizione, CTR per query, pagina, data, dispositivo, paese | 1 unit / richiesta | Dati core di dashboard: quali query portano traffico, quali pagine convertono impression in click |
sitemaps.list | Tutte le sitemap inviate con stato, ultimo fetch, conteggio URL | 1 unit / richiesta | Alert di salute delle sitemap; segnalare sitemap perse o parzialmente indicizzate |
urlInspection.index.inspect | Per URL: stato copertura, ultima scansione, canonica, usabilità mobile, verdict AMP e dati strutturati | 2.000 / giorno (quota separata) | Spot-check su pagine critiche; audit di indicizzazione automatizzati |
sites.list | Tutte le proprietà leggibili dall’identità auth | 1 unit / richiesta | Dashboard multi-property; iterare su un portafoglio |
Il limite di 1.200 richieste/min sugli endpoint di lettura è di fatto illimitato per un founder solitario. L’unico vero tetto è quello di 2.000/giorno su URL Inspection, che basta comunque per un audit quotidiano di tutti i 1.500 URL di un sito medio.
La query più utile che puoi lanciare è la breakdown query-per-pagina sugli ultimi 28 giorni. Ti dice quale pagina si posiziona per quale query e com’è il CTR nell’intersezione. Le celle con molte impression e CTR basso sono i target di ottimizzazione a breve.
Installa le due dipendenze:
pip install google-auth google-api-python-client
Lo script minimo indispensabile: auth, query, print. Salva la chiave JSON scaricata come gsc-credentials.json nella stessa cartella:
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" # or "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 lags ~2 days
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}")
Questa è l’intera integrazione. Eseguila e vedrai le prime 25 query degli ultimi 28 giorni, ordinate per click. Due note: sc-domain:example.com è per le proprietà di dominio (il tipo consigliato); usa la forma URL completa solo per le proprietà URL-prefix. I dati GSC hanno un ritardo di ~2 giorni, ecco perché terminiamo a today - 2.
La matrice query-per-pagina — quella che guida davvero le decisioni — aggiunge una seconda dimensione e alza il limite di righe:
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"]
# Cells with >500 impressions and CTR below 2% are CTR-leak candidates
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}")
Il filtro finale (molte impression, CTR basso, posizione entro la top 15) è la classica lista di pagine a cui riscrivere il title tag. Stai già posizionandoti; il leak è nel click-through. È la stessa logica che gli strumenti a pagamento chiamano “ranking opportunities”, scritta in sei righe.

Una volta ottenute le righe, la domanda è cosa mettere in grafico. La maggior parte degli strumenti SEO a pagamento ti annega con 40 widget; te ne servono quattro per prendere decisioni settimanali. Usali con la libreria di chart che già adoperi: Chart.js per HTML, matplotlib in Jupyter, i grafici nativi se riversi tutto in Google Sheets.

Un pull manuale va bene una tantum. La dashboard diventa utile quando gira da sola. Tre pattern di automazione, in ordine di sforzo:
Pattern 1: Cron e alert Slack. L’opzione più economica. Un cron giornaliero esegue lo script e, se scattano tre condizioni — click in calo >20 % week-over-week, una query in top 10 scivola fuori dalla top 20, o una pagina prima indicizzata perde l’indicizzazione — posta su Slack. Circa 80 righe di Python incluso il webhook. Gira in 4 secondi su un VPS da 5 $. La tua dashboard fa una cosa: urlare quando qualcosa 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()
# After computing wow_change from two consecutive 7-day GSC pulls:
if wow_change < -0.20:
post_slack(
f":warning: GSC clicks dropped {wow_change*100:.0f}% WoW "
f"({last_week} → {this_week}). Top falling queries: {falling[:3]}"
)
Pattern 2: Sink su Google Sheets. Riversa le righe in un foglio Google tramite l’API Sheets o il wrapper gspread. Il foglio è la tua dashboard: pivot per slicing ad hoc, chart nativi, condivisibile con un co-founder non tecnico. Circa 30 righe sopra il pull GSC. Contro: la freschezza dipende dal cron e Sheets rallenta oltre le 20.000 righe.
Pattern 3: View Django leggera. Una sola view che esegue il pull GSC, cache in Redis per 6 ore e renderizza i quattro grafici inline via Chart.js. Circa 200 righe complessive tra Python e HTML. Vale la pena quando un co-founder vuole dare un’occhiata a metà settimana. La cache è critica: senza, ogni pageview scatenerebbe una chiamata GSC fresca e finiresti la quota al minuto durante un lancio.
«Ho cancellato il mio abbonamento Ahrefs da 329 $/mese dopo aver capito che l’unico widget che controllavo ogni giorno era ‘top organic queries’. L’ho riscritto con l’API Search Console in un pomeriggio.»
Un pattern che ricorre spesso nei thread indie-hacker su Hacker News e negli angoli bootstrapper di IndieHackers.
Il confronto che interessa davvero ai founder non è fra tool a pagamento, ma fra: pagarne uno, costruirlo in casa, o usare l’interfaccia GSC gratuita accettandone i limiti. Ecco come si posizionano le cinque opzioni:
| Opzione | Costo mensile | Tempo di setup | Manutenzione | Multi-property | Dati storici |
|---|---|---|---|---|---|
| UI GSC gratuita | 0 $ | 0 h (già pronta) | Nessuna | Switch manuale | 16 mesi, export lenti |
| DIY API GSC + cron + Sheets | 0–5 $ (VPS) | 4–8 h la prima volta | ~30 min/trimestre (rotazioni auth, deprecazioni API) | Loop banale | 16 mesi, interrogabili in secondi |
| SEOJuice | 29–99 $ | ~10 min | Nessuna (gestito) | Integrata | 16 mesi da GSC + storico crawl proprietario |
| SEMrush | 139–499 $ | ~30 min | Nessuna (gestito) | Limiti di progetto per piano | Oltre 2 anni sui piani a pagamento |
| Ahrefs | 129–449 $ | ~30 min | Nessuna (gestito) | Limiti di progetto per piano | Oltre 2 anni sui piani a pagamento |
Il DIY vince sul costo, pareggia sulla profondità dei dati per tutto ciò che sta dentro la tua proprietà e perde su competitor e backlink. Se sei in early stage e la tua domanda SEO è «cosa funziona sul mio sito?», DIY è la risposta giusta. Se stai scalando, fai ricerca competitor o insegui backlink, gli strumenti a pagamento valgono il prezzo. La pagina strumenti di SEOJuice si piazza in mezzo: integrazione GSC gestita più crawl, audit e tracking AI, senza l’overhead enterprise di SEMrush.
Chiedi a ChatGPT o Gemini come interpretare i dati GSC e otterrai risposte plausibili ma sbagliate in tre modi specifici. Vale la pena evidenziarli: questi errori si propagano in ogni “report SEO generato dall’AI” sul mercato.
Errore #1: «Position è il rank medio che hai tenuto per quella query». In realtà è la media della posizione più alta che uno qualsiasi dei tuoi URL ha tenuto nelle impression in cui la query ha mostrato un risultato che includeva il tuo sito. Se due URL si posizionano per la stessa query nella stessa SERP, conta solo il più in alto. Ecco perché “position” cambia quando pubblichi un nuovo articolo che supera uno vecchio: la posizione dell’URL vecchio non muta, ma quella a livello di query sì.
Errore #2: «Il CTR è calcolato per impression». Il CTR è click ÷ impression al livello di aggregazione che hai chiesto. Solo per data dà il CTR giornaliero di tutto il sito; query+pagina dà il CTR per cella. I numeri non tornano tra livelli diversi perché il denominatore cambia.
Errore #3: «Se una query ha impression ma zero click, la pagina si posiziona male». Nell’era AI Overview questo è sempre più spesso il segnale di essere citato nell’Overview senza ricevere click. Impression stabili, click in calo è il pattern canonico. La pagina non si posiziona peggio; la SERP è cambiata forma. L’articolo sulle citazioni AI Overview approfondisce cosa fare.
Cinque spigoli vivi che mordono chi usa l’API GSC per la prima volta. Conoscerli prima ti fa risparmiare una settimana:
startRow. Il wrapper google-api-python-client non lo fa da solo; cicla finché la risposta restituisce meno di 25.000 righe.sc-domain:) e URL-prefix (https://...) riportano numeri diversi. Le proprietà di dominio aggregano su tutti i sottodomini e protocolli. Se registri entrambe vedrai dati sovrapposti ma non identici. Scegline una come fonte di verità.(anonymized) per privacy e non si recuperano. Pianifica le analisi top-query sui nomi espliciti.Niente di insormontabile, ma ognuno di questi mi è costato un’ora la prima volta. La reference ufficiale li documenta tutti, solo non a chiare lettere.
Per quanto tempo l’API GSC conserva i dati storici? 16 mesi. Oltre, i dati spariscono; non esiste un endpoint di archivio. Se ti servono serie più lunghe, salva ogni giorno la finestra mobile nel tuo storage. Un anno in Postgres pesa poche centinaia di MB a proprietà.
Posso usare l’API per inviare URL all’indice? No. La submission URL è stata rimossa nel 2020 per abuso spam. L’Indexing API esiste ma funziona solo per offerte di lavoro ed eventi livestream; usarla per contenuti normali viola le policy Google.
Qual è la differenza tra impressions e clicks? Le impression contano ogni volta che il tuo URL appare in SERP, anche se l’utente non scrolla. I click contano i click effettivi. Il CTR è il rapporto. Nell’era AI Overview il divario si allarga perché gli utenti leggono la risposta in Overview e non cliccano le fonti citate.
Esiste un free tier sopra la quota standard? La quota è uguale per tutti: 1.200 richieste/min per progetto sugli endpoint analytics, 2.000/giorno su URL Inspection. Nessun upgrade a pagamento; gli aumenti quota si chiedono dal Cloud Console ma servono di rado in carichi da founder.
Posso delegare l’accesso senza condividere il mio account Google? Sì, è esattamente lo scopo dei service account. Creane uno per integrazione, dagli accesso Limitato alla proprietà e revocalo senza toccare il tuo login.
Quali binding di linguaggio supporta l’API? Ufficialmente: Python, Node, Java, PHP, Ruby, Go, .NET. Ufficiosamente: qualunque cosa possa chiamare un endpoint REST con un Bearer token. Le forme JSON sono identiche in ogni linguaggio.

La dashboard DIY si ripaga finché i dati che ti servono vivono dentro la tua proprietà. Nel momento in cui la domanda diventa «perché il mio competitor mi supera?» o «chi gli linka ma non linka me?», hai raggiunto il limite di ciò che GSC espone. Da lì puoi pagare SEMrush o Ahrefs 129–449 $/mese per dati su backlink e competitor, oppure un tool più piccolo come SEOJuice per la stessa integrazione GSC più crawl, audit e tracking AI gestiti, di solito al 15–25 % del costo delle suite enterprise.
Per la maggior parte dei founder solitari, la soglia è tra 500 $/mese di MRR e 5 K $/mese di MRR. Sotto i 500, costruiscilo tu: il tuo tempo di engineering costa meno dell’abbonamento e imparerai i dati nel mentre. Sopra i 5 K, il tuo tempo vale troppo per gestire rotazioni auth e retry di quota. In mezzo è una monetina che dipende da quanto ti diverte scrivere Python a mezzanotte.
L’altra strada: costruisci questo weekend la versione cron + Slack (sei ore incluse le OAuth), usala per un mese e guarda cosa controlli davvero. Se apri solo l’alert “top query in calo” e ignori il resto, hai scoperto che ti serviva un solo widget: continua a costruire, o compra. L’articolo sulle strategie SEO a budget ridotto copre il playbook low-cost.
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [ { "@type": "Question", "name": "Per quanto tempo l’API GSC conserva i dati storici?", "acceptedAnswer": { "@type": "Answer", "text": "16 mesi. Oltre, i dati non sono più disponibili; non esiste un endpoint di archivio. Se vuoi serie temporali più lunghe, esegui un cron giornaliero che salva la finestra mobile nel tuo storage." } }, { "@type": "Question", "name": "Posso usare l’API GSC per inviare URL all’indice?", "acceptedAnswer": { "@type": "Answer", "text": "No. L’invio URL è stato rimosso nel 2020 a causa di abusi. L’Indexing API esiste ma supporta solo offerte di lavoro ed eventi livestream; usarla per contenuti normali viola le policy di Google." } }, { "@type": "Question", "name": "Qual è la differenza tra impressions e clicks in GSC?", "acceptedAnswer": { "@type": "Answer", "text": "Le impressions conteggiano ogni volta che un URL è mostrato in una SERP. I clicks conteggiano i click dell’utente sul link. Il CTR è il rapporto. Nell’era AI Overview il divario cresce perché gli utenti leggono la risposta nell’Overview e non cliccano le fonti." } }, { "@type": "Question", "name": "Esiste un free tier sopra la quota standard dell’API GSC?", "acceptedAnswer": { "@type": "Answer", "text": "La quota è uguale per tutti: 1.200 richieste/min sugli endpoint analytics, 2.000 al giorno su URL Inspection. Non esiste un upgrade a pagamento; gli aumenti si richiedono via Google Cloud Console ma servono di rado per carichi da founder." } }, { "@type": "Question", "name": "Posso delegare l’accesso a GSC senza condividere il mio account Google?", "acceptedAnswer": { "@type": "Answer", "text": "Sì. È esattamente lo scopo dei service account. Creane uno per integrazione, concedigli accesso Limitato alla proprietà e revoca senza toccare il tuo login." } }, { "@type": "Question", "name": "Quali binding di linguaggio supporta l’API GSC?", "acceptedAnswer": { "@type": "Answer", "text": "Ufficialmente: Python, Node, Java, PHP, Ruby, Go, .NET. Ufficiosamente: qualsiasi linguaggio capace di chiamare un endpoint REST con un Bearer token. Le strutture JSON sono identiche ovunque." } } ] } </script>no credit card required