Rate Limits
Die durchgesetzten Rate-Limit-Schichten, die für Clients sichtbaren Header und Hinweise zur 429-Behandlung
Die API setzt mehrere Limits nacheinander durch. Jedes kann 429 zurückgeben. Diese Seite listet sie auf und zeigt, wie Sie zurückfahren.
Durchgesetzte Schichten
| Schicht | Standard | Bei Überschreitung |
|---|---|---|
| Pro IP | 20 Anfragen/Sekunde, Burst 40 | 429 |
| RPM pro Schlüssel | 20 Anfragen/Minute, gleitendes 60s-Fenster | 429 mit Retry-After: 60 |
| Concurrency pro Schlüssel | 5 gleichzeitige Anfragen | 429 Concurrent request limit exceeded mit Retry-After: 5 |
| Agent-Slots | 2 Slots | 403 bei 0 Slots, 429 über dem Limit |
| Budget | 50 EUR Monatsbudget (api-Schlüssel) | 429 mit X-Budget-Remaining: 0 |
| Kontextlimit | 800000 Zeichen (etwa 200k Token) | 413 |
Die Werte für RPM, Concurrency, Slot und Budget pro Schlüssel sind die aktuellen Standardwerte. Um sie anzuheben, siehe Kontolimits.
Für Clients sichtbare Header
Jede /v1/*-Antwort trägt die Rate-Limit-Header. Retry-After wird bei 429 und 503 hinzugefügt.
| Header | Bedeutung |
|---|---|
X-RateLimit-Limit | Limit gleichzeitiger Anfragen (siehe Hinweis unten) |
X-RateLimit-Remaining | Verbleibende Kapazität |
X-RateLimit-Reset | Wann das Fenster zurückgesetzt wird |
Retry-After | Wartezeit in Sekunden vor dem erneuten Versuch |
X-RateLimit-Limit gibt derzeit das Limit gleichzeitiger Anfragen wieder, nicht Anfragen pro Minute. Lesen Sie es nicht als RPM.
429 behandeln
Wenn Sie ein 429 erhalten:
- Ist
Retry-Aftervorhanden, warten Sie diese Anzahl Sekunden und wiederholen Sie dann. - Andernfalls fahren Sie exponentiell mit Jitter zurück.
Wiederholen Sie 400, 401, 403 oder 422 nicht. Das sind Client-Fehler, und ein erneuter Versuch schlägt auf dieselbe Weise fehl. Siehe Fehler für die Statustabelle.
Beispiel-Backoff
import time, random
def call_with_retry(do_request, max_attempts=5):
for attempt in range(max_attempts):
resp = do_request()
if resp.status_code != 429:
return resp
retry_after = resp.headers.get("Retry-After")
if retry_after is not None:
time.sleep(float(retry_after))
else:
time.sleep((2 ** attempt) + random.random())
return resp