Rate Limiting
The Trade Hub API Rate Limiting – Antwort-Header, Umgang mit 429-Fehlern und exponentielle Backoff-Strategie.
Die Trade Hub API setzt eine Rate Limitierung durch, um die Verfügbarkeit des Dienstes und Fairness sicherzustellen. Das Limit ist pro API-Schlüssel konfigurierbar.
Antwort-Header
Jede API-Antwort enthält Header, die Ihre aktuelle Nutzung anzeigen:
| Header | Beschreibung |
|---|---|
X-RateLimit-Limit | Maximale Anzahl an Anfragen pro Minute |
X-RateLimit-Remaining | Verbleibende Anzahl an Anfragen im aktuellen Zeitraum |
Retry-After | Anzahl der Sekunden, die vor einem erneuten Versuch gewartet werden muss (nur bei 429-Antworten) |
Beispiel-Header
HTTP/1.1 200 OK
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 47
Content-Type: application/jsonStandardlimits
Die API verwendet getrennte Buckets für Schreib- und Leseanfragen:
| Parameter | Wert |
|---|---|
| Schreibanfragen pro Minute (POST, PUT, PATCH, DELETE) | 10 (LLM-Operationen, jede SSE bleibt ca. 90s offen) |
| Leseanfragen pro Minute (GET) | 60 (Polling, Statusabfragen) |
| Maximale Batch-Größe | 1.000 Elemente (max. 10 MB) |
| Maximale Nutzlast (Klassifizierung) | 1 MB |
Ein Batch-Aufruf zählt als eine Schreibanfrage. Das Limit pro Schlüssel kann im Entwickler-Dashboard gesenkt (aber nicht erhöht) werden.
429-Antwort (Too Many Requests)
Wenn das Limit erreicht ist, gibt die API einen 429 Too Many Requests Fehler mit einem Retry-After-Header zurück:
HTTP/1.1 429 Too Many Requests
Retry-After: 42
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
Content-Type: application/json
{
"detail": "rate limit exceeded"
}Der Wert von Retry-After gibt die verbleibenden Sekunden bis zum Zurücksetzen des Zeitfensters an.
Umgang mit Rate Limits
Empfohlene Strategie: exponentieller Backoff
Wenn Sie eine 429-Antwort erhalten, warten Sie die im Retry-After-Header angegebene Dauer, bevor Sie es erneut versuchen. Ist der Header nicht vorhanden, verwenden Sie exponentiellen Backoff:
import httpx
import time
def request_with_retry(client: httpx.Client, method: str, url: str, max_retries: int = 5, **kwargs):
delay = 1
for attempt in range(max_retries):
response = client.request(method, url, **kwargs)
if response.status_code != 429:
return response
# Retry-After respektieren, falls vorhanden
retry_after = response.headers.get("Retry-After")
if retry_after:
wait = int(retry_after)
else:
wait = delay
delay = min(delay * 2, 60)
print(f"Rate limit erreicht. Neuer Versuch in {wait}s (Versuch {attempt + 1}/{max_retries})")
time.sleep(wait)
raise Exception("Maximale Anzahl an Versuchen überschritten")
client = httpx.Client(
base_url="https://api.thetradehub.eu",
headers={"X-API-Key": "th_live_your_api_key"},
)
response = request_with_retry(client, "POST", "/v1/classify/jobs", json={
"content": "Wireless Bluetooth headphones"
})async function requestWithRetry(url, options, maxRetries = 5) {
let delay = 1000;
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.status !== 429) {
return response;
}
// Retry-After respektieren, falls vorhanden
const retryAfter = response.headers.get("Retry-After");
const wait = retryAfter ? parseInt(retryAfter) * 1000 : delay;
delay = Math.min(delay * 2, 60000);
console.log(`Rate limit erreicht. Neuer Versuch in ${wait / 1000}s (Versuch ${attempt + 1}/${maxRetries})`);
await new Promise((r) => setTimeout(r, wait));
}
throw new Error("Maximale Anzahl an Versuchen überschritten");
}
const response = await requestWithRetry(
"https://api.thetradehub.eu/v1/classify/jobs",
{
method: "POST",
headers: {
"X-API-Key": "th_live_your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({ content: "Wireless Bluetooth headphones" }),
}
);Abrechnung
Die API verwendet ein Pay-per-Use-Modell ohne feste Kontingente. Jede erfolgreiche Klassifizierung (HS oder Exportkontrolle) wird pro Einheit mit gestaffelten Preisen abgerechnet:
| Stufe (Einheiten/Monat) | Preis |
|---|---|
| 1 - 100 | 0,75 EUR/Einheit |
| 101 - 1.000 | 0,55 EUR/Einheit |
| 1.001 - 10.000 | 0,40 EUR/Einheit |
| 10.001 - 50.000 | 0,30 EUR/Einheit |
| 50.001+ | 0,25 EUR/Einheit |
Monatliche Volumina für Zolltarifeinreihung und Exportkontrolle werden für die Stufenberechnung zusammengefasst. Zollanmeldungen (Import, Export, Versandverfahren) werden mit einem Pauschalpreis von 1,50 EUR/Einheit berechnet.
Nur erfolgreich abgeschlossene Klassifizierungen werden berechnet. Fehler und Wiederholungen verursachen keine Kosten.
Abrechnungsmodi
| Modus | Beschreibung |
|---|---|
| Guthaben (Prepaid) | Gutschriften werden in Echtzeit abgezogen. Manuelle oder automatische Aufladung. |
| Rechnung (Enterprise) | Monatliche Netto-30-Tage-Rechnung. Konfigurierbares Ausgabenlimit. |
Erreicht das Guthaben Null (Guthaben-Modus) oder das Ausgabenlimit (Rechnungs-Modus), gibt die API einen 402 Payment Required Fehler zurück.
Best Practices
Überwachen Sie Ihre Header
Prüfen Sie nach jeder Anfrage den Wert von X-RateLimit-Remaining. Wenn der Wert gegen Null geht, reduzieren Sie proaktiv Ihre Anfragenrate.
Nutzen Sie Batch-Klassifizierung
Um mehrere Produkte zu verarbeiten, verwenden Sie bevorzugt den Batch-Endpunkt statt sequentieller Einzelaufrufe. Ein Batch-Aufruf zählt als eine einzelne Anfrage für die Rate Limitierung.
Verteilen Sie Ihre Anfragen
Bei hohen Volumina verteilen Sie Ihre Anfragen gleichmäßig über die Zeit, anstatt sie in kurzen Zeiträumen zu senden.
Zwischenspeicherung von Ergebnissen
Speichern Sie Klassifizierungsergebnisse clientseitig, um dieselben Produkte nicht mehrfach klassifizieren zu müssen. Verwenden Sie den History-Endpunkt, um vergangene Klassifizierungen abzurufen.
Niemals sofort erneut versuchen
Ein sofortiger Wiederholungsversuch nach einem 429 verschlimmert die Situation. Respektieren Sie immer die Retry-After-Verzögerung oder wenden Sie exponentiellen Backoff an.
Last updated on