Rate Limits
Die API schützt sich vor Überlastung und Missbrauch durch Anfragenlimits — abhängig vom Plan, Endpunkt-Typ und Authentifizierungsart.
Wie Rate Limits funktionieren
Alle Limits verwenden ein Gleitfenster von 60 Sekunden (1 Minute). Beim Überschreiten antwortet die API mit HTTP 429 und gibt an, wie lange gewartet werden soll:
HTTP/1.1 429 Too Many Requests
RateLimit-Limit: 60
RateLimit-Remaining: 0
RateLimit-Reset: 1713607260
Retry-After: 42
{
"success": false,
"error": "rate_limit_exceeded",
"message": "Zu viele Anfragen. Bitte warten.",
"retry_after_seconds": 42
}
Die Headers RateLimit-Limit, RateLimit-Remaining und RateLimit-Reset werden bei jeder Antwort mitgesendet — nicht nur bei 429. So können Clients ihr Budget proaktiv überwachen.
Limits nach Endpunkt-Typ
Unauthentifizierte Endpunkte (IP-basiert)
| Endpunkt | Limit | Fenster |
|---|---|---|
POST /api/auth/login, /register, /refresh |
10 Versuche | pro Minute / IP |
POST /api/auth/forgot-password, /reset-password |
5 Versuche | pro 15 Minuten / IP |
Quick-Check-Endpunkte (Partner-Freischaltung erforderlich)
POST /api/public/quickcheck und POST /api/public/geo-seo-quickcheck sind standardmäßig für jede Domain/jeden Aufrufer gesperrt —
das ist kein reines Rate-Limit, sondern eine Zugriffskontrolle: Anfragen werden nur akzeptiert, wenn der Origin-/Referer-Header einer im Admin-Bereich
("Quickcheck-Partner") freigeschalteten Domain entspricht, oder ein gültiger X-Api-Key mitgesendet wird. Alles andere erhält 403.
Freischaltung erfolgt manuell — Anfragen dazu an post@urbanstudio.de.
| Endpunkt | Limit | Fenster |
|---|---|---|
POST /api/public/quickcheck |
Konfigurierbar pro Partner (Default 30) | pro Stunde / Partner |
POST /api/public/geo-seo-quickcheck |
Konfigurierbar pro Partner (Default 30), eigener Zähler unabhängig vom allgemeinen Quick-Check | pro Stunde / Partner |
Authentifizierte API — Limits nach Plan
Die Limits gelten pro Organisation (JWT) bzw. pro Zugang (Token). Das Budget ist über alle Endpunkte der Kategorie geteilt — wer 8 verschiedene Routen aufruft, verbraucht dasselbe Budget wie wer eine Route 8-mal aufruft.
| Plan | Scans schreiben POST /audit/* |
Scans lesen GET /scans, /reports |
Monitoring lesen GET /servers, /websites |
Monitoring schreiben POST/DELETE /servers, /websites |
Billing POST /checkout, /portal |
|---|---|---|---|---|---|
| Free | 2/Min | 30/Min | — | — | 2/Min |
| Starter | 5/Min | 60/Min | — | — | 2/Min |
| Professional | 10/Min | 120/Min | — | — | 2/Min |
| Agentur | 15/Min | 200/Min | 200/Min | 40/Min | 5/Min |
| Agentur Pro | 20/Min | 300/Min | 300/Min | 60/Min | 5/Min |
| Monitor Free | — | — | 20/Min | 5/Min | 2/Min |
| Monitor Basic | — | — | 60/Min | 15/Min | 2/Min |
| Monitor Pro | — | — | 120/Min | 30/Min | 2/Min |
| Monitor Business | — | — | 300/Min | 60/Min | 2/Min |
— bedeutet: Das Feature ist im Plan nicht enthalten und wird vom Feature-Gate blockiert, bevor das Rate-Limit greift.
Zugänge trennen
Jeder API-Zugang (OAuth-Client) arbeitet im Rahmen der Limits Ihrer Organisation.
429-Fehler korrekt behandeln
Lesen Sie den Retry-After-Header und warte die angegebene Anzahl Sekunden, bevor Sie die Anfrage wiederholen. Implementieren Sie dabei exponentielles Backoff mit Jitter, um das gleichzeitige Neustarten mehrerer Clients zu vermeiden:
// Beispiel: Fetch mit automatischem Retry
async function apiWithRetry(url, options, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const res = await fetch(url, options);
if (res.status !== 429) return res;
const retryAfter = parseInt(res.headers.get('Retry-After') ?? '60');
const jitter = Math.random() * 1000;
await new Promise(r => setTimeout(r, retryAfter * 1000 + jitter));
}
throw new Error('Rate limit exceeded after retries');
}
Häufige Fragen
Gilt das Limit pro User oder pro Organisation?
Für JWT-Sessions (Dashboard) gilt es pro Organisation — alle Teammitglieder teilen dasselbe Budget. Für API-Zugänge gilt es pro Zugang, unabhängig vom Rest der Org.
Werden Billing-Endpunkte mitgezählt?
Nein — Billing-Anfragen (Checkout, Portal) haben ein eigenes, separates Budget (2–5/Min). Sie zählen nicht gegen das Scan- oder Monitoring-Budget.
Was passiert beim Agent-Heartbeat?
Der Server-Agent-Heartbeat (POST /api/monitoring/agent/heartbeat) hat kein Rate-Limit — er wird durch das im Response enthaltene check_interval_sec selbst gesteuert.