API Reference

Base URL https://api.kvkbase.nl/v1

Authentication

All endpoints (except /v1/health) require an API key. Two methods are supported:

Query Parameter

?apikey=YOUR_API_KEY

Get your API key from the Dashboard. Keys are scoped to your account tier and rate limits.

GET /v1/lookup/{kvkNumber}

Company Lookup

Look up detailed company information by KVK number. Returns company name, address, legal form, activities, and VIES-validated VAT number in a single call.

Parameters

kvkNumber required
string
8-digit KVK number (path parameter)

Request

curl -X GET "https://api.kvkbase.nl/v1/lookup/12345678" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch(
  "https://api.kvkbase.nl/v1/lookup/12345678",
  {
    headers: {
      Authorization: "Bearer YOUR_API_KEY",
    },
  }
);
const company = await response.json();
console.log(company.name); // "Acme B.V."
import requests

response = requests.get(
    "https://api.kvkbase.nl/v1/lookup/12345678",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)
company = response.json()
print(company["name"])  # "Acme B.V."
$ch = curl_init("https://api.kvkbase.nl/v1/lookup/12345678");
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Authorization: Bearer YOUR_API_KEY"
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch));
echo $response->name; // "Acme B.V."
req, _ := http.NewRequest("GET",
    "https://api.kvkbase.nl/v1/lookup/12345678", nil)
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")

resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()

var company map[string]interface{}
json.NewDecoder(resp.Body).Decode(&company)
fmt.Println(company["name"]) // "Acme B.V."
require "net/http"
require "json"

uri = URI("https://api.kvkbase.nl/v1/lookup/12345678")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer YOUR_API_KEY"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http|
  http.request(req)
}
company = JSON.parse(res.body)
puts company["name"] # "Acme B.V."

Response

{
  "kvkNumber": "12345678",
  "name": "Acme B.V.",
  "tradingNames": ["Acme", "Acme Trading"],
  "legalForm": "BV",
  "address": {
    "street": "Herengracht",
    "houseNumber": "100",
    "postalCode": "1015 AA",
    "city": "Amsterdam",
    "country": "NL"
  },
  "isActive": true,
  "registrationDate": "2020-01-15",
  "activities": [
    { "sbiCode": "6201", "description": "Ontwikkelen en uitgeven van software", "isMain": true }
  ],
  "vat": {
    "number": "NL123456789B01",
    "valid": true,
    "validatedAt": "2026-03-15T12:00:00Z"
  },
  "source": {
    "kvk": "opendata+zoeken",
    "vies": "validated",
    "cachedAt": "2026-03-15T12:00:00Z"
  }
}
GET /v1/validate/vat/{vatNumber}

VAT Validation

Validate a Dutch or EU VAT number against the VIES system. Returns validation status and registered company details.

Parameters

vatNumber required
string
VAT number, e.g. NL123456789B01 (path parameter)

Request

curl -X GET "https://api.kvkbase.nl/v1/validate/vat/NL123456789B01" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch(
  "https://api.kvkbase.nl/v1/validate/vat/NL123456789B01",
  { headers: { Authorization: "Bearer YOUR_API_KEY" } }
);
const { valid, name } = await response.json();
response = requests.get(
    "https://api.kvkbase.nl/v1/validate/vat/NL123456789B01",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)
result = response.json()
print(f"Valid: {result['valid']}")
$ch = curl_init(
    "https://api.kvkbase.nl/v1/validate/vat/NL123456789B01"
);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Authorization: Bearer YOUR_API_KEY"
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = json_decode(curl_exec($ch));
req, _ := http.NewRequest("GET",
    "https://api.kvkbase.nl/v1/validate/vat/NL123456789B01", nil)
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
resp, _ := http.DefaultClient.Do(req)
uri = URI("https://api.kvkbase.nl/v1/validate/vat/NL123456789B01")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer YOUR_API_KEY"

Response

{
  "vatNumber": "NL123456789B01",
  "valid": true,
  "name": "Acme B.V.",
  "address": "Herengracht 100, 1015 AA Amsterdam",
  "validatedAt": "2026-03-15T12:00:00Z"
}
GET /v1/health

Health Check

Check API and upstream service status. No authentication required.

Request

curl https://api.kvkbase.nl/v1/health
const response = await fetch("https://api.kvkbase.nl/v1/health");
const health = await response.json();
console.log(health.status); // "ok"
response = requests.get("https://api.kvkbase.nl/v1/health")
print(response.json()["status"])  # "ok"
$health = json_decode(
    file_get_contents("https://api.kvkbase.nl/v1/health")
);
resp, _ := http.Get("https://api.kvkbase.nl/v1/health")
res = Net::HTTP.get(URI("https://api.kvkbase.nl/v1/health"))

Response

{
  "status": "ok",
  "services": {
    "kvk": "up",
    "vies": "up"
  },
  "timestamp": "2026-03-15T12:00:00Z"
}

Errors

All errors return a consistent JSON format:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "No company found with KVK number 99999999"
  }
}

See the Error Codes page for a complete reference with HTTP status codes.

Rate Limits

Rate limits are applied per API key based on your plan tier:

Tier
Rate Limit
Headers
free
10 req/min
X-RateLimit-Limit, X-RateLimit-Remaining
starter
60 req/min
X-RateLimit-Limit, X-RateLimit-Remaining
pro
300 req/min
X-RateLimit-Limit, X-RateLimit-Remaining

When rate limited, the API returns 429 Too Many Requests with a Retry-After header.