api
POST /api/audits
Encua una auditoria SEO completa amb Core Web Vitals. Retorna audit_id + status: queued en 1-2s. Compta contra el pla, respecta cooldowns.
Què fa aquest endpoint
POST /api/audits encua una auditoria SEO i d’AI-readability completa i retorna immediatament amb el sobre d’auditoria. És l’equivalent autenticat i complet del POST /api/public/audit.
- S’encua de forma asíncrona i retorna en 1-2 segons amb
status: "queued"i unaudit_idreal. - Obté els Core Web Vitals (LCP, CLS, INP) de Google PageSpeed Insights com a part de l’execució.
- Compta contra l’allocació del pla de l’usuari (Free 10/mes, Starter 50/mes, Pro il·limitat).
- Respecta els cooldowns per domini: 24 hores entre auditories de la mateixa URL exacta, més un cooldown global curt entre qualsevol parella d’auditories.
- Retorna la mateixa forma que
GET /api/audits/:id. Els findings estan buits fins que l’auditoria passa acompleted.
Per què importa
POST /api/audits és l’endpoint correcte sempre que necessitis una auditoria persistent que puguis recuperar després, un PDF, dades de tràfic orgànic o Core Web Vitals. Les auditories anònimes cobreixen unes 90 comprovacions però salten PSI; aquest endpoint ho cobreix tot.
Fluxos concrets:
- Un bot d’auditoria a les PR crida
POST /api/auditsquan es desplega una preview, captura l’audit_id, fa poll aGET /api/audits/:idcada 5 segons fins a 60 segons, i publica un comentari amb la diferència respecte a la darrera auditoria de la mateixa URL. - Un agent cron setmanal recorre les landing pages més visitades de l’usuari i encua una auditoria nova per a cadascuna, i després envia un resum des de
GET /api/audits.
Com utilitzar-lo
L’endpoint és asíncron per disseny. Tracta la resposta immediata 201 Created com una confirmació, i després fes poll a GET /api/audits/:id amb l’audit_id retornat cada pocs segons. El temps típic de finalització és de 10 a 30 segons; preveu fins a 90 segons per a objectius lents.
Petició
POST /api/audits HTTP/1.1
Host: app.metricspot.com
Authorization: Bearer ms_live_xxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
{ "url": "https://example.com" }
El camp url és obligatori, ha de ser absolut (https://...), parsejable, i com a màxim de 2000 caràcters.
curl
curl -X POST https://app.metricspot.com/api/audits \
-H "authorization: Bearer ms_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
-H "content-type: application/json" \
-d '{"url": "https://example.com"}'
Node (encuar + poll)
const headers = {
authorization: "Bearer ms_live_xxxxxxxxxxxxxxxxxxxxxxxx",
"content-type": "application/json",
};
const queueRes = await fetch("https://app.metricspot.com/api/audits", {
method: "POST",
headers,
body: JSON.stringify({ url: "https://example.com" }),
});
const { audit } = await queueRes.json();
const id = audit.id;
while (true) {
await new Promise((r) => setTimeout(r, 3000));
const r = await fetch(`https://app.metricspot.com/api/audits/${id}`, { headers });
const data = await r.json();
if (["completed", "failed"].includes(data.audit.status)) {
console.log(data.audit.status, data.audit.score);
break;
}
}
Python httpx
import httpx, time
HEADERS = {"authorization": "Bearer ms_live_xxxxxxxxxxxxxxxxxxxxxxxx"}
r = httpx.post(
"https://app.metricspot.com/api/audits",
headers=HEADERS,
json={"url": "https://example.com"},
timeout=30.0,
)
audit_id = r.json()["audit"]["id"]
for _ in range(30):
time.sleep(3)
r = httpx.get(f"https://app.metricspot.com/api/audits/{audit_id}", headers=HEADERS, timeout=30.0)
audit = r.json()["audit"]
if audit["status"] in ("completed", "failed"):
print(audit["status"], audit["score"])
break
Resposta
201 Created:
{
"audit": {
"id": 12345,
"domain": "example.com",
"url": "https://example.com",
"status": "queued",
"score": null,
"created_at": "2026-05-14T10:18:04.000Z"
}
}
Camps de la resposta encuada:
id: id enter de l’auditoria, utilitzat a cada crida posterior (GET /api/audits/:id, PDF, Google).domain: hostname extret de la URL.url: retornat tal qual des de la petició.status: sempre"queued"a la resposta inicial. Passa a"running"i després a"completed"o"failed".score:nullfins que l’auditoria acaba.created_at: timestamp ISO 8601.
Quan status === "completed", GET /api/audits/:id retorna el sobre complet amb score, module_scores i l’array findings (vegeu api-get-audit).
Sobre d’error
{ "error": "Quota exceeded", "message": "Upgrade to Starter for 50 audits per month." }
Errors habituals
| Codi | Quan | Acció |
|---|---|---|
UNAUTHORIZED (401) | Token Bearer absent o invàlid | Emet una clau a app.metricspot.com/settings/api-keys |
QUOTA_EXCEEDED (402) | Allocació mensual del pla utilitzada | Actualitza a app.metricspot.com/billing |
INVALID_URL (400) | URL no parsejable o > 2000 caràcters | Passa una URL absoluta https:// |
RATE_LIMITED (429) | Cooldown per domini o global | Espera la finestra indicada abans de reintentar la mateixa URL |
UPSTREAM_FAILED (5xx) | Falla puntual de PSI o del rastrejador | Reintenta un cop amb backoff |
Preguntes freqüents
Quant triga a acabar l’auditoria?
10 a 30 segons per a llocs típics. Objectius amb molt JS o pàgines amb grans quantitats de dades estructurades poden trigar fins a 90 segons. Fes poll a GET /api/audits/:id cada 3 a 5 segons: l’auditoria està totalment calculada quan status passa a completed.
Una auditoria fallida consumeix una auditoria?
Una auditoria amb estat failed no consumeix allocació de pla. La quota només es decrementa quan l’execució acaba correctament i els findings es desen. Els errors de rate-limit de PSI es reintenten internament abans de sortir cap a fora.
Per què hi ha un cooldown per domini?
La mateixa URL auditada dues vegades en cinc minuts retorna els mateixos findings: malgasta quota de PSI i confon els dashboards de tràfic. El cooldown de 24 hores per URL s’aplica al servidor. El missatge d’error inclou el timestamp exacte de retry_at perquè els clients puguin planificar el nou encuat.
Puc encuar moltes auditories en paral·lel?
Sí, fins al cooldown global (uns pocs segons entre qualsevol parella d’auditories per compte). Per a lots de 50+ URLs, espaia-les des del client o utilitza Pro, que aixeca la quota mensual i afluixa el throttle global.
Fonts
Última actualització 2026-05-14