KVKBase Team

Belgische bedrijfsgegevens API integreren: gids voor developers

Belgische bedrijfsgegevens API integreren in je CRM, facturatie of checkout: authenticatie, lookup, batch, foutafhandeling, caching en codevoorbeelden.

belgieapiintegratiedevelopers

Wie Belgische bedrijfsgegevens in een eigen applicatie wil gebruiken, wil meestal dezelfde drie dingen: een nummer of naam omzetten naar een volledig bedrijfsprofiel, dat profiel in een formulier of CRM laten landen, en dit doen zonder bij elke storing of typefout in de problemen te komen. Deze gids loopt door de integratie met de KVKBase API, van de eerste curl tot een robuuste productieflow. Het gaat om officiële Belgische bedrijfsgegevens, geleverd als eenvoudige JSON.

Basis: authenticatie en endpoints

De basis-URL is https://api.kvkbase.nl. Elke aanvraag draagt een bearer-token in de header Authorization. Maak een sleutel aan via /signup, het gratis plan heeft 50 tokens per maand en vraagt geen kredietkaart. Zet de sleutel in een omgevingsvariabele, nooit in front-endcode.

EndpointDoelKost
GET /v1/be/lookup/{ondernemingsnummer}Volledig profiel van één onderneming1 token
GET /v1/be/search?q=...&postalCode=...Zoeken op naam, max. 25 resultaten1 token
POST /v1/be/lookup/batchTot 25 nummers per oproep1 token per nummer
GET /v1/be/validate/vat/{btw-nummer}Btw-controle via VIES1 token

Daarnaast accepteert GET /v1/lookup/{number} ook Belgische nummers, handig als je al een algemene integratie hebt. De volledige veldbeschrijving staat in de API-referentie, prijsdetails op /pricing.

Eerste lookup

curl -s "https://api.kvkbase.nl/v1/be/lookup/0821.015.819?lang=nl" \
  -H "Authorization: Bearer YOUR_API_KEY"

Het nummer mag met of zonder punten, met of zonder BE-prefix. De parameter lang (nl, fr, de of en) bepaalt de taal van labels zoals legalForm en juridicalSituation. Standaard is dat nl.

Normaliseren en valideren voor je belt

Gebruikers typen BE 0821 015 819, plakken spaties mee of vergeten de leidende nul. Ruim dat op in je eigen code, en controleer het controlegetal. Een ondernemingsnummer heeft tien cijfers, begint met 0 of 1, en de laatste twee cijfers zijn 97 min (de eerste acht cijfers modulo 97). Meer uitleg vind je in de gids over opzoeken.

export function normalizeCompanyNumber(input) {
  let digits = String(input).replace(/\D/g, "");
  if (digits.length === 9) digits = "0" + digits; // older 9-digit numbers
  if (!/^[01]\d{9}$/.test(digits)) return null;
  const base = Number(digits.slice(0, 8));
  const check = Number(digits.slice(8));
  return 97 - (base % 97) === check ? digits : null;
}

Geeft de functie null, toon dan meteen een foutmelding in het formulier. Je bespaart een netwerkoproep. Ook als je het toch doorstuurt, is er geen verlies: een misvormd nummer wordt aan onze kant geweigerd voor er opgezocht wordt en kost niets.

Lookup in JavaScript en Python

async function lookupCompany(number) {
  const res = await fetch(
    `https://api.kvkbase.nl/v1/be/lookup/${number}?lang=nl`,
    { headers: { Authorization: `Bearer ${process.env.KVKBASE_API_KEY}` } }
  );
  if (!res.ok) {
    const body = await res.text().catch(() => "");
    throw Object.assign(new Error(`HTTP ${res.status}: ${body}`), {
      status: res.status,
    });
  }
  return res.json();
}
import os
import requests

def lookup_company(number: str) -> dict:
    r = requests.get(
        f"https://api.kvkbase.nl/v1/be/lookup/{number}",
        params={"lang": "nl"},
        headers={"Authorization": f"Bearer {os.environ['KVKBASE_API_KEY']}"},
        timeout=10,
    )
    r.raise_for_status()
    return r.json()

Zet altijd een time-out. Een hangende oproep in een checkout is erger dan een foutmelding.

Zoeken en batch

Heb je enkel een naam, gebruik dan search. Een q van minstens twee tekens is verplicht, postalCode (vier cijfers) versmalt de resultaten sterk. Elke hit bevat onder meer cbeNumber, cbeNumberFormatted, name, entityType, legalForm, postcode en gemeente.

curl -s "https://api.kvkbase.nl/v1/be/search?q=bakkerij&postalCode=9000&pageSize=10" \
  -H "Authorization: Bearer YOUR_API_KEY"

Voor lijsten gebruik je de batch-oproep. Maximaal 25 nummers per aanvraag, het antwoord is een object met je nummers als sleutel, en elk item is {success, data} of {success, error}. Een nummer dat niet gevonden wordt, krijgt dus een eigen foutregel. Een nummer met een ongeldig formaat of controlegetal wordt wel voor de hele batch geweigerd (HTTP 400), controleer ze dus vooraf.

const res = await fetch("https://api.kvkbase.nl/v1/be/lookup/batch", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.KVKBASE_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ cbeNumbers: numbers.slice(0, 25), lang: "nl" }),
});
const results = await res.json();

