api
GET /api/audits/:id/google
Recupera lo snapshot del traffico organico per un audit, tirato da GA4 + GSC collegati. Restituisce sessioni, top query, pagine indicizzate. Cache 24h.
Cosa fa questo endpoint
GET /api/audits/:id/google restituisce lo snapshot del traffico organico per un audit, tirato dalla proprietà Google Analytics 4 e dal sito Google Search Console collegati dall’utente.
- Restituisce
{ "connected": false }quando l’utente non ha ancora collegato Google. - Restituisce
{ "connected": true, "linked": false }quando Google è connesso ma l’URL dell’audit non ha proprietà GA4 o sito GSC mappati. - Quando connesso e collegato, restituisce lo snapshot completo: traffico GA4, query GSC, e extra di indicizzazione.
- Cache lato server 24h per
(user_id, url), così chiamate ripetute nello stesso giorno sono economiche e idempotenti. - Solo Pro e gatato su scope OAuth Google: restituisce
403se il token non ha accesso Google o il piano dell’utente non include l’integrazione.
Perché è importante
Gli audit senza dati di traffico dicono agli agent cosa correggere, non cosa correggere per primo. Lo snapshot del traffico organico permette a un agent di rankare le pagine fallite per valore SEO reale, così le raccomandazioni atterrano sugli URL che effettivamente muovono ricavi.
Flussi concreti:
- Un agent “da dove inizio?” chiama
GET /api/audits/:idper i findings eGET /api/audits/:id/googleper le sessioni, poi redige una lista di correzioni ordinata per sessioni 28 giorni per landing page. - Un agent “query-gap” legge
gsc.top_queries(impressioni alte, CTR basso) e riscrive il title e la meta description della pagina corrispondente per alzare il CTR.
Come usarlo
L’utente deve prima connettere Google Analytics 4 e Search Console dentro la dashboard MetricSpot, poi mappare esplicitamente ogni URL di audit a una proprietà GA4 e un sito GSC. Quando non mappato, l’endpoint riesce comunque con linked: false così gli agent possono degradare graziosamente.
Richiesta
GET /api/audits/12345/google HTTP/1.1
Host: app.metricspot.com
Authorization: Bearer ms_live_xxxxxxxxxxxxxxxxxxxxxxxx
curl
curl https://app.metricspot.com/api/audits/12345/google \
-H "authorization: Bearer ms_live_xxxxxxxxxxxxxxxxxxxxxxxx"
Node fetch
const res = await fetch("https://app.metricspot.com/api/audits/12345/google", {
headers: { authorization: "Bearer ms_live_xxxxxxxxxxxxxxxxxxxxxxxx" },
});
const data = await res.json();
if (!data.connected) {
console.log("Collega Google su app.metricspot.com/settings/integrations");
} else if (!data.linked) {
console.log("Mappa questo URL a una proprietà GA4 e sito GSC nella dashboard");
} else {
console.log(`Sessioni 28g: ${data.ga4?.sessions_28d}`);
for (const q of data.gsc?.top_queries?.slice(0, 5) ?? []) {
const ctr = q.impressions ? q.clicks / q.impressions : 0;
console.log(`${q.query}: CTR ${(ctr * 100).toFixed(1)}%`);
}
}
Python httpx
import httpx
r = httpx.get(
"https://app.metricspot.com/api/audits/12345/google",
headers={"authorization": "Bearer ms_live_xxxxxxxxxxxxxxxxxxxxxxxx"},
timeout=30.0,
)
data = r.json()
if not data.get("connected"):
print("Collega Google su app.metricspot.com/settings/integrations")
elif not data.get("linked"):
print("Mappa questo URL a una proprietà GA4 e sito GSC")
else:
print("Sessioni 28g:", (data.get("ga4") or {}).get("sessions_28d"))
Risposta
Connesso e collegato
200 OK:
{
"connected": true,
"linked": true,
"ga4": {
"sessions_28d": 14328,
"sessions_trend": [
{ "date": "2026-04-16", "sessions": 482 },
{ "date": "2026-04-17", "sessions": 511 }
],
"top_landing_pages": [
{ "url": "https://example.com/", "sessions": 5104 },
{ "url": "https://example.com/pricing", "sessions": 2871 }
]
},
"gsc": {
"top_queries": [
{ "query": "example pricing", "clicks": 612, "impressions": 8412, "position": 4.2 },
{ "query": "example alternative", "clicks": 387, "impressions": 5101, "position": 7.8 }
],
"indexing": {
"indexed_pages": 184,
"coverage_issues": 3
}
},
"ga_property_used": {
"property_id": "properties/123456789",
"display_name": "Example - GA4"
},
"gsc_site_used": {
"site_url": "https://example.com/"
}
}
Campi:
connected:truese l’account ha un grant OAuth Google attivo.falsee gli altri campi sono omessi se non esiste alcun grant.linked:truese l’URL di questo audit ha una proprietà GA4 o sito GSC mappati.falsesignifica che l’utente deve mapparlo nella dashboard.ga4.sessions_28d: totale sessioni organiche negli ultimi 28 giorni.ga4.sessions_trend: serie giornaliera di sessioni organiche, dalla più vecchia alla più recente.ga4.top_landing_pages: array di{ url, sessions }, ordinato per sessioni desc.gsc.top_queries: array di{ query, clicks, impressions, position }, ordinato per clicks desc.gsc.indexing: oggetto opzionale conindexed_pagesecoverage_issuesda GSC.ga_property_used/gsc_site_used: il mappaggio usato dall’audit, per visualizzazione.
Connesso ma non collegato
{ "connected": true, "linked": false }
Non connesso
{ "connected": false }
Ri-autenticazione richiesta
Quando il token OAuth memorizzato non può essere rinfrescato (revocato o scaduto oltre il refresh), la riga di connessione è eliminata e l’endpoint restituisce:
{ "connected": false, "reason": "reauth_required" }
Errori comuni
| Codice | Quando | Azione |
|---|---|---|
UNAUTHORIZED (401) | Bearer mancante o non valido | Genera una chiave su app.metricspot.com/settings/api-keys |
FORBIDDEN (403) | Piano senza integrazioni Google, o audit appartenente a un altro account | Passa a Pro, o usa l’account proprietario |
AUDIT_NOT_FOUND (404) | Audit id non esiste | Passa un audit che possiedi |
INVALID_URL (400) | :id non è un intero positivo | Passa un id intero |
UPSTREAM_FAILED (5xx) | Outage API GA4 o GSC | Riprova; la risposta è cacheata 24h quando riesce |
Domande frequenti
Perché linked: false anche se vedo traffico in GA4?
Il link è per URL lato MetricSpot. Dopo aver connesso Google su app.metricspot.com/settings/integrations, devi anche mappare ogni URL di audit a una proprietà GA4 e sito GSC specifici. MetricSpot fa questo perché un account Google ha spesso molte proprietà GA4; il mappaggio esplicito evita di prendere quella sbagliata.
Perché una finestra di 28 giorni?
Corrisponde a come GSC riporta le sue top query per default ed è abbastanza corta per riflettere cambiamenti recenti (post-deploy, post-launch) e abbastanza lunga per lisciare la stagionalità settimanale. La finestra non è configurabile in v1.
Quanto fresco è il dato?
I dati GA4 sono tipicamente 24 a 48 ore indietro rispetto al tempo reale, secondo la finestra di processing di Google. I dati GSC hanno ritardo di 2 a 3 giorni. L’endpoint cachea risposte riuscite 24h per (user_id, url), così chiamate ripetute nello stesso giorno restituiscono lo stesso snapshot.
Questo consuma quota di audit?
No. Questo endpoint non è misurato oltre il piano dell’utente e la quota API Google. La cache 24h significa anche che un loop CI che martella questo endpoint non farà saltare i limiti giornalieri di Google.
Fonti
Ultimo aggiornamento 2026-05-14