api
POST /api/public/audit
Rode uma auditoria SEO anónima one-shot sem chave API. Resposta síncrona em menos de 60s, 1 por IP a cada 24h, sem Core Web Vitals.
O que este endpoint faz
POST /api/public/audit roda uma auditoria SEO síncrona em qualquer URL público sem chave API. Devolve o envelope completo da auditoria na mesma resposta: pontuação total, pontuações por módulo e findings ao nível de regra. PageSpeed Insights é pulado para manter a chamada barata e a resposta abaixo de 60 segundos.
- Síncrono: bloqueia até a auditoria terminar, sem polling.
- Anónimo: identificado pelo IP do cliente, limitado a 1 auditoria por IP a cada 24h.
- Pula Core Web Vitals (LCP, CLS, INP). Para dados PSI, use o
POST /api/auditsautenticado. - O resultado não é persistido numa conta de utilizador: uma linha de rate-limit é guardada na tabela audits com
user_id = NULL.
Por que importa
A auditoria anónima é o caminho de menor fricção para o widget “free audit” da página inicial e para ferramentas de terceiros que querem mostrar a pontuação da MetricSpot antes de pedir ao utilizador para se registar. Sem OAuth, sem geração de chaves, sem plano: apenas um POST HTTPS.
Fluxos concretos:
- Um construtor de landing page incorpora um formulário “teste o seu site” que chama o endpoint diretamente do browser do utilizador e renderiza a pontuação inline.
- Um bot Slack aceita
/audit example.comde qualquer colega e devolve a pontuação sem ninguém no workspace precisar de autenticar contra a MetricSpot.
Como usar
Envie um POST com um corpo JSON contendo url. O URL deve ser absoluto (https://...), parseável e ter no máximo 2000 caracteres.
Requisição
POST /api/public/audit HTTP/1.1
Host: app.metricspot.com
Content-Type: application/json
{ "url": "https://example.com" }
curl
curl -X POST https://app.metricspot.com/api/public/audit \
-H "content-type: application/json" \
-d '{"url": "https://example.com"}'
Node fetch
const res = await fetch("https://app.metricspot.com/api/public/audit", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ url: "https://example.com" }),
});
const { audit } = await res.json();
console.log(`Pontuação ${audit.total_score} para ${audit.domain}`);
Python httpx
import httpx
r = httpx.post(
"https://app.metricspot.com/api/public/audit",
json={"url": "https://example.com"},
timeout=90.0,
)
print(r.json()["audit"]["total_score"])
Resposta
200 OK com o envelope completo da auditoria:
{
"audit": {
"url": "https://example.com",
"domain": "example.com",
"total_score": 78,
"module_scores": {
"technical": 92,
"onpage": 71,
"performance": null,
"ai": 65,
"modern_seo": 80,
"social": 88,
"accessibility": 74,
"privacy": 82,
"readability": 70,
"tech_stack": 100,
"organic_traffic": 100
},
"rules": [
{
"module": "onpage",
"rule_id": "onpage.meta-description",
"passed": false,
"severity": "major",
"title": "Missing meta description",
"recommendation": "Add a 140-160 character meta description summarizing the page.",
"data": {}
}
]
},
"note": "Anonymous audits are limited and do not include Core Web Vitals. Sign up free for full audits and PDF reports."
}
Campos:
audit.url: o URL auditado, ecoado de volta.audit.domain: hostname extraído do URL.audit.total_score: pontuação ponderada em todos os módulos, 0 a 100.audit.module_scores: pontuação por módulo 0 a 100, ounullquando o módulo foi pulado (performanceé semprenullpara auditorias anónimas).audit.rules: array de cada regra avaliada. Cada entrada temmodule,rule_id,passed(boolean),severity(info|minor|major|critical),title,recommendationopcional, edata(payload específico da regra).note: string a explicar os limites anónimos, para exibir na UI.
Envelope de erro
{ "error": "Rate limit reached", "message": "Sign up free for more reports." }
Erros comuns
| Código | Quando | Ação |
|---|---|---|
INVALID_URL (400) | URL não parseável, sem esquema ou > 2000 caracteres | Passe um URL absoluto https:// |
RATE_LIMITED (429) | IP já auditou nas últimas 24h | Aguarde 24h, ou registe-se num plano Free (10 auditorias/mês) |
UPSTREAM_FAILED (502) | Falha do crawler | Tente novamente com backoff curto |
INTERNAL (500) | Erro de backend inesperado | Tente novamente; se persistir, faça login e use POST /api/audits para um retry enfileirado |
O endpoint não devolve 401, 402 ou 404: é não-autenticado por design e não tem recursos para olhar.
Perguntas frequentes
Por que performance é sempre null?
O endpoint anónimo pula o Google PageSpeed Insights para manter o tempo total abaixo de 60 segundos e evitar queimar quota PSI em tráfego não-limitado. Para Core Web Vitals (LCP, CLS, INP), use o POST /api/audits autenticado, que roda PSI em paralelo com o crawler.
Como o rate limit é aplicado?
Uma linha é inserida na tabela audits em cada execução anónima com user_id = NULL e ip_address definido para o IP do chamador. Chamadas subsequentes do mesmo IP em 24h devolvem 429. O IP é lido dos cabeçalhos padrão de proxy reverso (X-Forwarded-For), então auditorias atrás de um proxy partilhado podem colidir.
Posso usar isto a partir do browser?
Sim. O endpoint define CORS permissivo para metricspot.com e aceita POSTs cross-origin. Para o seu próprio domínio, rode uma função serverless como proxy fino: permite adicionar rate limiting por tenant e evita expor IPs dos seus visitantes à MetricSpot.
O resultado é persistido em algum lugar?
Existe uma linha para fins de rate-limit, mas não está ligada a qualquer conta e não é visível em painel nenhum. Para guardar e revisitar uma auditoria, registe-se grátis e chame POST /api/audits.
Fontes
Última atualização 2026-05-14