CompanyBelgium

Rate limits, quotas et caching pour scaler une application BCE/KBO : architecture de référence

Votre app interroge l'API BCE/KBO en volume — comment éviter les 429, maîtriser les coûts et garantir la latence ? Architecture de référence avec cache à plusieurs niveaux, file de requêtes, observabilité et webhooks. Patterns concrets et chiffres à viser.

11 mai 20269 min de lecture

En bref

L'API BCE/KBO de Company Belgium expose des headers de rate limit lisibles par votre code. Pour scaler sans exploser votre quota, combinez un cache à 4 niveaux (CDN, mémoire, cache partagé, snapshot DB) avec des webhooks pour le suivi continu. Cette architecture absorbe 95 % du trafic avant l'API et maintient la latence sous 50 ms.

Le problème : passer de 100 à 100 000 requêtes/jour

Vous démarrez avec quelques appels par jour. Le produit grandit. Six mois plus tard, votre app fait 100 000 lookups par jour. Si vous appelez l'API à chaque page vue de chaque utilisateur, vous :

  • Saturez votre quota
  • Recevez des 429 Too Many Requests
  • Payez la note de tarif au volume
  • Augmentez la latence côté utilisateur

L'architecture de cet article empêche ça. Elle est testée en prod.

Comprendre les rate limits

Anatomie d'une fenêtre

Une API expose typiquement un quota par fenêtre glissante :

  • Plan Free : 10 req/min, 100 req/jour
  • Plan Starter : 60 req/min, 5 000 req/jour
  • Plan Pro : 600 req/min, 100 000 req/jour
  • Plan Enterprise : selon contrat

Les headers Company Belgium :

Code
1
2
3
4
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 432
X-RateLimit-Reset: 1746541234
Retry-After: 30   (seulement sur 429)
X-RateLimit-Reset est un timestamp Unix : à cette seconde, le quota repart à zéro.

