api

GET /api/audits/:id

Recupera un singolo audit per id con punteggio, ripartizione per modulo e l'array completo dei findings. Polla questo dopo aver messo in coda con POST /api/audits.

Cosa fa questo endpoint

GET /api/audits/:id restituisce la busta completa di un audit che il tuo account possiede: punteggi, ripartizione per modulo e ogni regola valutata. Questo è l’endpoint da pollare dopo aver messo in coda con POST /api/audits.

  • Idempotente e cacheable lato client: i findings di un audit non cambiano più quando status === "completed".
  • Include plan (piano effettivo corrente dell’utente) e cooldown (quando il prossimo audit sullo stesso URL è permesso), che la dashboard usa per renderizzare i bottoni.
  • Restituisce 404 se l’id non esiste, 403 se l’audit appartiene a un altro account, 401 se il token Bearer manca o non è valido.

Perché è importante

GET /api/audits/:id è la rilettura di qualsiasi audit che hai messo in coda. È la chiamata che metti in un loop di polling 3-5 secondi dopo POST /api/audits, ed è la chiamata che fai più tardi quando un agent vuole rivedere i findings senza ri-eseguire l’audit.

Flussi concreti:

  • Un bot audit-on-PR polla ogni 3 secondi finché status è completed, poi ordina i findings per severity e posta i tre peggiori sul PR.
  • Un agent revisore di contenuti riceve l’id dell’audit via webhook e tira i findings per redigere una lista di correzioni ordinata per modulo.

Come usarlo

L’id è l’intero restituito da POST /api/audits. Auth Bearer obbligatoria.

Richiesta

GET /api/audits/12345 HTTP/1.1
Host: app.metricspot.com
Authorization: Bearer ms_live_xxxxxxxxxxxxxxxxxxxxxxxx

curl

curl https://app.metricspot.com/api/audits/12345 \
  -H "authorization: Bearer ms_live_xxxxxxxxxxxxxxxxxxxxxxxx"

Node fetch

const res = await fetch("https://app.metricspot.com/api/audits/12345", {
  headers: { authorization: "Bearer ms_live_xxxxxxxxxxxxxxxxxxxxxxxx" },
});
const data = await res.json();
console.log(data.audit.status, data.audit.score);
console.log(`${data.findings.length} findings`);

Python httpx

import httpx

r = httpx.get(
    "https://app.metricspot.com/api/audits/12345",
    headers={"authorization": "Bearer ms_live_xxxxxxxxxxxxxxxxxxxxxxxx"},
    timeout=30.0,
)
data = r.json()
for f in data["findings"]:
    if not f["passed"] and f["severity"] in ("major", "critical"):
        print(f["severity"], f["rule_id"], f["title"])

Risposta

200 OK:

{
  "audit": {
    "id": 12345,
    "user_id": 42,
    "domain": "example.com",
    "url": "https://example.com",
    "status": "completed",
    "score": 78,
    "audit_version": 7,
    "raw": {
      "module_scores": {
        "technical": 92,
        "onpage": 71,
        "performance": 84,
        "ai": 65,
        "modern_seo": 80,
        "social": 88,
        "accessibility": 74,
        "privacy": 82,
        "readability": 70,
        "tech_stack": 100,
        "organic_traffic": 100
      }
    },
    "perf_status": "ready",
    "error_message": null,
    "started_at": "2026-05-14T10:18:05.000Z",
    "completed_at": "2026-05-14T10:18:24.000Z",
    "created_at": "2026-05-14T10:18:04.000Z"
  },
  "findings": [
    {
      "id": 9001,
      "module": "onpage",
      "rule_id": "onpage.meta-description",
      "severity": "major",
      "passed": false,
      "title": "Missing meta description",
      "recommendation": "Add a 140-160 character meta description summarizing the page.",
      "data": {}
    }
  ],
  "plan": "starter",
  "cooldown": { "ready_at": "2026-05-15T10:18:04.000Z" }
}

Campi:

  • audit.status: uno di queued, running, completed, failed. I findings sono stabili solo quando completed.
  • audit.score: intero 0 a 100, o null mentre in coda o in esecuzione.
  • audit.raw.module_scores: punteggio per modulo 0 a 100. Moduli non applicabili restituiscono null.
  • audit.perf_status: ready quando PageSpeed Insights restituisce; pending mentre PSI è ancora in volo.
  • audit.error_message: popolato solo quando status === "failed".
  • findings[]: ogni regola valutata, incluse quelle passate. Filtra su passed: false per ottenere solo i fallimenti.
  • findings[].severity: info, minor, major, critical. Ordina desc per severity per la lista di correzioni più utile.
  • findings[].data: dati extra specifici della regola (es: dimensioni pixel misurate, conteggio tag mancanti).
  • plan: piano effettivo dell’utente: free, starter o pro.
  • cooldown.ready_at: timestamp ISO del prossimo audit permesso per questo URL.

Busta di errore

{ "error": "Not found" }

Errori comuni

CodiceQuandoAzione
UNAUTHORIZED (401)Bearer mancante o non validoGenera una chiave su app.metricspot.com/settings/api-keys
FORBIDDEN (403)Audit appartiene a un altro accountUsa la chiave dell’account proprietario, o chiama GET /api/audits per elencare i tuoi
AUDIT_NOT_FOUND (404):id non esisteChiama GET /api/audits e usa un id reale
INVALID_URL (400):id non è un intero positivoPassa un id intero

Domande frequenti

Quanto spesso dovrei pollare?

3 a 5 secondi è il punto giusto. Più veloce spreca round trip; più lento ritarda il commento o la notifica downstream. La maggior parte degli audit completa entro i primi 30 secondi; fai bail a 90 secondi ed esponi lo stato ancora-in-esecuzione all’utente.

I findings sono ordinati in un ordine utile?

Sono restituiti in ordine di inserimento (per id ascendente), che rispecchia come la pipeline di audit fa girare i moduli. Per una lista di correzioni rivolta all’umano, ordina lato client per severity (critical > major > minor > info), poi per modulo.

Cosa succede se recupero un audit mentre è ancora in esecuzione?

Otterrai status: "queued" o status: "running" con un array findings vuoto e score: null. Gli altri campi (id, domain, url, created_at) sono stabili dalla prima risposta.

Questo consuma quota del piano?

No. Solo POST /api/audits (e solo quando riesce) decrementa il contatore mensile. GET /api/audits/:id è non-misurato.

Fonti

Ultimo aggiornamento 2026-05-14