Zum Hauptinhalt springen
Pro Plan5 minutesFortgeschrittene

Rate Limits & Best Practices

API-Rate-Limits verstehen – Kontingente, Header und Strategien für eine effiziente API-Nutzung.

apirate-limitsperformancebest-practices
Zuletzt aktualisiert:
Pro Plan

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/):

TarifAnfragen/MinuteAnfragen/Monat
Pro3010.000
Scale60100.000
Enterprise1201.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
HeaderBeschreibung
X-RateLimit-LimitIhr Anfragelimit pro Minute
X-RateLimit-RemainingVerbleibende Anfragen in dieser Minute (nicht immer vorhanden — siehe unten)
X-Usage-MonthlyIn diesem Monat verwendete Anfragen
X-Usage-LimitMonatliches Anfragelimit
X-Usage-ResetZeitpunkt der monatlichen Zurücksetzung (ISO 8601)
X-Usage-TotalGesamtzahl 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

VersuchWartezeit
11–2 Sekunden
22–4 Sekunden
34–8 Sekunden
48–16 Sekunden
516–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 Plan

Enterprise-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:

  1. Fügen Sie Verzögerungen zwischen Anfragen hinzu (oder eine Anfragewarteschlange)
  2. Verwenden Sie exponentielles Backoff auf 429s
  3. Cachen Sie Antworten, die Sie wiederverwenden
  4. Verwenden Sie aggregierte Endpunkte statt vieler kleiner Aufrufe
  5. 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:

  1. Überprüfen Sie Ihre Tarifstufe — Limits basieren auf dem Abonnement Ihres Teams
  2. Bestätigen Sie, dass Sie einen Schlüssel aus dem richtigen Team verwenden
  3. Wenden Sie sich an den Support

Nächste Schritte

War dieser Artikel hilfreich?