Limitation de débit
Limitation de débit de l'API The Trade Hub - en-têtes de réponse, gestion des erreurs 429 et stratégie de backoff exponentiel.
L'API The Trade Hub applique une limitation de débit (rate limiting) pour garantir la disponibilité et l'équité du service. La limite est configurable par clé API.
En-têtes de réponse
Chaque réponse de l'API inclut des en-têtes indiquant votre consommation courante :
| En-tête | Description |
|---|---|
X-RateLimit-Limit | Nombre maximum de requêtes autorisées par minute |
X-RateLimit-Remaining | Nombre de requêtes restantes dans la fenêtre courante |
Retry-After | Nombre de secondes avant de pouvoir réessayer (uniquement sur les réponses 429) |
Exemple d'en-têtes
HTTP/1.1 200 OK
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 47
Content-Type: application/jsonLimites par défaut
L'API utilise des buckets séparés pour les requêtes d'écriture et de lecture :
| Paramètre | Valeur |
|---|---|
| Ecritures par minute (POST, PUT, PATCH, DELETE) | 10 (opérations LLM, chaque SSE reste ouvert ~90s) |
| Lectures par minute (GET) | 60 (polling, vérification de statut) |
| Lot max | 1 000 éléments (10 Mo max) |
| Payload max (classement) | 1 Mo |
Un appel batch compte comme une seule requête d'écriture. La limite par clé API peut être abaissée (mais pas augmentée) depuis le tableau de bord développeur.
Réponse 429 (Too Many Requests)
Lorsque la limite est atteinte, l'API retourne une erreur 429 Too Many Requests avec un en-tête Retry-After :
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"
}Le Retry-After indique le nombre de secondes restantes avant la réinitialisation de la fenêtre.
Gestion du rate limiting
Stratégie recommandée : backoff exponentiel
Lorsque vous recevez une réponse 429, attendez la durée indiquée par Retry-After avant de réessayer. Si l'en-tête est absent, utilisez un backoff exponentiel :
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
# Respecter Retry-After si présent
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 limited. Nouvelle tentative dans {wait}s (tentative {attempt + 1}/{max_retries})")
time.sleep(wait)
raise Exception("Nombre maximum de tentatives atteint")
client = httpx.Client(
base_url="https://api.thetradehub.eu",
headers={"X-API-Key": "th_live_votre_cle_api"},
)
response = request_with_retry(client, "POST", "/v1/classify/jobs", json={
"content": "Casque audio Bluetooth"
})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;
}
// Respecter Retry-After si présent
const retryAfter = response.headers.get("Retry-After");
const wait = retryAfter ? parseInt(retryAfter) * 1000 : delay;
delay = Math.min(delay * 2, 60000);
console.log(`Rate limited. Nouvelle tentative dans ${wait / 1000}s (tentative ${attempt + 1}/${maxRetries})`);
await new Promise((r) => setTimeout(r, wait));
}
throw new Error("Nombre maximum de tentatives atteint");
}
const response = await requestWithRetry(
"https://api.thetradehub.eu/v1/classify/jobs",
{
method: "POST",
headers: {
"X-API-Key": "th_live_votre_cle_api",
"Content-Type": "application/json",
},
body: JSON.stringify({ content: "Casque audio Bluetooth" }),
}
);Facturation
L'API utilise un modèle pay-per-use sans quota fixe. Chaque classification réussie (SH ou export control) est facturée a l'unité avec une tarification graduée :
| Palier (unités/mois) | Prix |
|---|---|
| 1 - 100 | 0,75 EUR/unité |
| 101 - 1 000 | 0,55 EUR/unité |
| 1 001 - 10 000 | 0,40 EUR/unité |
| 10 001 - 50 000 | 0,30 EUR/unité |
| 50 001+ | 0,25 EUR/unité |
Les volumes mensuels de classement douanier et export control sont agrégés pour le calcul du palier. Les déclarations (import, export, transit) utilisent un tarif fixe de 1,50 EUR/unité.
Seules les classifications terminées avec succes sont facturées. Les échecs et les retries ne generent aucun cout.
Modes de facturation
| Mode | Description |
|---|---|
| Balance (prépayé) | Crédits déduits en temps réel. Recharge manuelle ou automatique. |
| Invoice (enterprise) | Facturation mensuelle net-30. Plafond de dépenses configurable. |
Si le solde de crédits atteint zéro (balance) ou le plafond est atteint (invoice), l'API retourne une erreur 402 Payment Required.
Bonnes pratiques
Surveillez vos en-têtes
Vérifiez X-RateLimit-Remaining après chaque requête. Si la valeur approche de zéro, ralentissez proactivement vos appels.
Utilisez le classement par lot
Pour traiter plusieurs produits, privilégiez l'endpoint batch plutôt que des appels unitaires en série. Un appel batch compte comme une seule requête vers le rate limiter.
Espacez vos requêtes
Si vous traitez un grand volume, répartissez vos requêtes uniformément dans le temps plutôt que de les envoyer en rafale.
Mettez en cache les résultats
Stockez les résultats de classement côté client pour éviter de classer le même produit plusieurs fois. Consultez l'endpoint historique pour retrouver un classement passe.
Ne réessayez jamais immédiatement
Réessayer immédiatement après un 429 aggrave la situation. Respectez toujours le délai Retry-After ou appliquez un backoff exponentiel.
Dernière mise à jour