Monitoring Dutch Company Status with the KVK API: Detecting Bankruptcies and Changes
KVKBase Team

Monitoring Dutch Company Status with the KVK API: Detecting Bankruptcies and Changes

Automatically detect when a customer or supplier goes bankrupt, deregisters, or changes address. Use the KVKBase API to monitor company status in real time and reduce financial risk.

kvkapimonitoringrisk managementbankruptcycompliance

Monitoring Dutch Company Status with the KVK API: Detecting Bankruptcies and Changes

A customer who paid on time last week could be bankrupt next week. A supplier that operated from the same address for years may have quietly deregistered. For B2B companies, these are not hypothetical scenarios — they are real risks that can cause serious financial damage.

With the KVKBase API, you can detect these changes automatically, without manually checking the Dutch Trade Register every day. This article explains how to monitor company status, which signals matter, and how to set it up in practice.

Which status changes are relevant?

The KVK Trade Register does not just contain static business data. It also includes current status information. The changes that have the most impact on your operations are:

  • Bankruptcy declaration: the company has been declared bankrupt by a court
  • Suspension of payments: the company has applied for a temporary debt moratorium
  • Deregistration: the business has been formally dissolved and removed from the register
  • Address change: the registered office address has changed, relevant for mail and invoicing
  • Name change: the company now trades under a different name
  • Legal form change: for instance from sole trader to private limited company (BV)
  • Change of directors: different persons now have signing authority

Not all of these are equally urgent. An address change is administrative; a bankruptcy declaration requires immediate action from credit management or accounts receivable.

Why manual checks don’t scale

The tendency at many companies is to check debtors or suppliers ad hoc, only once something has already gone wrong. An outstanding invoice that never gets paid, a payment reminder returned to an old address.

At that point, the damage is already done. Proactive monitoring is far more effective: you know before you send an invoice, before you make a large delivery, before you sign a contract.

Manually checking the Trade Register for a list of hundreds of customers is not feasible. Automated monitoring via the API is.

Querying company status via the KVKBase API

The KVKBase API returns an active field and additional status information for every company. Here is a simple implementation in Python:

import os
import requests

API_KEY = os.environ["KVKBASE_API_KEY"]
BASE_URL = "https://api.kvkbase.nl/api/v1"

def check_company_status(kvk_number: str) -> dict:
    response = requests.get(
        f"{BASE_URL}/kvk/{kvk_number}",
        headers={"x-api-key": API_KEY}
    )
    response.raise_for_status()
    data = response.json()

    return {
        "kvk_number": kvk_number,
        "name": data.get("naam"),
        "active": data.get("actief", True),
        "legal_form": data.get("rechtsvorm"),
        "address": data.get("adres", {}),
    }

# Check a specific company
status = check_company_status("12345678")
if not status["active"]:
    print(f"WARNING: {status['name']} is no longer active!")

Bulk monitoring: scanning your entire customer list

In practice, you don’t want to check one company at a time. You want to run your entire customer list. The most efficient approach is a periodic batch job combined with an alerting mechanism.

import time
import smtplib
from email.message import EmailMessage
from typing import List

def monitor_portfolio(kvk_numbers: List[str]) -> List[dict]:
    """Check a list of KVK numbers and return any alerts."""
    alerts = []

    for kvk in kvk_numbers:
        try:
            status = check_company_status(kvk)
            if not status["active"]:
                alerts.append({
                    "kvk_number": kvk,
                    "company": status["name"],
                    "reason": "Company no longer active in KVK register"
                })
            time.sleep(0.2)  # Respect rate limits
        except Exception as e:
            print(f"Error fetching {kvk}: {e}")

    return alerts

def send_alert_email(alerts: List[dict], recipient: str):
    if not alerts:
        return

    msg = EmailMessage()
    msg["Subject"] = f"KVK Monitor: {len(alerts)} company/companies require attention"
    msg["From"] = "monitor@yourcompany.com"
    msg["To"] = recipient

    body = "The following companies are no longer active:\n\n"
    for alert in alerts:
        body += f"- {alert['company']} (KVK: {alert['kvk_number']})\n"
        body += f"  Reason: {alert['reason']}\n\n"

    msg.set_content(body)

    with smtplib.SMTP("localhost") as smtp:
        smtp.send_message(msg)

Detecting address changes

Address changes require a different approach. You need a reference point: the address stored in your own system. You then compare the API response against your own database.

def detect_address_changes(kvk_number: str, stored_address: dict) -> dict | None:
    """Compare current KVK address with stored address."""
    current = check_company_status(kvk_number)
    api_address = current.get("address", {})

    fields_to_check = ["straat", "huisnummer", "postcode", "plaats"]
    changes = {}

    for field in fields_to_check:
        stored_val = stored_address.get(field, "").lower().strip()
        api_val = str(api_address.get(field, "")).lower().strip()
        if stored_val != api_val and api_val:
            changes[field] = {
                "old": stored_address.get(field),
                "new": api_address.get(field)
            }

    if changes:
        return {
            "kvk_number": kvk_number,
            "company": current["name"],
            "changes": changes
        }
    return None

Frequency and strategy

How often you monitor depends on your risk profile:

SegmentRecommended frequencyReason
Large debtors (>10k outstanding)DailyHigh financial risk
Regular customersWeeklyBalance between risk and API usage
Occasional customersMonthlyLow volume, low risk
SuppliersMonthlyBusiness continuity risk

For most companies, a weekly overnight batch job per segment strikes a good balance. Pair this with your webhook setup if you want real-time updates alongside periodic checks.

Integrating with your CRM or ERP

Monitoring becomes truly powerful when connected to your existing systems. Imagine:

  • A customer is declared bankrupt, automatically triggering a task for the credit manager in your CRM
  • A supplier deregisters, causing a warning to appear in your procurement module on the next order
  • A debtor changes address, automatically updating all outstanding invoices with the new details

These integrations are achievable with the KVKBase API as the data source and a lightweight middleware layer that translates events into actions in your ERP or CRM.

Getting started with monitoring

Want to set up company status monitoring for your own portfolio? Start with these steps:

  1. Export your KVK numbers from your CRM or accounting package
  2. Get an API key via the KVKBase dashboard
  3. Set up an initial batch check via a Python script or a cron job
  4. Define your alert thresholds - what triggers a notification, and who receives it?
  5. Connect to your workflow - is a Slack message enough, or should a task be created immediately?

Monitoring is not a one-off project but an ongoing process. Companies change constantly, and most changes only become a problem when you notice them too late. With automated KVK monitoring, you always have an accurate picture of your customer portfolio, without anyone needing to check manually every day.

Also read: Newly Registered Companies as B2B Leads for the other side of the coin: spotting new opportunities through the Trade Register.