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 403 se 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/:id per i findings e GET /api/audits/:id/google per 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: true se l’account ha un grant OAuth Google attivo. false e gli altri campi sono omessi se non esiste alcun grant.
  • linked: true se l’URL di questo audit ha una proprietà GA4 o sito GSC mappati. false significa 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 con indexed_pages e coverage_issues da 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

CodiceQuandoAzione
UNAUTHORIZED (401)Bearer mancante o non validoGenera una chiave su app.metricspot.com/settings/api-keys
FORBIDDEN (403)Piano senza integrazioni Google, o audit appartenente a un altro accountPassa a Pro, o usa l’account proprietario
AUDIT_NOT_FOUND (404)Audit id non esistePassa un audit che possiedi
INVALID_URL (400):id non è un intero positivoPassa un id intero
UPSTREAM_FAILED (5xx)Outage API GA4 o GSCRiprova; 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