Traitement par lots avec l'API BCE/KBO : guide pratique
Comment traiter des milliers d'entreprises efficacement ? Guide complet sur le batch processing avec l'API BCE/KBO : import, validation et enrichissement en masse.
En bref
Le traitement par lots avec l'API BCE/KBO permet de valider, enrichir ou nettoyer des milliers de fiches entreprises en une seule passe. La stratégie repose sur trois briques : la normalisation des numéros BCE, une queue de concurrence limitée à 5-10 appels simultanés pour respecter le rate limiting, et l'export des résultats en CSV. Idéal pour les migrations CRM, la due diligence fournisseurs ou la prospection B2B en Belgique.
Pourquoi le traitement par lots ?
De nombreux cas d'usage nécessitent le traitement de grandes quantités de données entreprises :
- Migration CRM : importer et enrichir des milliers de fiches clients
- Nettoyage de base : valider et corriger les données existantes
- Due diligence : vérifier un portefeuille de fournisseurs
- Prospection : enrichir une liste de prospects B2B
Architecture recommandée
1 2 3 4 5 6 7 8 9
┌──────────────┐ ┌───────────────┐ ┌──────────────┐
│ Fichier CSV │────▶│ Worker Queue │────▶│ API BCE/KBO │
│ ou Base DB │ │ (Bull/Redis) │ │ │
└──────────────┘ └───────┬───────┘ └──────────────┘
│
┌───────▼───────┐
│ Résultats │
│ enrichis │
└───────────────┘
Étape 1 : Préparer vos données
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
import { parse } from class="code-string">'csv-parse/sync';
import fs from class="code-string">'fs';
interface CompanyInput {
name: string;
bceNumber?: string;
vatNumber?: string;
}
class="code-comment">// Lire et parser le fichier CSV
const csvContent = fs.readFileSync(class="code-string">'companies.csv', class="code-string">'utf-8');
const companies: CompanyInput[] = parse(csvContent, {
columns: true,
skip_empty_lines: true,
});
console.log(class="code-string">`${companies.length} entreprises à traiter`);
Étape 2 : Normaliser les numéros BCE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
function normalizeBceNumber(input: string): string | null {
class="code-comment">// Supprimer tous les caractères non numériques
const digits = input.replace(/\D/g, class="code-string">'');
class="code-comment">// Un numéro BCE a 10 chiffres
if (digits.length === 10) {
return class="code-string">`${digits.slice(0, 4)}.${digits.slice(4, 7)}.${digits.slice(7)}`;
}
class="code-comment">// Certains omettent le 0 initial
if (digits.length === 9) {
return class="code-string">`0${digits.slice(0, 3)}.${digits.slice(3, 6)}.${digits.slice(6)}`;
}
return null; class="code-comment">// Format invalide
}
Étape 3 : File d'attente avec contrôle de débit
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
async function processBatch(
companies: CompanyInput[],
concurrency = 5,
delayMs = 200
) {
const results = [];
const errors = [];
for (let i = 0; i < companies.length; i += concurrency) {
const batch = companies.slice(i, i + concurrency);
const promises = batch.map(async (company) => {
try {
const bceNumber = company.bceNumber
? normalizeBceNumber(company.bceNumber)
: null;
if (!bceNumber) {
class="code-comment">// Recherche par nom
const res = await fetch(
class="code-string">`https:class="code-comment">//companybelgium.be/api/companies/search?q=${encodeURIComponent(company.name)}&limit=1`,
{ headers: { class="code-string">'X-API-Key': apiKey, class="code-string">'X-API-Secret': apiSecret } }
);
return { input: company, result: await res.json(), matched: true };
}
class="code-comment">// Recherche par numéro BCE
const res = await fetch(
class="code-string">`https:class="code-comment">//companybelgium.be/api/companies/${bceNumber}`,
{ headers: { class="code-string">'X-API-Key': apiKey, class="code-string">'X-API-Secret': apiSecret } }
);
return { input: company, result: await res.json(), matched: true };
} catch (error) {
return { input: company, error, matched: false };
}
});
const batchResults = await Promise.all(promises);
results.push(...batchResults.filter(r => r.matched));
errors.push(...batchResults.filter(r => !r.matched));
class="code-comment">// Respecter le rate limit
if (i + concurrency < companies.length) {
await new Promise(resolve => setTimeout(resolve, delayMs));
}
class="code-comment">// Log progression
console.log(class="code-string">`Progression : ${Math.min(i + concurrency, companies.length)}/${companies.length}`);
}
return { results, errors };
}
Étape 4 : Export des résultats
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
import { stringify } from class="code-string">'csv-stringify/sync';
function exportResults(results: any[]) {
const rows = results.map(r => ({
input_name: r.input.name,
input_bce: r.input.bceNumber || class="code-string">'',
matched_name: r.result?.name || class="code-string">'',
matched_bce: r.result?.enterpriseNumber || class="code-string">'',
status: r.result?.status || class="code-string">'non trouvé',
legal_form: r.result?.juridicalForm || class="code-string">'',
address: r.result?.address || class="code-string">'',
}));
const csv = stringify(rows, { header: true });
fs.writeFileSync(class="code-string">'results_enriched.csv', csv);
console.log(class="code-string">'Résultats exportés dans results_enriched.csv');
}
Bonnes pratiques
| Pratique | Pourquoi |
|---|---|
| Concurrence limitée (5-10) | Respecter le rate limiting |
| Délai entre lots (200ms) | Lisser la charge |
| Normaliser les entrées | Maximiser le taux de correspondance |
| Gérer les erreurs | Ne pas bloquer tout le lot |
| Logger la progression | Suivre le traitement |
| Sauvegarder régulièrement | Reprendre en cas d'interruption |
Conclusion
Le traitement par lots est essentiel pour les projets de grande envergure. Avec une bonne gestion du débit et des erreurs, vous pouvez traiter des dizaines de milliers d'entreprises efficacement. Consultez aussi le guide d'intégration Node.js/TypeScript de l'API BCE, l'article sur l'automatisation de la vérification des fournisseurs, la page sur les rate limits et le caching et le pipeline CRM pour la prospection B2B belge.
Questions fréquentes
Combien d'entreprises belges puis-je traiter en lot avec l'API BCE/KBO par heure ?
Cela dépend de votre plan tarifaire et de votre stratégie de concurrence. Avec une concurrence de 5 appels simultanés et un délai de 200 ms entre chaque lot, vous pouvez traiter environ 1 500 entreprises par minute sur un plan Pro. Pour des volumes plus importants, optimisez le cache (évitez de requêter plusieurs fois le même numéro BCE) et utilisez le traitement par lots avec une file d'attente comme BullMQ.
Comment normaliser les numéros BCE/KBO avant un traitement en lot ?
Un numéro BCE belge contient 10 chiffres au format 0XXX.XXX.XXX. Dans vos données sources, vous trouverez souvent des variantes : sans points, avec espaces, sans le zéro initial. Nettoyez tous les caractères non numériques, vérifiez que vous obtenez 9 ou 10 chiffres, et reformatez au standard 0XXX.XXX.XXX. Cela maximise le taux de correspondance lors de la recherche dans la base BCE.
Comment reprendre un traitement par lots en cas d'interruption avec l'API BCE/KBO ?
Sauvegardez les résultats au fur et à mesure dans un fichier ou une base de données, en marquant chaque entreprise comme traitée. En cas d'interruption, filtrez les entreprises déjà traitées avant de relancer le batch. Utilisez un index de reprise basé sur le numéro BCE pour éviter les doublons et identifier rapidement où vous en êtes.
Quelle est la différence entre le traitement par lots et les webhooks pour surveiller les entreprises belges ?
Le traitement par lots est adapté aux traitements ponctuels sur un grand volume (migration, audit, enrichissement initial). Les webhooks conviennent à la surveillance en temps réel d'un portefeuille précis : Company Belgium vous notifie dès qu'une entreprise change (adresse, statut, dirigeant, NACE). Pour une veille continue, combinez les deux approches : batch initial puis webhooks pour les mises à jour.
Commentaires
Articles similaires

Expert-comptable : automatiser l'analyse financière de votre portefeuille clients
Un expert-comptable gère 50 à 300 dossiers clients. Analyser manuellement les comptes annuels, calculer les ratios, repérer les signaux d'alerte et préparer un rapport pour chaque réunion annuelle, c'est plusieurs centaines d'heures par an. Voici comment automatiser 80% de ce travail tout en gagnant en qualité de service.

Calculer la limite de crédit d'un client B2B : 4 méthodes éprouvées
Combien d'encours pouvez-vous accorder en toute sécurité à un client B2B ? Découvrez les quatre méthodes utilisées par les assureurs-crédit et les services financiers des PME belges : plafond fonds propres, plafond chiffre d'affaires, plafond actifs et scoring financier — avec exemples chiffrés.

Recherche d'entreprises belges en langage naturel : le guide complet de /recherche
Tapez « comptables à Liège », « restaurants 1000 Bruxelles » ou un numéro BCE : la barre /recherche transforme votre phrase en filtres NACE, code postal, dénomination, puis renvoie une page enrichie de statistiques sectorielles. Tour d'horizon des cas d'usage, des raccourcis URL et des subtilités linguistiques.
