Verstehen Sie die API-Rate-Limits von Zenovay und optimieren Sie Ihre Integration für Zuverlässigkeit und Leistung.
Übersicht der Rate Limits
Die REST-API ist eine kostenpflichtige Funktion. API-Schlüssel funktionieren nur auf Pro-, Scale- und Enterprise-Tarifen — Free-Plan-Schlüssel werden mit einer 403 API_PAID_PLAN_REQUIRED-Antwort abgelehnt.
API-Limits nach Tarif
Diese Limits gelten für die REST-API (Endpunkte unter /api/external/v1/):
| Tarif | Anfragen/Minute | Anfragen/Monat |
|---|---|---|
| Pro | 30 | 10.000 |
| Scale | 60 | 100.000 |
| Enterprise | 120 | 1.000.000 |
Limits werden anhand des Abonnements Ihres Teams aufgelöst. Wenn Sie mehreren Teams angehören, verwendet die API den höchsten Tarif, dem Sie angehören.
Was als Anfrage zählt
Jeder authentifizierte API-Aufruf zählt als eine Anfrage gegen Ihr monatliches Kontingent — die Lese-Endpunkte (GET) und der Abfrage-Endpunkt (POST /query/:websiteId). Die REST-API ist schreibgeschützt; es gibt keine PUT-, PATCH- oder DELETE-Endpunkte.
Was nicht zählt
Anfragen, die die Authentifizierung nicht bestehen (401, z. B. ein fehlender oder ungültiger Schlüssel), zählen nicht zu Ihrem Kontingent, da der Schlüssel nie validiert wird.
Rate-Limit-Header
Antwort-Header
Jede API-Antwort enthält Nutzungs-Header:
X-RateLimit-Limit: 30
X-Usage-Monthly: 4521
X-Usage-Limit: 10000
X-Usage-Reset: 2026-07-01T00:00:00.000Z
X-Usage-Total: 89234
| Header | Beschreibung |
|---|---|
| X-RateLimit-Limit | Ihr Anfragelimit pro Minute |
| X-RateLimit-Remaining | Verbleibende Anfragen in dieser Minute (nicht immer vorhanden — siehe unten) |
| X-Usage-Monthly | In diesem Monat verwendete Anfragen |
| X-Usage-Limit | Monatliches Anfragelimit |
| X-Usage-Reset | Zeitpunkt der monatlichen Zurücksetzung (ISO 8601) |
| X-Usage-Total | Gesamtzahl der mit diesem Schlüssel getätigten Anfragen |
X-RateLimit-Remaining wird nur einbezogen, wenn eine genaue verbleibende Anzahl verfügbar ist; behandeln Sie dessen Abwesenheit als normal und verlassen Sie sich auf X-RateLimit-Limit plus Ihre eigene Anfragezählung zur Budgetplanung.
Header auslesen
const response = await fetch(url, { headers });
const limit = response.headers.get('X-RateLimit-Limit');
const remaining = response.headers.get('X-RateLimit-Remaining'); // kann null sein — siehe Hinweis oben
const monthlyReset = response.headers.get('X-Usage-Reset'); // ISO 8601-Zeitstempel
console.log(`${remaining ?? '?'}/${limit} Anfragen in dieser Minute verbleibend`);
console.log(`Monatliche Nutzung setzt sich am ${monthlyReset} zurück`);
Rate Limit überschritten
Antwort
Wenn das Limit pro Minute überschritten wird:
HTTP/1.1 429 Too Many Requests
Retry-After: 42
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded (30 requests/minute). Try again in 42 seconds",
"timestamp": "2026-06-13T12:00:00.000Z"
}
}
Das Pro-Minute-429 enthält einen Retry-After-Header (in Sekunden), der Ihnen mitteilt, wie lange Sie warten müssen, bevor Sie erneut versuchen.
Wenn das monatliche Kontingent überschritten wird, verwendet der Fehlertext die gleiche Form mit "code": "MONTHLY_LIMIT_EXCEEDED". Diese Antwort enthält keinen Retry-After-Header — überprüfen Sie stattdessen den X-Usage-Reset-Header, der Ihnen mitteilt, wann Ihre monatliche Zuteilung zurückgesetzt wird (am ersten des Folgemonats).
429-Fehler behandeln
async function apiRequest(url, options, retries = 3) {
const response = await fetch(url, options);
if (response.status === 429 && retries > 0) {
const retryAfter = response.headers.get('Retry-After') || 60;
console.log(`Rate limited. Waiting ${retryAfter}s...`);
await sleep(retryAfter * 1000);
return apiRequest(url, options, retries - 1);
}
return response;
}
Best Practices
Caching
Cachen Sie Antworten, wenn möglich:
const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 Minuten
async function getWithCache(endpoint) {
const cached = cache.get(endpoint);
if (cached && Date.now() - cached.time < CACHE_TTL) {
return cached.data;
}
const response = await api.get(endpoint);
cache.set(endpoint, { data: response, time: Date.now() });
return response;
}
Fordern Sie nur an, was Sie brauchen
Verwenden Sie den range-Filter, um die zurückgegebenen Daten einzuschränken:
# Filtert auf einen bestimmten Zeitraum:
GET /api/external/v1/analytics/WEBSITE_ID?range=7d
Datumsfilter verwenden
Begrenzen Sie die zurückgegebenen Daten auf bestimmte Zeiträume (unterstützte Werte: 24h, 7d, 30d, 90d, 1y):
# Nur die letzten 30 Tage abrufen:
GET /api/external/v1/analytics/WEBSITE_ID?range=30d
Paginierung
Der Besucherendpunkt paginiert mit limit und offset (keine Seitennummern). limit hat einen Standardwert von 100 und ist auf 1000 begrenzt.
Anfrage
GET /api/external/v1/analytics/WEBSITE_ID/visitors?range=30d&limit=100&offset=0
Antwort
{
"success": true,
"data": {
"visitors": [...],
"pagination": {
"limit": 100,
"offset": 0,
"has_more": true
}
},
"timestamp": "2026-06-13T12:00:00.000Z"
}
Effiziente Paginierung
Fordern Sie weiter Seiten an, bis has_more false ist, erhöhen Sie offset um limit jedes Mal:
async function getAllVisitors(websiteId) {
let allVisitors = [];
let offset = 0;
const limit = 100;
let hasMore = true;
while (hasMore) {
const response = await api.get(
`/analytics/${websiteId}/visitors?limit=${limit}&offset=${offset}`
);
const { visitors, pagination } = response.data;
allVisitors = allVisitors.concat(visitors);
hasMore = pagination.has_more;
offset += limit;
// Rate Limits respektieren
await sleep(100);
}
return allVisitors;
}
Exponentielles Backoff
Implementierung
async function requestWithBackoff(fn, maxRetries = 5) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fn();
} catch (error) {
if (error.status === 429 && attempt < maxRetries - 1) {
const delay = Math.pow(2, attempt) * 1000 + Math.random() * 1000;
console.log(`Retry ${attempt + 1} after ${delay}ms`);
await sleep(delay);
} else {
throw error;
}
}
}
}
Backoff-Zeitplan
| Versuch | Wartezeit |
|---|---|
| 1 | 1–2 Sekunden |
| 2 | 2–4 Sekunden |
| 3 | 4–8 Sekunden |
| 4 | 8–16 Sekunden |
| 5 | 16–32 Sekunden |
Nutzung überwachen
Aktuelle Nutzung prüfen
curl https://api.zenovay.com/api/external/v1/usage \
-H "X-API-Key: zv_YOUR_API_KEY"
Dies gibt Ihre aktuelle monatliche Anfragenzahl, verbleibendes Kontingent, Pro-Minute-Rate-Limit und Abonnementtarif zurück.
Jede API-Antwort enthält auch Ihre Live-Nutzung in Headern (X-Usage-Monthly, X-Usage-Limit, X-Usage-Reset), sodass Sie den Verbrauch ohne einen separaten Anruf verfolgen können.
Im Dashboard
Öffnen Sie API-Schlüssel (app.zenovay.com/api-keys), um Ihre Schlüssel und die Anfragezahlen sowie die jüngsten Aktivitäten für jeden Schlüssel anzusehen. Verwenden Sie den obigen GET /usage-Endpunkt für die genaue monatliche Anzahl und verbleibendes Kontingent.
Optimierung bei hohem Anfragevolumen
Aggregierte Endpunkte verwenden
Verwenden Sie den Analytics-Übersichtsendpunkt, um zusammenfassende Gesamtwerte in einem Aufruf zu erhalten, anstatt mehrere Raw-Besucherdatensätze durchzublättern:
# Ein Aufruf für Analytics-Übersicht:
GET /api/external/v1/analytics/WEBSITE_ID?range=30d
Dies gibt einen summary-Block (Gesamtbesucher, Seitenaufrufe, eindeutige Besucher) plus daily_stats in einer Antwort zurück. Für geografische, Seiten- oder Geräte-Aufschlüsselungen verwenden Sie die dedizierten Endpunkte /countries, /pages und /technology.
Enterprise Rate Limits
Enterprise PlanEnterprise-Tarife beginnen mit den höchsten veröffentlichten Limits (120 Anfragen/Minute, 1.000.000 Anfragen/Monat). Wenn Sie höhere Limits benötigen, senden Sie eine E-Mail an [email protected] mit:
- Ihren aktuellen Nutzungsmustern
- Erwartetem Wachstum
- Ihren Anwendungsfalldetails
Fehlerbehebung
Häufig Rate-Limited
Wenn Sie das Pro-Minute-Limit oft erreichen:
- Fügen Sie Verzögerungen zwischen Anfragen hinzu (oder eine Anfragewarteschlange)
- Verwenden Sie exponentielles Backoff auf 429s
- Cachen Sie Antworten, die Sie wiederverwenden
- Verwenden Sie aggregierte Endpunkte statt vieler kleiner Aufrufe
- Upgraden Sie Ihren Tarif für ein höheres Limit
Monatliches Kontingent aufgebraucht
Ein MONTHLY_LIMIT_EXCEEDED (429) bedeutet, dass Sie Ihr monatliches Anfragekontingent aufgebraucht haben. Es setzt sich am ersten des Folgemonats zurück (siehe den X-Usage-Reset-Header). Upgraden Sie Ihren Tarif für ein höheres monatliches Kontingent.
Unerwartet niedrige Limits
Wenn Ihre Limits falsch erscheinen:
- Überprüfen Sie Ihre Tarifstufe — Limits basieren auf dem Abonnement Ihres Teams
- Bestätigen Sie, dass Sie einen Schlüssel aus dem richtigen Team verwenden
- Wenden Sie sich an den Support