Knip grotere lijsten zelf in stukken van 25 en dedupliceer eerst: elk nummer in een batch kost een token.

Foutafhandeling en retries

CodeStatusWat doen
INVALID_CBE_NUMBER400Niet herhalen, gebruiker laten corrigeren
NOT_FOUND404Niet herhalen, nummer bestaat niet in de gegevens
QUOTA_EXCEEDED / rate limit429Wachten en trager aanvragen, of plan opschalen
UPSTREAM_ERROR502Beperkt herhalen met backoff
UPSTREAM_BUDGET503Later opnieuw proberen

Herhaal enkel bij 429, 502 en 503, en gebruik exponentiele backoff met een plafond van drie of vier pogingen. Een 4xx-fout herhalen heeft geen zin.

import time

RETRYABLE = {429, 502, 503}

def lookup_with_retry(number, attempts=4):
    for i in range(attempts):
        try:
            return lookup_company(number)
        except requests.HTTPError as e:
            status = e.response.status_code
            if status not in RETRYABLE or i == attempts - 1:
                raise
            time.sleep(2 ** i)

Opslaan en cachen

Bedrijfsgegevens veranderen traag. De meeste bedrijven verhuizen of wijzigen zelden van rechtsvorm. Bewaar daarom het volledige antwoord in je eigen database, met cbeNumber als sleutel en een eigen fetchedAt. Een paar richtlijnen:

  • Toon in je eigen UI het opvraagmoment, bijvoorbeeld “gegevens van 2026-11-10”.
  • Ververs actieve klanten op een vast ritme (maandelijks of per kwartaal) en altijd vlak voor een grote factuur of contract.
  • Houd isActive en juridicalSituation scherper in de gaten dan adresgegevens.
  • Het antwoord bevat source.cachedAt en source.stale, zodat je weet hoe vers een kopie is. Wij bewaren kopieën, waardoor herhaalde lookups snel zijn, maar de gegevens zijn niet realtime en we garanderen geen volledigheid.

Een eigen cache bespaart tokens: dezelfde klant tien keer tonen in een dashboard hoeft niet tien tokens te kosten.

Velden mappen naar CRM of factuurformulier

DoelveldBron in het antwoord
Bedrijfsnaamname
HandelsnamentradingNames[]
OndernemingsnummercbeNumberFormatted
Btw-nummer"BE" + cbeNumber, bevestigd via vat.valid
RechtsvormlegalFormShort (BV, NV) of legalForm
Adresaddress.street, houseNumber, postalCode, city
StatusisActive, juridicalSituation
Hoofdactiviteitactivities[] waar isMain waar is

Let op bij entityType: "natural_person": een eenmanszaak kan een privéadres als vestigingsadres hebben. Toon dat niet zomaar in publieke context en behandel het volgens de AVG. Het verschil tussen ondernemingsnummer en btw-nummer leg je uit in deze gids, en de VIES-controle in deze.

Patroon: autofill in een checkout

Een gangbaar patroon voor B2B-checkouts:

  1. De klant typt een ondernemingsnummer of btw-nummer.
  2. Je front-end normaliseert en controleert het controlegetal lokaal (geen oproep nodig).
  3. Bij een geldig nummer doet je backend de lookup. De API-sleutel blijft op de server.
  4. Je vult naam, adres en rechtsvorm in als voorstel, de klant bevestigt of past aan.
  5. Je bewaart het antwoord met tijdstip bij de bestelling.

Heeft de klant enkel een naam, laat dan een search met postcode een korte lijst tonen. Wil je ook controleren of het bedrijf nog actief is, dan vind je de checklist in de gids over klant- en leveranciersonderzoek. Je kan het mechanisme ook eerst uitproberen met de gratis tool /be/ondernemingsnummer-opzoeken.

Tokens in de hand houden

  • Valideer lokaal vooraf, cache in je eigen opslag, dedupliceer batches.
  • Zet een teller per dag of per klant, en log 429-antwoorden.
  • Ontwerp je flow zodat een tijdelijke fout (502, 503) de gebruiker niet blokkeert: laat handmatige invoer toe en verrijk later.

Meer over de Belgische kant van het product lees je op de landingspagina.

Veelgestelde vragen

Hoeveel tokens kost een Belgische lookup?
Elke lookup, zoekopdracht en btw-validatie kost 1 token. In een batch tel je 1 token per nummer. Het gratis plan bevat 50 tokens per maand, zonder kredietkaart.
Kost een ongeldig ondernemingsnummer tokens?
Nee. Een foutief geformatteerd nummer wordt geweigerd voor er een lookup gebeurt en geeft INVALID_CBE_NUMBER (400). Valideer toch zelf vooraf, dan bespaar je ook de netwerkronde.
Welke formaten voor het ondernemingsnummer accepteert de API?
Alle gangbare schrijfwijzen: 0821.015.819, 0821015819 en BE0821015819. Het antwoord bevat altijd zowel de ruwe tien cijfers als de geformatteerde variant.
Hoe lang mag ik antwoorden bewaren?
Dat bepaal je zelf, maar bewaar altijd het tijdstip van de opvraging. Het veld source.cachedAt toont hoe oud het opgeslagen exemplaar is, en gegevens zijn nooit gegarandeerd realtime.