api

POST /api/public/audit

Anonymen SEO-Audit ohne API-Key starten. Synchrone Antwort unter 60s, gedeckelt auf 1 Audit pro IP pro 24h, ohne Core Web Vitals.

Was dieser Endpunkt macht

POST /api/public/audit führt einen synchronen SEO-Audit auf jeder öffentlichen URL ohne API-Key aus. Er liefert den vollen Audit-Envelope in derselben Antwort: Gesamtscore, Modulscores und regelbezogene Findings. PageSpeed Insights wird übersprungen, damit der Aufruf günstig bleibt und die Antwort unter 60 Sekunden dauert.

  • Synchron: blockiert bis der Audit fertig ist, kein Polling.
  • Anonym: über die Client-IP identifiziert, gedeckelt auf 1 Audit pro IP pro 24h.
  • Überspringt Core Web Vitals (LCP, CLS, INP). Für PSI-Daten den authentifizierten POST /api/audits nutzen.
  • Das Ergebnis wird keinem Konto zugeordnet: nur eine Rate-Limit-Zeile mit user_id = NULL wird gespeichert.

Warum das wichtig ist

Der anonyme Audit ist der reibungsärmste Weg für das “Kostenlos auditieren”-Widget auf einer Startseite und für Drittanbieter-Tools, die den MetricSpot-Score zeigen wollen, bevor sie einen Nutzer zur Registrierung bitten. Kein OAuth, kein Key, kein Plan: nur ein HTTPS-POST.

Konkrete Workflows:

  • Ein Landing-Builder bettet ein “Teste deine Seite”-Formular ein, das den Endpunkt direkt aus dem Browser des Nutzers aufruft und den Score inline rendert.
  • Ein Slack-Bot akzeptiert /audit example.com von jedem Teammitglied und postet den Score zurück, ohne dass sich jemand im Workspace bei MetricSpot authentifizieren muss.

Wie du ihn nutzt

Schicke einen POST mit JSON-Body, der url enthält. Die URL muss absolut sein (https://...), parsbar und maximal 2000 Zeichen lang.

Request

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(`Score ${audit.total_score} for ${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"])

Antwort

200 OK mit dem vollen Audit-Envelope:

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

Felder:

  • audit.url: die auditierte URL, als Echo zurück.
  • audit.domain: aus der URL extrahierter Hostname.
  • audit.total_score: gewichteter Score über alle Module, 0 bis 100.
  • audit.module_scores: Score pro Modul 0 bis 100, oder null wenn das Modul übersprungen wurde (z. B. performance ist bei anonymen Audits immer null).
  • audit.rules: Array jeder evaluierten Regel. Jeder Eintrag hat module, rule_id, passed (boolean), severity (info | minor | major | critical), title, optionalen recommendation und data (regelspezifisches Payload).
  • note: String mit den anonymen Limits, gedacht für UI-Anzeige.

Fehler-Envelope

{ "error": "Rate limit reached", "message": "Sign up free for more reports." }

Häufige Fehler

CodeWannAktion
INVALID_URL (400)URL nicht parsbar, ohne Schema oder länger als 2000 ZeichenAbsolute https://-URL übergeben
RATE_LIMITED (429)Diese IP hat in den letzten 24h schon auditiert24h warten oder kostenlosen Free-Plan registrieren (10 Audits/Monat)
UPSTREAM_FAILED (502)Crawler-Upstream-AussetzerMit kurzer Pause einmal erneut versuchen
INTERNAL (500)Unerwarteter Backend-FehlerErneut versuchen; bei Persistenz einloggen und POST /api/audits nutzen

Der Endpunkt liefert kein 401, 402 oder 404: er ist absichtlich nicht authentifiziert und hat keine Ressourcen zum Auflösen.

Häufig gestellte Fragen

Warum ist performance immer null?

Der anonyme Endpunkt überspringt Google PageSpeed Insights, um die Gesamtzeit unter 60 Sekunden zu halten und keine PSI-Quote auf ungebremsten Traffic zu verbrennen. Für Core Web Vitals (LCP, CLS, INP) den authentifizierten POST /api/audits nutzen, der PSI parallel zum Crawler ausführt.

Wie wird das Rate Limit erzwungen?

Bei jedem anonymen Lauf wird eine Zeile in die audits-Tabelle eingefügt mit user_id = NULL und ip_address auf die IP des Aufrufers gesetzt. Folgeaufrufe von derselben IP innerhalb von 24h liefern 429. Die IP wird aus Standard-Reverse-Proxy-Headern (X-Forwarded-For) gelesen; Audits hinter einem geteilten Proxy können kollidieren.

Kann ich das aus dem Browser nutzen?

Ja. Der Endpunkt setzt permissives CORS für metricspot.com und akzeptiert Cross-Origin-POSTs. Für deine eigene Domain eine Serverless-Funktion als dünnen Proxy laufen lassen: sie erlaubt Per-Tenant-Rate-Limiting und verhindert, dass die IPs deiner Besucher direkt an MetricSpot gehen.

Wird das Ergebnis irgendwo persistiert?

Für Rate-Limit-Zwecke existiert eine Zeile, sie ist aber keinem Nutzerkonto zugeordnet und in keinem Dashboard sichtbar. Um einen Audit zu speichern und später wieder zu öffnen, kostenlos registrieren und POST /api/audits nutzen.

Quellen

Zuletzt aktualisiert 2026-05-14