Codes d'erreur
Toutes les erreurs de l'API suivent un format cohérent. Le code de statut HTTP indique la catégorie de l'erreur, et le corps de la réponse contient un code d'erreur lisible par une machine ainsi qu'un message lisible par un humain.
Format des erreurs
{
"error": {
"code": "NOT_FOUND",
"message": "Company not found for KVK number 99999999"
}
} Codes d'erreur
| Code | Statut HTTP | Description |
|---|---|---|
NOT_FOUND | 404 | Aucune entreprise trouvée pour le numéro KVK ou de TVA indiqué. |
INVALID_KVK_NUMBER | 400 | Le numéro KVK fourni n'est pas un numéro valide à 8 chiffres. |
INVALID_VAT_NUMBER | 400 | Le numéro de TVA fourni ne respecte pas le format attendu (par ex. NL + 9 chiffres + B + 2 chiffres). |
INVALID_CBE_NUMBER | 400 | Le numéro d'entreprise belge fourni n'est pas valide. Il doit comporter 10 chiffres et une paire de chiffres de contrôle correcte. 0821.015.819, BE0821015819 et 821015819 sont tous acceptés. Sur /v1/be/lookup/batch, un seul numéro invalide fait rejeter toute la requête. Aucun jeton n'est débité. |
INVALID_QUERY | 400 | Les paramètres de recherche ont été rejetés. Un filtre de code postal doit être associé à un huisnummer et écrit sans espace (6604LW, et non 6604 LW). Le problème vient de la requête, pas du service. |
UNAUTHORIZED | 401 | Clé d'API absente ou invalide. Vérifiez que vous envoyez une clé valide via l'en-tête Authorization ou le paramètre de requête apikey. |
RATE_LIMIT_EXCEEDED | 429 | Vous avez dépassé la limite de débit de votre offre. Patientez puis réessayez, ou passez à une offre supérieure pour des limites plus élevées. |
QUOTA_EXCEEDED | 429 | Vous avez utilisé toutes les recherches et validations incluses pour ce mois. Passez à une offre supérieure ou attendez le prochain cycle de facturation. |
UPSTREAM_ERROR | 502 | Un service en amont (registre de données ou VIES) est temporairement indisponible. La requête peut aboutir si vous la renouvelez. Sur /v1/validate/vat, cette erreur n'est renvoyée que lorsque nous n'avons strictement rien d'utile à indiquer, voir Validation de TVA pendant une panne de VIES. |
UPSTREAM_BUDGET | 503 | Les données des entreprises belges sont temporairement limitées : notre quota de données du jour est épuisé et la fiche n'est pas encore enregistrée. Les fiches que nous détenons déjà restent servies, avec source.stale activé lorsqu'elles n'ont pas pu être actualisées. La réponse contient un en-tête Retry-After indiquant le nombre de secondes à attendre. Réessayez plus tard : votre requête n'est pas en cause. |
INTERNAL_ERROR | 500 | Une erreur inattendue s'est produite. Si elle persiste, contactez le support. |
Validation de TVA pendant une panne de VIES
VIES est une passerelle vers le service de TVA propre à chaque État membre, et ces services
tombent parfois en panne. Lorsqu'un État membre est indisponible, VIES répond par un HTTP 200 sans
aucun verdict. Nous ne le transformons jamais en "valid": false, car un
client le lirait comme « ce numéro de TVA est invalide » et rejetterait à tort une
contrepartie parfaitement légitime.
À la place, /v1/validate/vat/{vatNumber} vous indique dans laquelle des
quatre situations vous vous trouvez grâce à un champ status. Trois d'entre elles
renvoient un 200, seule la dernière renvoie un 502.
| status | HTTP | Signification |
|---|---|---|
validated | 200 | VIES a répondu, à l'instant ou via une entrée de cache non expirée. valid est le verdict propre de VIES. |
stale | 200 | VIES est injoignable, nous servons donc un verdict VIES obtenu précédemment, au-delà de sa durée de cache normale. validatedAt et ageSeconds indiquent son ancienneté. Nous les servons pendant 30 jours au plus, puis nous arrêtons. Considérez-le comme un indice, pas comme une confirmation en temps réel. |
malformed | 200 | VIES est injoignable, mais le numéro échoue à l'elfproef néerlandais (contrôle de somme) : il ne peut donc pas être un numéro de TVA néerlandais réel. valid vaut false et vous pouvez vous y fier. |
| (aucun) | 502 | UPSTREAM_ERROR. Aucun verdict en cache datant de moins de 30 jours et le contrôle de somme ne permet pas de trancher : nous n'avons donc rien. Réessayez plus tard. Ce n'est pas un verdict sur le numéro. |
Chaque réponse contient aussi checksumValid, le résultat de l'elfproef néerlandais
sur le bloc de neuf chiffres. Il vaut true lorsque le numéro est
bien formé, ce qui n'est pas la même chose que valide : le contrôle écarte
les fautes de frappe et les chiffres inversés, mais un nombre à neuf chiffres choisi au hasard le réussit tout de même environ
une fois sur onze. Il ne dit rien sur l'enregistrement ou l'activité du numéro.
Seul VIES y répond. Pour un numéro non néerlandais, il vaut null,
car chaque État membre applique son propre schéma.
{
"vatNumber": "NL123456789B01",
"valid": true,
"name": "Acme B.V.",
"address": "Herengracht 100, 1015 AA Amsterdam",
"validatedAt": "2026-08-14T09:12:00Z",
"status": "stale",
"ageSeconds": 786240,
"checksumValid": true,
"unavailableReason": "MS_UNAVAILABLE"
}
Les mêmes champs status, checksumValid et
ageSeconds figurent dans l'objet vat d'une recherche d'entreprise,
avec une quatrième valeur, unvalidated, pour un numéro de TVA candidat déduit
que VIES n'a jamais confirmé. Dans ce cas, valid vaut null.
Gérer les erreurs
Nous recommandons de vérifier d'abord le code de statut HTTP, puis d'analyser le corps de l'erreur pour obtenir plus de détails :
const res = await fetch("https://api.kvkbase.nl/v1/lookup/12345678", {
headers: { Authorization: "Bearer YOUR_API_KEY" },
});
if (!res.ok) {
const { error } = await res.json();
switch (error.code) {
case "NOT_FOUND":
console.log("Entreprise introuvable");
break;
case "RATE_LIMIT_EXCEEDED":
// Patienter puis réessayer
const retryAfter = res.headers.get("Retry-After");
break;
case "QUOTA_EXCEEDED":
console.log("Quota mensuel atteint");
break;
default:
console.error("Erreur d'API :", error.message);
}
} En-têtes de limite de débit
Chaque réponse contient des informations sur la limite de débit dans ses en-têtes :
| En-tête | Description |
|---|---|
X-RateLimit-Limit | Nombre maximal de requêtes par minute pour votre offre |
X-RateLimit-Remaining | Requêtes restantes dans la fenêtre en cours |
X-RateLimit-Reset | Horodatage Unix de la réinitialisation de la fenêtre de limite de débit |
Retry-After | Nombre de secondes à attendre avant de réessayer (uniquement sur les réponses 429) |