Code Examples
Copy-paste examples for every language and framework. All examples are production-ready.
Company Lookup
Fetch complete company data by KVK number. The most common use case.
curl -X GET "https://api.kvkbase.nl/v1/lookup/12345678" \
-H "Authorization: Bearer YOUR_API_KEY" // Using fetch (browser or Node.js 18+)
const response = await fetch(
"https://api.kvkbase.nl/v1/lookup/12345678",
{
headers: {
Authorization: "Bearer YOUR_API_KEY",
},
}
);
if (!response.ok) {
const { error } = await response.json();
throw new Error(error.message);
}
const company = await response.json();
console.log(company.name); // "Acme B.V."
console.log(company.address.city); // "Amsterdam"
console.log(company.vat?.valid); // true import requests
response = requests.get(
"https://api.kvkbase.nl/v1/lookup/12345678",
headers={"Authorization": "Bearer YOUR_API_KEY"}
)
response.raise_for_status()
company = response.json()
print(company["name"]) # "Acme B.V."
print(company["address"]["city"]) # "Amsterdam"
print(company["vat"]["valid"]) # True <?php
$ch = curl_init("https://api.kvkbase.nl/v1/lookup/12345678");
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_API_KEY"],
CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
echo $response["name"]; // "Acme B.V."
echo $response["address"]["city"]; // "Amsterdam" package main
import (
"encoding/json"
"fmt"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET",
"https://api.kvkbase.nl/v1/lookup/12345678", nil)
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
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) do |http|
http.request(req)
end
company = JSON.parse(res.body)
puts company["name"] # "Acme B.V."
puts company["address"]["city"] # "Amsterdam" using var client = new HttpClient();
client.DefaultRequestHeaders.Add(
"Authorization", "Bearer YOUR_API_KEY");
var response = await client.GetAsync(
"https://api.kvkbase.nl/v1/lookup/12345678");
var json = await response.Content.ReadAsStringAsync();
var company = JsonSerializer.Deserialize<JsonElement>(json);
Console.WriteLine(company.GetProperty("name")); // "Acme B.V." React Form with Auto-fill
A React component that looks up company data when a user enters a KVK number, with loading and error states.
import { useState, useCallback } from "react";
function KvkLookupForm() {
const [kvk, setKvk] = useState("");
const [company, setCompany] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState("");
const lookup = useCallback(async () => {
if (kvk.length !== 8) return;
setLoading(true);
setError("");
try {
const res = await fetch(
`https://api.kvkbase.nl/v1/lookup/${kvk}`,
{ headers: { Authorization: "Bearer YOUR_API_KEY" } }
);
if (!res.ok) {
const data = await res.json();
throw new Error(data.error?.message || "Lookup failed");
}
setCompany(await res.json());
} catch (err) {
setError(err.message);
setCompany(null);
} finally {
setLoading(false);
}
}, [kvk]);
return (
<form onSubmit={(e) => { e.preventDefault(); lookup(); }}>
<label htmlFor="kvk">KVK Nummer</label>
<input
id="kvk"
value={kvk}
onChange={(e) => setKvk(e.target.value)}
placeholder="12345678"
maxLength={8}
pattern="[0-9]{8}"
/>
<button type="submit" disabled={loading || kvk.length !== 8}>
{loading ? "Zoeken..." : "Opzoeken"}
</button>
{error && <p className="error">{error}</p>}
{company && (
<div className="result">
<p><strong>{company.name}</strong></p>
<p>{company.address?.street} {company.address?.houseNumber}</p>
<p>{company.address?.postalCode} {company.address?.city}</p>
{company.vat && (
<p>BTW: {company.vat.number} ({company.vat.valid ? "geldig" : "ongeldig"})</p>
)}
</div>
)}
</form>
);
} <template>
<form @submit.prevent="lookup">
<label for="kvk">KVK Nummer</label>
<input
id="kvk"
v-model="kvk"
placeholder="12345678"
maxlength="8"
/>
<button :disabled="loading || kvk.length !== 8">
{{ loading ? "Zoeken..." : "Opzoeken" }}
</button>
<p v-if="error" class="error">{{ error }}</p>
<div v-if="company" class="result">
<p><strong>{{ company.name }}</strong></p>
<p>{{ company.address?.street }} {{ company.address?.city }}</p>
<p v-if="company.vat">
BTW: {{ company.vat.number }}
({{ company.vat.valid ? "geldig" : "ongeldig" }})
</p>
</div>
</form>
</template>
<script setup>
import { ref } from "vue";
const kvk = ref("");
const company = ref(null);
const loading = ref(false);
const error = ref("");
async function lookup() {
if (kvk.value.length !== 8) return;
loading.value = true;
error.value = "";
try {
const res = await fetch(
`https://api.kvkbase.nl/v1/lookup/${kvk.value}`,
{ headers: { Authorization: "Bearer YOUR_API_KEY" } }
);
if (!res.ok) throw new Error((await res.json()).error?.message);
company.value = await res.json();
} catch (err) {
error.value = err.message;
company.value = null;
} finally {
loading.value = false;
}
}
</script> <script>
let kvk = "";
let company = null;
let loading = false;
let error = "";
async function lookup() {
if (kvk.length !== 8) return;
loading = true;
error = "";
try {
const res = await fetch(
`https://api.kvkbase.nl/v1/lookup/${kvk}`,
{ headers: { Authorization: "Bearer YOUR_API_KEY" } }
);
if (!res.ok) throw new Error((await res.json()).error?.message);
company = await res.json();
} catch (err) {
error = err.message;
company = null;
} finally {
loading = false;
}
}
</script>
<form on:submit|preventDefault={lookup}>
<label for="kvk">KVK Nummer</label>
<input id="kvk" bind:value={kvk} placeholder="12345678" maxlength="8" />
<button disabled={loading || kvk.length !== 8}>
{loading ? "Zoeken..." : "Opzoeken"}
</button>
{#if error}<p class="error">{error}</p>{/if}
{#if company}
<div class="result">
<p><strong>{company.name}</strong></p>
<p>{company.address?.street} {company.address?.city}</p>
</div>
{/if}
</form> Drop-in Widget
The fastest integration — one script tag auto-fills your form when a user types a KVK number.
<!DOCTYPE html>
<html>
<head>
<title>Registration Form</title>
</head>
<body>
<form>
<label>KVK Number</label>
<input type="text" id="kvk" placeholder="Enter KVK number">
<label>Company Name</label>
<input type="text" id="name" readonly>
<label>Address</label>
<input type="text" id="address" readonly>
<label>City</label>
<input type="text" id="city" readonly>
<label>Postal Code</label>
<input type="text" id="postal" readonly>
<label>VAT Number</label>
<input type="text" id="vat" readonly>
</form>
<!-- One script tag does everything -->
<script
src="https://widget.kvkbase.nl/v1.js"
data-api-key="YOUR_API_KEY"
data-target-kvk="#kvk"
data-target-name="#name"
data-target-address="#address"
data-target-city="#city"
data-target-postal="#postal"
data-target-vat="#vat">
</script>
</body>
</html> // Listen for widget events
document.addEventListener("kvkbase:found", (e) => {
console.log("Company found:", e.detail);
// {
// kvkNumber: "12345678",
// name: "Acme B.V.",
// address: { street: "Herengracht", city: "Amsterdam", ... },
// vat: { number: "NL123456789B01", valid: true }
// }
});
document.addEventListener("kvkbase:error", (e) => {
console.error("Lookup failed:", e.detail.message);
}); /* Customize the widget appearance */
:root {
--kvkbase-primary: #2563eb; /* Main color */
--kvkbase-success: #16a34a; /* Valid VAT checkmark */
--kvkbase-error: #dc2626; /* Error states */
--kvkbase-font: "Inter", sans-serif;
--kvkbase-border-radius: 8px;
} Next.js API Route
Server-side lookup in a Next.js API route. Keeps your API key secure on the server.
// app/api/kvk/[number]/route.ts
import { NextResponse } from "next/server";
export async function GET(
request: Request,
{ params }: { params: { number: string } }
) {
const response = await fetch(
`https://api.kvkbase.nl/v1/lookup/${params.number}`,
{
headers: {
Authorization: `Bearer ${process.env.KVKBASE_API_KEY}`,
},
}
);
if (!response.ok) {
const error = await response.json();
return NextResponse.json(error, { status: response.status });
}
const company = await response.json();
return NextResponse.json(company);
} # views.py
import requests
from django.conf import settings
from django.http import JsonResponse
def kvk_lookup(request, kvk_number):
response = requests.get(
f"https://api.kvkbase.nl/v1/lookup/{kvk_number}",
headers={
"Authorization": f"Bearer {settings.KVKBASE_API_KEY}"
},
timeout=10,
)
if not response.ok:
return JsonResponse(
response.json(),
status=response.status_code
)
return JsonResponse(response.json())
# urls.py
# path("api/kvk/<str:kvk_number>/", kvk_lookup) <?php
// app/Http/Controllers/KvkController.php
namespace App\Http\Controllers;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Http;
class KvkController extends Controller
{
public function lookup(string $kvkNumber): JsonResponse
{
$response = Http::withToken(config("services.kvkbase.key"))
->get("https://api.kvkbase.nl/v1/lookup/{$kvkNumber}");
if ($response->failed()) {
return response()->json(
$response->json(),
$response->status()
);
}
return response()->json($response->json());
}
}
// routes/api.php
// Route::get("/kvk/{number}", [KvkController::class, "lookup"]); // routes/kvk.js
import express from "express";
const router = express.Router();
router.get("/lookup/:kvkNumber", async (req, res) => {
try {
const response = await fetch(
`https://api.kvkbase.nl/v1/lookup/${req.params.kvkNumber}`,
{
headers: {
Authorization: `Bearer ${process.env.KVKBASE_API_KEY}`,
},
}
);
const data = await response.json();
res.status(response.status).json(data);
} catch (error) {
res.status(500).json({
error: { code: "INTERNAL", message: "KVK lookup failed" }
});
}
});
export default router; Batch Lookup (CSV Processing)
Process a CSV file of KVK numbers and enrich each row with company data. Respects rate limits with delays.
import csv
import time
import requests
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.kvkbase.nl/v1"
def enrich_csv(input_file, output_file):
with open(input_file) as infile, open(output_file, "w", newline="") as outfile:
reader = csv.DictReader(infile)
fieldnames = reader.fieldnames + [
"company_name", "address", "city",
"postal_code", "vat_number", "vat_valid"
]
writer = csv.DictWriter(outfile, fieldnames=fieldnames)
writer.writeheader()
for row in reader:
kvk = row.get("kvk_number", "").strip()
if len(kvk) != 8:
writer.writerow(row)
continue
try:
resp = requests.get(
f"{BASE_URL}/lookup/{kvk}",
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=10,
)
if resp.ok:
data = resp.json()
row["company_name"] = data.get("name", "")
addr = data.get("address") or {}
row["address"] = f"{addr.get('street', '')} {addr.get('houseNumber', '')}"
row["city"] = addr.get("city", "")
row["postal_code"] = addr.get("postalCode", "")
vat = data.get("vat") or {}
row["vat_number"] = vat.get("number", "")
row["vat_valid"] = str(vat.get("valid", ""))
# Respect rate limits
time.sleep(0.2) # 5 req/sec max
except Exception as e:
print(f"Error for {kvk}: {e}")
writer.writerow(row)
enrich_csv("contacts.csv", "contacts_enriched.csv") import fs from "fs";
import { parse } from "csv-parse/sync";
import { stringify } from "csv-stringify/sync";
const API_KEY = process.env.KVKBASE_API_KEY;
const delay = (ms) => new Promise((r) => setTimeout(r, ms));
async function enrichCSV(inputPath, outputPath) {
const input = fs.readFileSync(inputPath, "utf-8");
const records = parse(input, { columns: true });
const enriched = [];
for (const row of records) {
const kvk = row.kvk_number?.trim();
if (kvk?.length === 8) {
try {
const res = await fetch(
`https://api.kvkbase.nl/v1/lookup/${kvk}`,
{ headers: { Authorization: `Bearer ${API_KEY}` } }
);
if (res.ok) {
const data = await res.json();
row.company_name = data.name || "";
row.city = data.address?.city || "";
row.vat_number = data.vat?.number || "";
row.vat_valid = String(data.vat?.valid || "");
}
await delay(200); // Respect rate limits
} catch (e) {
console.error(`Error for ${kvk}:`, e.message);
}
}
enriched.push(row);
}
fs.writeFileSync(outputPath, stringify(enriched, { header: true }));
console.log(`Enriched ${enriched.length} rows`);
}
enrichCSV("contacts.csv", "contacts_enriched.csv");