Classement par lot
Endpoint de classement par lot - classifiez jusqu'à 1 000 produits en une seule requête avec suivi d'avancement.
L'endpoint de classement par lot permet de classer jusqu'à 1 000 produits en une seule requête. Comme pour le classement unitaire, le traitement est asynchrone avec un suivi d'avancement en temps réel.
Créer un lot de classement
POST
/v1/classify/batchParamètres du corps (JSON)
| Paramètre | Type | Requis | Description |
|---|---|---|---|
items | object[] | Oui | Liste des produits à classer (1 à 1 000) |
items[].id | string | Non | Identifiant personnalisé pour corréler les résultats |
items[].content | string | Oui | Description du produit |
items[].image_urls | string[] | Non | URLs d'images du produit |
locale | "fr" | "en" | "es" | Non | Langue des réponses (défaut : "fr") |
Exemple de requête
curl -X POST https://api.thetradehub.eu/v1/classify/batch \
-H "X-API-Key: th_live_votre_cle_api" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"id": "SKU-001",
"content": "Casque audio Bluetooth sans fil avec réduction de bruit"
},
{
"id": "SKU-002",
"content": "T-shirt en coton biologique pour homme, taille L"
},
{
"id": "SKU-003",
"content": "Huile d olive extra vierge, bouteille en verre 750ml, origine Espagne"
}
],
"locale": "fr"
}'import httpx
client = httpx.Client(
base_url="https://api.thetradehub.eu",
headers={"X-API-Key": "th_live_votre_cle_api"},
)
response = client.post("/v1/classify/batch", json={
"items": [
{"id": "SKU-001", "content": "Casque audio Bluetooth sans fil avec réduction de bruit"},
{"id": "SKU-002", "content": "T-shirt en coton biologique pour homme, taille L"},
{"id": "SKU-003", "content": "Huile d'olive extra vierge, bouteille en verre 750ml, origine Espagne"},
],
"locale": "fr",
})
batch = response.json()
print(f"Lot créé : {batch['id']} - {batch['total']} produits")const response = await fetch("https://api.thetradehub.eu/v1/classify/batch", {
method: "POST",
headers: {
"X-API-Key": "th_live_votre_cle_api",
"Content-Type": "application/json",
},
body: JSON.stringify({
items: [
{ id: "SKU-001", content: "Casque audio Bluetooth sans fil avec réduction de bruit" },
{ id: "SKU-002", content: "T-shirt en coton biologique pour homme, taille L" },
{ id: "SKU-003", content: "Huile d'olive extra vierge, bouteille en verre 750ml, origine Espagne" },
],
locale: "fr",
}),
});
const batch = await response.json();
console.log(`Lot créé : ${batch.id} - ${batch.total} produits`);Réponse (202 Accepted)
{
"id": "batch_f1e2d3c4-b5a6-7890-abcd-ef1234567890",
"status": "processing",
"total": 3,
"completed": 0,
"failed": 0,
"progress": 0,
"created_at": "2026-02-24T10:30:00Z",
"updated_at": "2026-02-24T10:30:00Z"
}Obtenir le statut d'un lot
GET
/v1/classify/batch/{batch_id}Paramètres de chemin
| Paramètre | Type | Description |
|---|---|---|
batch_id | string (UUID) | Identifiant du lot retourné à la création |
Statuts possibles
| Statut | Description |
|---|---|
processing | Le lot est en cours de traitement |
completed | Tous les éléments ont été traités |
partial | Le lot est terminé mais certains éléments ont échoué |
failed | Le lot entier a échoué |
Exemple de polling
curl https://api.thetradehub.eu/v1/classify/batch/batch_f1e2d3c4-b5a6-7890-abcd-ef1234567890 \
-H "X-API-Key: th_live_votre_cle_api"import httpx
import time
client = httpx.Client(
base_url="https://api.thetradehub.eu",
headers={"X-API-Key": "th_live_votre_cle_api"},
)
batch_id = "batch_f1e2d3c4-b5a6-7890-abcd-ef1234567890"
delay = 2
while True:
response = client.get(f"/v1/classify/batch/{batch_id}")
batch = response.json()
print(f"Progression : {batch['progress'] * 100:.0f}% ({batch['completed']}/{batch['total']})")
if batch["status"] in ("completed", "partial"):
for item in batch["items"]:
if item["status"] == "completed":
hs = item["result"]["classification"]["rankings"][0]["hs_code"]
print(f" {item['id']} → {hs}")
else:
print(f" {item['id']} → Erreur : {item.get('error')}")
break
elif batch["status"] == "failed":
print(f"Erreur lot : {batch.get('error')}")
break
time.sleep(delay)
delay = min(delay * 1.5, 10)const API_KEY = "th_live_votre_cle_api";
const batchId = "batch_f1e2d3c4-b5a6-7890-abcd-ef1234567890";
async function pollBatch(batchId) {
let delay = 2000;
while (true) {
const response = await fetch(
`https://api.thetradehub.eu/v1/classify/batch/${batchId}`,
{ headers: { "X-API-Key": API_KEY } }
);
const batch = await response.json();
console.log(`Progression : ${Math.round(batch.progress * 100)}% (${batch.completed}/${batch.total})`);
if (batch.status === "completed" || batch.status === "partial") {
for (const item of batch.items) {
if (item.status === "completed") {
const hs = item.result.classification.rankings[0].hs_code;
console.log(` ${item.id} → ${hs}`);
} else {
console.log(` ${item.id} → Erreur : ${item.error}`);
}
}
return batch;
}
if (batch.status === "failed") {
throw new Error(batch.error);
}
await new Promise((r) => setTimeout(r, delay));
delay = Math.min(delay * 1.5, 10000);
}
}
const result = await pollBatch(batchId);Réponse complète (status: completed)
Chaque élément contient la même structure de résultat que le classement unitaire.
{
"id": "batch_f1e2d3c4-b5a6-7890-abcd-ef1234567890",
"status": "completed",
"total": 3,
"completed": 3,
"failed": 0,
"progress": 1.0,
"items": [
{
"id": "SKU-001",
"status": "completed",
"result": {
"classification": {
"rankings": [
{
"rank": 1,
"hs_code": "8518.30.00",
"description": "Ecouteurs et casques",
"confidence": 0.94,
"gri_justification": "GRI 1 - Position 8518 couvre nommément les casques et écouteurs.",
"validated": true
}
]
},
"text": "D'apres les décisions BTI de l'UE et la nomenclature TARIC...",
"session_id": "sess_abc123"
}
},
{
"id": "SKU-002",
"status": "completed",
"result": {
"classification": {
"rankings": [
{
"rank": 1,
"hs_code": "6109.10.00",
"description": "T-shirts et maillots de corps en coton",
"confidence": 0.97,
"gri_justification": "GRI 1 - Le produit est un t-shirt en coton, nommément couvert par la position 6109.",
"validated": true
}
]
},
"text": "Classement en position 6109 pour les articles en bonneterie...",
"session_id": "sess_def456"
}
},
{
"id": "SKU-003",
"status": "completed",
"result": {
"classification": {
"rankings": [
{
"rank": 1,
"hs_code": "1509.10.90",
"description": "Huile d'olive vierge",
"confidence": 0.96,
"gri_justification": "GRI 1 - Position 1509 couvre l'huile d'olive. Sous-position 1509.10 : huile vierge.",
"validated": true
}
]
},
"text": "Classement en position 1509 pour les huiles d'olive...",
"session_id": "sess_ghi789"
}
}
],
"created_at": "2026-02-24T10:30:00Z",
"updated_at": "2026-02-24T10:30:45Z"
}Structure de la réponse
| Champ | Type | Description |
|---|---|---|
id | string | Identifiant unique du lot |
status | string | Statut global du lot |
total | number | Nombre total d'éléments |
completed | number | Nombre d'éléments traités avec succès |
failed | number | Nombre d'éléments en erreur |
progress | number | Ratio d'avancement (0.0 à 1.0) |
items | object[] | Résultats par élément - structure identique au classement unitaire |
Résultats persistants
Les résultats sont accessibles en permanence via le même endpoint :
GET /v1/classify/batch/{batch_id}- Pendant le traitement / 24 premieres heures - servi depuis le cache, progression en temps réel
- Apres 24h - basculement transparent vers la base de données, résultats toujours disponibles
Aucun stockage client nécessaire. Récupérez n'importe quel batch passé avec son batch_id d'origine.
Bonnes pratiques
| Recommandation | Détail |
|---|---|
| Taille de lot | Maximum 1 000 éléments par requête (10 Mo max) |
| Polling | Intervalle de 2s au départ, augmenter progressivement |
| Identifiants | Utilisez items[].id pour corréler avec vos données |
| Gestion des erreurs partielles | Vérifiez status de chaque élément dans items |
| Timeout | Prévoir 30s + 5s par élément pour les gros lots |
| Stockage des résultats | Non nécessaire - résultats accessibles en permanence via batch_id |
Dernière mise à jour