api

GET /api/audits/:id

Récupérez un audit par id avec score, ventilation par module et le tableau complet de findings. C'est l'endpoint à poll après POST /api/audits.

Ce que fait cet endpoint

GET /api/audits/:id renvoie l’enveloppe complète d’un audit que votre compte possède : scores, ventilation par module et chaque règle évaluée. C’est l’endpoint à poll après mise en file via POST /api/audits.

  • Idempotent et cacheable côté client : les findings d’un audit ne changent plus une fois status === "completed".
  • Inclut plan (plan effectif de l’utilisateur) et cooldown (quand le prochain audit sur la même URL est autorisé), que le tableau de bord utilise pour afficher les boutons.
  • Renvoie 404 si l’id n’existe pas, 403 si l’audit appartient à un autre compte, 401 si le token Bearer manque ou est invalide.

Pourquoi c’est important

GET /api/audits/:id est la relecture de tout audit mis en file. C’est l’appel placé dans une boucle de polling 3-5 secondes après POST /api/audits, et c’est l’appel fait plus tard quand un agent veut revoir les findings sans rejouer l’audit.

Workflows concrets :

  • Un bot audit-sur-PR poll toutes les 3 secondes jusqu’à status completed, puis trie les findings par severity et poste les trois pires sur le PR.
  • Un agent réviseur de contenu reçoit l’id d’audit par webhook et tire les findings pour rédiger une liste de corrections ordonnée par module.

Comment l’utiliser

L’id est l’entier renvoyé par POST /api/audits. Auth Bearer obligatoire.

Requête

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"])

Réponse

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" }
}

Champs :

  • audit.status : un parmi queued, running, completed, failed. Les findings ne sont stables qu’en completed.
  • audit.score : entier 0 à 100, ou null pendant la file ou l’exécution.
  • audit.raw.module_scores : score par module 0 à 100. Modules non applicables renvoient null.
  • audit.perf_status : ready dès que PageSpeed Insights répond ; pending tant que PSI est en vol.
  • audit.error_message : rempli uniquement quand status === "failed".
  • findings[] : chaque règle évaluée, y compris celles qui passent. Filtrez sur passed: false pour ne garder que les échecs.
  • findings[].severity : info, minor, major, critical. Triez en décroissant pour la liste de correctifs la plus utile.
  • findings[].data : données supplémentaires propres à la règle (par ex. tailles en pixels, nombre de tags absents).
  • plan : plan effectif de l’utilisateur : free, starter ou pro.
  • cooldown.ready_at : horodatage ISO du prochain audit autorisé pour cette URL.

Enveloppe d’erreur

{ "error": "Not found" }

Erreurs courantes

CodeQuandAction
UNAUTHORIZED (401)Bearer manquant ou invalideCréez une clé sur app.metricspot.com/settings/api-keys
FORBIDDEN (403)L’audit appartient à un autre compteUtilisez la clé du compte propriétaire, ou appelez GET /api/audits
AUDIT_NOT_FOUND (404):id inexistantAppelez GET /api/audits et utilisez un id réel
INVALID_URL (400):id n’est pas un entier positifPassez un id entier

Questions fréquentes

À quelle fréquence dois-je poller ?

3 à 5 secondes est le bon créneau. Plus rapide gaspille des allers-retours ; plus lent retarde le commentaire ou la notification. La plupart des audits finissent dans les 30 premières secondes ; abandonnez la boucle à 90 secondes et remontez l’état “encore en cours” à l’utilisateur.

Les findings sont-ils triés utilement ?

Ils arrivent dans l’ordre d’insertion (id croissant), qui reflète l’exécution des modules par le pipeline. Pour une liste lisible par un humain, triez côté client par severity (critical > major > minor > info), puis par module.

Que se passe-t-il si je consulte un audit en cours ?

Vous obtiendrez status: "queued" ou status: "running" avec findings vide et score: null. Les autres champs (id, domain, url, created_at) sont stables dès la première réponse.

Cela consomme-t-il du quota ?

Non. Seul POST /api/audits (et seulement en cas de succès) décrémente le compteur mensuel. GET /api/audits/:id n’est pas comptabilisé.

Sources

Dernière mise à jour 2026-05-14