Error Codes
All API errors follow a consistent format. The HTTP status code indicates the category of error, and the response body contains a machine-readable error code and a human-readable message.
Error response format
Every error response has this structure:
{
"error": {
"code": "NOT_FOUND",
"message": "Company not found for KVK number 99999999"
}
} Error code reference
All possible error codes, their HTTP status, and common causes:
NOT_FOUND 404 No company found for the given identifier.
INVALID_KVK_NUMBER 400 The provided KVK number is not valid.
INVALID_VAT_NUMBER 400 The provided VAT number format is not recognized.
INVALID_REQUEST 400 The request is missing required parameters or has invalid values.
UNAUTHORIZED 401 Missing or invalid API key.
RATE_LIMIT_EXCEEDED 429 Too many requests in the current time window.
QUOTA_EXCEEDED 429 Monthly token allowance exhausted.
UPSTREAM_ERROR 502 An upstream service is temporarily unavailable.
INTERNAL_ERROR 500 An unexpected server error occurred.
Handling errors
We recommend checking the HTTP status code first, then parsing the error body for the specific error code:
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("Company not found");
break;
case "RATE_LIMIT_EXCEEDED":
const retryAfter = res.headers.get("Retry-After");
console.log(`Rate limited. Retry after ${retryAfter}s`);
break;
case "QUOTA_EXCEEDED":
console.log("Monthly token quota reached");
break;
case "UNAUTHORIZED":
console.log("Invalid API key");
break;
default:
console.error("API error:", error.message);
}
} Rate limit headers
Every API response includes headers with rate limit and token usage information. Use these to monitor your usage and avoid hitting limits.
| Header | Description | Example |
|---|---|---|
X-RateLimit-Limit | Maximum requests per minute for your plan | 60 |
X-RateLimit-Remaining | Requests remaining in the current window | 58 |
X-RateLimit-Reset | Unix timestamp when the rate limit window resets | 1710676800 |
X-Tokens-Remaining | Tokens remaining for the current billing cycle | 847 |
Retry-After | Seconds to wait before retrying (only on 429 responses) | 12 |
Retry strategy
For production applications, we recommend implementing exponential backoff:
async function kvkLookup(kvkNumber, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const res = await fetch(
`https://api.kvkbase.nl/v1/lookup/${kvkNumber}`,
{ headers: { Authorization: "Bearer YOUR_API_KEY" } }
);
if (res.ok) return res.json();
if (res.status === 429) {
const wait = parseInt(res.headers.get("Retry-After") || "5");
await new Promise(r => setTimeout(r, wait * 1000));
continue;
}
if (res.status === 502) {
// Upstream error -- wait and retry
await new Promise(r => setTimeout(r, (attempt + 1) * 2000));
continue;
}
// Non-retryable error
const { error } = await res.json();
throw new Error(error.message);
}
throw new Error("Max retries exceeded");
}