Les 3 types de limites

  • Burst (req/seconde) — empêche les rafales courtes
  • Sustained (req/minute) — protège l'infra
  • Daily quota — facturation
  • Une bonne app doit gérer les trois, pas seulement le 429 ponctuel.

    Architecture de référence en 4 couches

    Code
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [ User Request ]
    
    [ Browser cache + CDN ]            ← Couche 1 (gratuit, hors quota)
    
    [ App cache mémoire (LRU TTL) ]    ← Couche 2 (10-100 ms)
    
    [ Shared cache (memcached) ]       ← Couche 3 (1-10 ms réseau)
    
    [ Database snapshot ]              ← Couche 4 (10-50 ms, fraîcheur ~24 h)
    
    [ BCE/KBO API ]                    ← Quota & coût

    L'objectif : que moins de 5 % des requêtes utilisateur tapent réellement l'API en couche 5.

    Couche 1 — CDN / Browser

    Pour les endpoints publics sans données sensibles, exposez vos routes proxy avec un Cache-Control: public, max-age=300, s-maxage=600. CloudFront, Cloudflare, Vercel Edge Network feront le reste.

    Effet typique : 50 à 70 % des requêtes sont absorbées avant même votre app.

    Couche 2 — Cache mémoire de l'application

    LRU avec TTL (vu dans le tuto Python et le tuto Node.js) :

    • Capacité : 500 à 5 000 fiches selon RAM disponible
    • TTL : 5 minutes pour la fiche, 30 minutes pour les codes NACE
    • Eviction : LRU

    Effet typique : +20 % d'absorption.

    Couche 3 — Cache partagé entre processus

    Si vous avez plusieurs instances de votre app (Docker, Kubernetes, Vercel functions), un cache local n'est pas partagé. Utilisez :

    • Memcached : simple, rapide, mode shared-nothing
    • In-cluster cache type Caffeine (Java), Tinybird (analytics)
    • Postgres avec table cache + index sur la clé (suffisant pour le volume typique d'un SaaS)

    Effet : un MISS sur l'instance A peut être un HIT sur la couche 3, mis en place par l'instance B 10 secondes avant.

    Couche 4 — Snapshot DB

    Pour les apps qui font beaucoup de lookups sur leurs propres clients (CRM, ERP, comptabilité), maintenez une copie locale des fiches BCE des entreprises que vous suivez. Synchronisée via webhooks.

    Avantages :

    • Requêtes en local : 10-50 ms
    • Pas de dépendance réseau en lecture
    • Possibilité de filtrer/grouper avec SQL

    Inconvénient :

    • Données potentiellement vieilles de quelques heures
    • Maintenance d'une table

    C'est le bon compromis pour 80 % des cas usage SaaS B2B.

    Couche 5 — Appel API direct

    Quand toutes les couches précédentes ratent, on appelle l'API. Encadré par :

    • Retry exponentiel sur 429/5xx avec Retry-After honoré
    • Circuit breaker : si > 50 % d'erreurs sur 1 minute, on stoppe les appels pendant 30 secondes
    • Timeout dur (10 s)
    • Limite locale : sémaphore de N requêtes concurrentes maximum

    Stratégies par cas d'usage

    A. Vérification de fournisseur (peu fréquent, doit être frais)

    • Cache mémoire 1 minute (au cas où l'utilisateur clique 3 fois)
    • Pas de cache CDN (données dépendantes du client)
    • Appel direct si miss

    Volume API typique : 1 req par dossier.

    B. Affichage public d'un annuaire (fréquent, peut être un peu vieux)

    • CDN 30 minutes
    • Cache mémoire 5 minutes
    • Snapshot DB rafraîchi nuit
    • Appel direct uniquement si miss complet

    Volume API typique : 1 req pour 100 vues.

    C. Recherche full-text (fréquent, doit être frais)

    • Pas de CDN (URL avec query unique)
    • Cache mémoire 1 minute avec clé = hash(query+filters)
    • Appel direct si miss

    Volume API typique : 1 req pour 5-10 recherches.

    D. Monitoring/alertes (suivi continu, événementiel)

    • Pas de polling — webhooks
    • Snapshot DB à jour via webhook
    • Cache mémoire optionnel

    Volume API typique : 0 req par jour (tout vient des webhooks).

    Webhooks vs polling : le calcul

    Vous suivez 1 000 clients et voulez détecter tout changement dans les 15 minutes.

    Polling :

    • 1 000 entreprises × (60/15) lookups/h × 24 h = 96 000 req/jour
    • Plan Pro requis (100 000/jour)
    • Coût : ~300 €/mois selon tarif

    Webhooks :

    • ~20 changements/jour (taux réel observé)
    • 20 webhooks reçus = 20 lookups optionnels = 20 req/jour
    • Plan Free suffit
    • Coût : 0 €/mois

    L'écart est 4 800×. Les webhooks sont quasi toujours la bonne réponse pour le suivi.

    Gérer les 429 proprement

    Pseudo-code pour un retry intelligent :

    Code
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    function callApi(req):
      attempt = 0
      while attempt < 4:
        res = http.send(req)
        if res.status == 429:
          delay = res.header("Retry-After") || base * 2^attempt
          sleep(delay + jitter())
          attempt++
          continue
        if res.status in [500, 502, 503, 504]:
          sleep(base * 2^attempt + jitter())
          attempt++
          continue
        return res
      throw RateLimitExhausted()

    Jitter = délai aléatoire ±25 % pour éviter le thundering herd (toutes vos instances qui retentent en même temps).

    Observabilité

    Métriques à exposer (Prometheus / Datadog / OpenTelemetry) :

    MétriqueTypePourquoi
    bce_api_requests_total{status}counterVolume par code HTTP
    bce_api_request_duration_mshistogramLatence p50/p95/p99
    bce_api_rate_limit_remaininggaugeQuota restant (alerte si < 10 %)
    bce_cache_hits_total{layer}counterEffet de chaque couche
    bce_circuit_breaker_stategauge0 closed / 1 half / 2 open

    Alerte si X-RateLimit-Remaining < 10 % du quota → bascule sur snapshot DB le temps que ça repasse.

    Tableau de capacité

    Volume utilisateurStratégie minimaleQuota API requis
    < 1 000 req/jourAppels directs + retryFree
    1 K - 10 K req/jour+ cache mémoireStarter
    10 K - 100 K req/jour+ cache partagé + CDNPro
    100 K - 1 M req/jour+ snapshot DB + webhooksPro ou Enterprise
    > 1 M req/jourTout + sharding cacheEnterprise + SLA dédié

    Pièges fréquents

  • Mettre en cache des réponses d'erreur — TTL=0 pour les 4xx/5xx, sinon vous "lockez" un échec
  • Cache key sans normalisation"0200.065.765" et "0200065765" doivent partager la même clé
  • Aucune deduplication — si 100 utilisateurs demandent la même PME en 100 ms, vous faites 100 appels. Implémentez un singleflight qui groupe les requêtes identiques en vol
  • Pas de fallback — si l'API tombe, votre app tombe. Toujours avoir un snapshot DB
  • Quota partagé entre prod et batch — séparez les API keys
  • Comment Company Belgium aide à scaler

    • Headers rate-limit transparents : votre code adapte son rythme
    • Webhooks pour 9 types d'événements (company.updated, company.ubo.changed, company.peppol.registered, etc.) — voir la référence des endpoints
    • Paliers de plan alignés sur des architectures réelles (Free, Starter, Pro, Enterprise)
    • Sandbox pour tester sans consommer le quota prod
    • Bulk endpoint sur les plans pro (récupérer 100 fiches en un appel)

    En résumé

    Scaler une app BCE/KBO ne se résume pas à payer un plan supérieur. La bonne architecture absorbe 95 % du trafic avant l'API, via 4 couches de cache et les webhooks. Le quota devient une formalité, la latence reste sous 50 ms, et la facture suit la valeur, pas le bruit.

    Trois leviers à activer dans l'ordre : cache mémoire + retry, webhooks au lieu du polling, snapshot DB pour vos propres clients. Avec ça, vous gérez 100 K req/jour utilisateur en consommant 5 K req/jour API.

    Questions fréquentes

    Qu'est-ce qu'un rate limit sur l'API BCE/KBO de Company Belgium ?

    Un rate limit est une limite au nombre de requêtes qu'une application peut envoyer à l'API pendant une fenêtre de temps donnée. Sur Company Belgium, les limites sont exprimées par minute et par jour selon le plan souscrit : 10 req/min sur le plan gratuit, 600 req/min sur le plan Pro. Les headers X-RateLimit-Remaining et Retry-After vous informent en temps réel de l'état de votre quota.

    Comment éviter les erreurs 429 Too Many Requests avec l'API BCE ?

    Pour éviter les 429, implémentez un cache à plusieurs niveaux pour absorber les requêtes répétées, et un retry exponentiel avec jitter pour les requêtes qui atteignent quand même la limite. L'utilisation de webhooks à la place du polling réduit dramatiquement le volume d'appels, souvent d'un facteur 4 800. Séparez aussi vos clés API entre environnements prod et batch pour éviter la contention.

    Quelle stratégie de cache est recommandée pour une app SaaS B2B belge consommant l'API KBO ?

    L'architecture recommandée combine 4 couches : un cache CDN pour les endpoints publics (TTL 5-10 min), un cache mémoire LRU par instance (TTL 5 min), un cache partagé Memcached ou Postgres entre instances, et un snapshot DB local pour les entreprises que vous suivez. Cette combinaison absorbe 95 % du trafic utilisateur avant l'API et réduit les coûts et la latence.

    Webhooks ou polling pour surveiller des changements dans la BCE/KBO en 2026 ?

    Les webhooks sont quasi toujours préférables. Avec du polling toutes les 15 minutes sur 1 000 entreprises, vous consommez environ 96 000 requêtes par jour. Avec les webhooks de Company Belgium, vous ne recevez que les événements réels, soit environ 20 notifications par jour pour la même couverture. L'écart de consommation est d'un facteur 4 800, ce qui permet souvent de rester sur le plan gratuit.

    Prêt à commencer ?

    Créez votre compte gratuitement et obtenez vos clés API en quelques minutes.

    Commentaires

    Chargement des commentaires…

    Laisser un commentaire

    Non publié — sert uniquement à vous notifier.

    Les commentaires sont modérés avant publication.

    Articles similaires