Surveillance des entreprises
Surveillez des entreprises néerlandaises par numéro KvK et soyez averti dès que quelque chose change : une nouvelle adresse, un changement de nom, une faillite, une dissolution. Les alertes sont envoyées par e-mail, par webhook signé, ou les deux. Vous pouvez tout gérer depuis le tableau de bord ou via l'API.
403 monitoring_requires_paid_plan.
Fonctionnement
- Chaque entreprise surveillée est vérifiée une fois par jour, à partir des mêmes données que
/v1/lookup. - La première vérification sert de référence et ne déclenche jamais d'alerte.
- Un changement n'est signalé que si la source a répondu avec une valeur les deux fois. Une indisponibilité temporaire de la source n'apparaît jamais comme un changement.
- L'historique des alertes est conservé pendant 90 jours.
Champs pouvant déclencher une alerte
| Champ | Signification |
|---|---|
name | Raison sociale |
address | Rue, code postal et ville |
legalForm | Forme juridique (BV, NV, VOF, ...) |
status | active ou dissolved (dissoute) |
insolvency | none, bankrupt ou surseance |
sbiCodes | Codes d'activité (SBI) |
directors | Dirigeants, uniquement lorsque la source de données les fournit |
vat | Validité VIES du numéro de TVA connu |
Vous pouvez limiter les alertes à un sous-ensemble de champs dans les paramètres. Si aucun n'est sélectionné, vous les recevez tous.
Limites
| Offre | Emplacements de surveillance |
|---|---|
| Gratuit | 0 (non disponible) |
| Starter | 10 |
| Pro | 100 |
| Business | 1 000 |
- Un emplacement correspond à une entreprise surveillée, quel que soit le nombre de vérifications.
- Si votre offre passe sous le nombre d'entreprises que vous surveillez, les plus anciennes restent actives et les autres sont mises en pause, jamais supprimées. Elles reprennent lorsque vous passez à une offre supérieure.
- L'ajout en masse accepte 500 numéros au maximum par requête.
- 50 alertes par jour au maximum sont envoyées immédiatement par e-mail. Les suivantes sont regroupées dans le résumé quotidien.
- Les webhooks sont envoyés au maximum une fois par seconde et par compte.
- Si la capacité de surveillance est temporairement saturée, l'ajout d'une entreprise renvoie
503 monitoring_capacity. Réessayez plus tard.
Points d'accès
Tous les points d'accès utilisent votre clé d'API habituelle, Authorization: Bearer YOUR_API_KEY, et la limite de débit par minute habituelle.
| Point d'accès | Description |
|---|---|
GET /v1/monitor/watches | Liste les entreprises surveillées, avec limit et cursor. Renvoie watches (chacune avec kvkNumber, label, name, paused, createdAt, lastCheckedAt), slots: { used, limit } et nextCursor (null sur la dernière page). |
POST /v1/monitor/watches | Ajoute une entreprise (kvkNumber, label facultatif) ou plusieurs (kvkNumbers, 500 maximum). Les deux renvoient results et slots. Une requête en masse répond 200 avec un résultat par numéro (added, exists, invalid, over_limit ou not_found). Un ajout unique renvoie à la place une erreur en cas d'échec : 400 numéro invalide, 404 introuvable, 403 monitoring_slot_limit lorsqu'il ne reste plus d'emplacement. Un ajout unique réussi renvoie 201 (added) ou 200 (exists). |
PATCH /v1/monitor/watches/{kvk} | Modifie le libellé. |
DELETE /v1/monitor/watches/{kvk} | Arrête la surveillance d'une entreprise. |
GET /v1/monitor/alerts | Historique des alertes, renvoyé sous la forme alerts plus nextCursor. Filtrez avec kvkNumber et since ; paginez avec limit et cursor. |
GET /v1/monitor/settings | Lit les paramètres d'e-mail, de remise, de champs et de webhook. Renvoie emailEnabled, delivery, fields, webhookUrl, webhookConfigured, webhookDisabled et lang. Le secret du webhook n'est jamais renvoyé. |
PUT /v1/monitor/settings | Met à jour les paramètres. L'enregistrement d'une URL de webhook pour la première fois renvoie aussi webhookSecret, une seule fois. |
POST /v1/monitor/settings/webhook-secret | Génère un nouveau secret de webhook. La réponse (webhookSecret) est la seule occasion où il est affiché. |
POST /v1/monitor/webhook/test | Envoie un événement company.test signé à l'URL de votre webhook. Répond { delivered, status, reason } : delivered vaut true uniquement si votre point de terminaison a répondu par un 2xx, sinon reason en donne la cause. |
# Surveiller une entreprise
curl -X POST https://api.kvkbase.nl/v1/monitor/watches \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"kvkNumber": "12345678", "label": "client 1042"}'
# En surveiller plusieurs à la fois (500 maximum par requête)
curl -X POST https://api.kvkbase.nl/v1/monitor/watches \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"kvkNumbers": ["12345678", "87654321"]}' Alertes par e-mail
L'e-mail est envoyé à l'adresse de votre compte, en néerlandais, en anglais ou en français selon la langue de votre tableau de bord. Choisissez le mode immédiat (un e-mail par changement détecté, jusqu'à 20 changements listés par e-mail) ou résumé (un e-mail par jour à 07:00 UTC, regroupé par entreprise).
Webhooks
Indiquez une URL HTTPS dans les paramètres et KVKBase envoie un POST par événement. Seul le HTTPS sur le port 443 ou 8443 est accepté.
Les URL contenant une adresse IP privée ou de bouclage littérale, ou un nom d'hôte local tel que localhost ou *.local,
sont rejetées. Les redirections ne sont pas suivies.
Charge utile
{
"id": "evt_7c1f0b6e2a",
"type": "company.changed",
"createdAt": "2026-10-04T05:23:11.000Z",
"kvkNumber": "12345678",
"name": "Acme B.V.",
"changes": [
{ "field": "address", "from": "Herengracht 100, 1015 BS Amsterdam", "to": "Keizersgracht 5, 1015 CC Amsterdam" },
{ "field": "status", "from": "active", "to": "dissolved" }
]
} type vaut company.changed pour les changements réels et company.test pour le bouton de test.
Chaque changement est de la forme { field, from, to }, où from et to peuvent valoir null.
En-têtes
| En-tête | Valeur |
|---|---|
X-KVKBase-Event | Le type d'événement |
X-KVKBase-Timestamp | Heure Unix en secondes à laquelle la requête a été signée |
X-KVKBase-Signature | v1= suivi du HMAC-SHA256 hexadécimal de <timestamp>.<raw body> calculé avec votre secret de webhook |
Vérifier la signature
Le secret commence par whsec_. Il est affiché une fois lors de sa création et de nouveau lorsque vous le renouvelez,
conservez-le donc immédiatement. Vérifiez toujours la signature sur le corps brut de la requête, comparez en temps constant et
rejetez les requêtes dont l'horodatage date de plus de quelques minutes.
import { createHmac, timingSafeEqual } from "node:crypto";
// rawBody doit être exactement les octets reçus, avant tout parsing JSON.
export function verify(rawBody, headers, secret) {
const timestamp = headers["x-kvkbase-timestamp"];
const received = (headers["x-kvkbase-signature"] || "").replace(/^v1=/, "");
// Rejeter les requêtes anciennes pour qu'une requête interceptée ne puisse pas être rejouée.
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
const expected = createHmac("sha256", secret)
.update(timestamp + "." + rawBody)
.digest("hex");
return (
received.length === expected.length &&
timingSafeEqual(Buffer.from(received), Buffer.from(expected))
);
} <?php
$secret = getenv('KVKBASE_WEBHOOK_SECRET');
$rawBody = file_get_contents('php://input');
$timestamp = $_SERVER['HTTP_X_KVKBASE_TIMESTAMP'] ?? '';
$received = preg_replace('/^v1=/', '', $_SERVER['HTTP_X_KVKBASE_SIGNATURE'] ?? '');
$expected = hash_hmac('sha256', $timestamp . '.' . $rawBody, $secret);
if (abs(time() - (int) $timestamp) > 300 || !hash_equals($expected, $received)) {
http_response_code(401);
exit;
}
$event = json_decode($rawBody, true);
http_response_code(200); import hashlib
import hmac
import time
def verify(raw_body: bytes, headers: dict, secret: str) -> bool:
timestamp = headers.get("X-KVKBase-Timestamp", "")
received = headers.get("X-KVKBase-Signature", "").removeprefix("v1=")
# Rejeter les requêtes anciennes pour qu'une requête interceptée ne puisse pas être rejouée.
if abs(time.time() - int(timestamp or 0)) > 300:
return False
expected = hmac.new(
secret.encode(),
timestamp.encode() + b"." + raw_body,
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(expected, received) Nouvelles tentatives et désactivation automatique
- Répondez par n'importe quel
2xxdans les 5 secondes. Toute autre réponse, un dépassement de délai ou une redirection compte comme une tentative échouée. - Une remise échouée est retentée jusqu'à 3 tentatives au total, avec des délais croissants entre les tentatives.
- Après 20 remises échouées consécutives, le webhook est désactivé automatiquement et vous recevez un e-mail. Enregistrer à nouveau l'URL dans les paramètres le réactive. Un seul succès remet le compteur à zéro.
- Dans de rares cas, un événement peut arriver en double. Utilisez l'
idde l'événement pour dédoublonner.
Erreurs
La surveillance utilise le même format d'erreur que le reste de l'API. Les codes propres à cette fonctionnalité :
| Statut | Code | Signification |
|---|---|---|
| 403 | monitoring_requires_paid_plan | L'offre gratuite n'inclut aucun emplacement de surveillance. |
| 403 | monitoring_slot_limit | Tous les emplacements de surveillance de votre offre sont utilisés (ajout unique). |
| 503 | monitoring_capacity | La surveillance est temporairement saturée. Réessayez plus tard. |