API reference
Companize API
Dutch business data - company search and profiles, address validation and VAT validation, in one API.
curl https://api.companize.nl/v1/companies/69599084 \ -H "Authorization: Bearer <api-key>"
Full spec: openapi.yaml · version 1.0.0
Companize is three APIs behind one key: company data (search, autocomplete and registry profiles from the Handelsregister, plus an enrichment layer with websites, e-mail addresses, phone numbers, social profiles, employee counts, key financials, SBI codes and registry publications), address validation (postcode + house number lookup, free-text address search and autocomplete over Dutch addresses) and VAT validation (BTW numbers checked live against the EU VIES register and resolved to the company behind them).
Conventions
- Envelope. Every response is
{ "data": ..., "meta": ... }.datadescribes the resource(s);metadescribes the *request* (request id, timing, pagination info, and, on metered calls, credit usage). Recency of the data itself (asOf,source,stale) lives *inside* the resource, never inmeta. - Identifiers are strings.
kvkNumber(8 digits),establishmentNumber(12 digits, Handelsregister: vestigingsnummer) andrsin(9 digits) preserve leading zeros and must be treated as strings, never integers. - Metering. Autocomplete, basic profile fetches and enrichment are each counted against your plan's monthly allowance. Enrichment responses additionally return
Companize-Credits-CostandCompanize-Credits-Remaining. When an allowance is exhausted you receive402 plan_limit_reached(naming which limit) until the period resets or you upgrade. - Unmetered extras. Address validation and VAT validation are included with paid plans and consume no monthly credits; on trial plans they return
402 paid_plan_required. VAT lookups have their own modest rate ceiling to protect the shared VIES upstream, with repeat lookups served from cache and a last-known answer (markedstale: true) when VIES itself is unreachable. - Rate limiting. All responses carry
RateLimit-Limit,RateLimit-RemainingandRateLimit-Reset. Exceeding the per-second limit returns429withRetry-After. - Errors. Failures are RFC 9457
application/problem+jsondocuments; eachtypeURI resolves to a documentation page describing that error.
Out of scope for this version (planned)
On-demand fresh re-scrapes (fresh=true), asynchronous batch enrichment, and change-monitoring webhooks are intentionally not part of v1.
Search
Autocomplete and filtered company search.
/autocomplete
Autocomplete companies by name
Low-latency typeahead returning minimal fields. Counts against your autocomplete allowance.
- q*
- string · query
- Partial company name.
- limit
- integer · query
{
"data": [
{
"kvkNumber": "01234567",
"name": "Acme Amsterdam B.V.",
"city": "Amsterdam",
"type": "hoofdvestiging"
}
],
"meta": {
"requestId": "req_a1b2c3",
"tookMs": 38
}
}
/companies
Search companies
Filtered, page-paginated company search. Pagination depth is capped per plan (see the 400 response); deep enumeration of the full dataset is the bulk/export product, not search. Counts against your basic-fetch allowance.
- name
- string · query
- city
- string · query
- postcode
- string · query
- sbi
- string · query
- SBI activity code.
- legalForm
- string · query
- status
- string · query
- pageSize
- integer · query
- Results per page. Capped by your plan's maximum.
- page
- integer · query
- 1-based page number. The deepest reachable page is bounded by your plan's pagination ceiling; see the search endpoint.
{
"data": [
{
"kvkNumber": "69599084",
"name": "Coolblue B.V.",
"city": "Rotterdam",
"legalForm": "Besloten Vennootschap",
"status": "active",
"type": "hoofdvestiging"
},
{
"kvkNumber": "24502593",
"name": "Coolblue Webshops B.V.",
"city": "Rotterdam",
"legalForm": "Besloten Vennootschap",
"status": "active",
"type": "hoofdvestiging"
}
],
"meta": {
"requestId": "req_a1b2c3",
"tookMs": 41,
"page": 1,
"pageSize": 25,
"hasMore": false
}
}
Companies
Company registry profiles (by KVK number).
/companies/{kvkNumber}
Get a company's basic profile
Returns the registry profile. Add include=enrichment to also return the enrichment block in one round trip; that consumes one enrichment credit and returns the credit headers. Counts against your basic-fetch allowance.
- kvkNumber*
- string · path
- 8-digit KVK number (string; leading zeros significant).
- include
- string · query
- Set to
enrichmentto embed the enrichment block (metered).
{
"data": {
"kvkNumber": "01234567",
"legalName": "Acme Amsterdam B.V.",
"tradeNames": [
"Acme",
"Acme Amsterdam"
],
"legalForm": "bv",
"status": "active",
"incorporationDate": "2014-03-11",
"sbiCodes": [
{
"code": "62010",
"description": "Ontwerpen en programmeren van computerprogramma's"
}
],
"mainEstablishment": {
"establishmentNumber": "000051435020",
"isMainEstablishment": true,
"visitingAddress": {
"street": "Keizersgracht",
"houseNumber": "123",
"postcode": "1015CJ",
"city": "Amsterdam",
"country": "NL"
},
"postalAddress": {
"street": "Postbus",
"houseNumber": "4321",
"postcode": "1000AB",
"city": "Amsterdam",
"country": "NL"
}
},
"establishmentCount": 1,
"enrichment": null
},
"meta": {
"requestId": "req_a1b2c3",
"tookMs": 22
}
}
Addresses
Dutch address autocomplete and postcode + house-number resolution.
/addresses/autocomplete
Autocomplete and resolve Dutch addresses
Typeahead and resolver over Dutch addresses, returning concrete resolved addresses. The query is parsed for an optional postcode, house number and suffix:
Damrak- addresses from the lowest house number upDamrak 47- the one street segment covering 47, as a concrete address1012 LK 47A- resolve that exact postcode + number, echoing47A1012 LK- that postcode's addresses from the lowest house number up
The postcode is normalized (1012 lg -> 1012LG). A house number outside every matching segment's range (or an unknown postcode) returns no results. Included with paid plans; not metered (address calls consume no monthly credits), authenticated and rate-limited.
- q*
- string · query
- Partial address - a street or postcode, optionally a house number (with suffix), optionally a city.
- limit
- integer · query
{
"data": [
{
"postcode": "1012 LK",
"houseNumber": "47",
"street": "Damrak",
"city": "Amsterdam",
"municipality": "Amsterdam",
"country": "NL"
}
],
"meta": {
"requestId": "req_a1b2c3",
"tookMs": 12
}
}
Establishments
Establishment (vestiging) profiles.
/companies/{kvkNumber}/establishments
List a company's establishments
- kvkNumber*
- string · path
- 8-digit KVK number (string; leading zeros significant).
- pageSize
- integer · query
- Results per page. Capped by your plan's maximum.
- page
- integer · query
- 1-based page number. The deepest reachable page is bounded by your plan's pagination ceiling; see the search endpoint.
{
"data": [
{
"establishmentNumber": "000019625863",
"kvkNumber": "69599084",
"isMainEstablishment": true,
"tradeNames": [
"Coolblue"
],
"visitingAddress": {
"street": "Weena 664",
"houseNumber": "664",
"postcode": "3012 CN",
"city": "Rotterdam",
"country": "NL"
},
"postalAddress": null
}
],
"meta": {
"requestId": "req_d4e5f6",
"tookMs": 22,
"page": 1,
"pageSize": 25,
"hasMore": false
}
}
/establishments/{establishmentNumber}
Get an establishment profile
- establishmentNumber*
- string · path
- 12-digit establishment number (string; leading zeros significant). Handelsregister term: vestigingsnummer.
{
"data": {
"establishmentNumber": "000019625863",
"kvkNumber": "69599084",
"isMainEstablishment": true,
"tradeNames": [
"Coolblue"
],
"visitingAddress": {
"street": "Weena 664",
"houseNumber": "664",
"postcode": "3012 CN",
"city": "Rotterdam",
"country": "NL"
},
"postalAddress": null
},
"meta": {
"requestId": "req_g7h8i9",
"tookMs": 18
}
}
Enrichment
Cached enrichment data. Metered.
/companies/{kvkNumber}/enrichment
Get cached enrichment for a company
Served from the cache. Consumes one enrichment credit, counted against your plan's monthly enrichment allowance. The payload carries its own asOf/source/stale recency markers.
- kvkNumber*
- string · path
- 8-digit KVK number (string; leading zeros significant).
{
"data": {
"website": [
"https://acme.nl"
],
"socialProfiles": {
"linkedin": "https://linkedin.com/company/acme",
"facebook": null,
"instagram": null,
"x": null
},
"email": [
"info@acme.nl"
],
"phone": [],
"rsin": "812345678",
"vat": {
"number": "NL001234567B01",
"valid": true,
"checkedAt": "2026-06-14T09:00:00Z"
},
"employees": {
"count": 48,
"band": "20-49"
},
"financials": [
{
"year": 2024,
"revenue": 1250000,
"totalAssets": 1680000
},
{
"year": 2023,
"revenue": 990000,
"totalAssets": 1420000
}
],
"people": null,
"asOf": "2026-06-10T02:00:00Z",
"source": "cache",
"stale": false
},
"meta": {
"requestId": "req_d4e5f6",
"tookMs": 31,
"creditsCost": 1,
"creditsRemaining": 1742
}
}
VAT
VAT (BTW) validation and resolution. Metered.
/vat/{vatNumber}
Validate a VAT (BTW) number and resolve it to a company
Validates a VAT (BTW) number against the EU VIES service and, when the trader name it returns confidently matches a company we hold, resolves it to that KVK entity and records the validation on file (kvkNumber is null when no confident match is found).
Included with paid plans, not metered. Because the result comes from the external VIES service - which can be slow, throttled or temporarily down - this endpoint doesn't consume an allowance. When VIES can't be reached, the last known answer (up to 7 days old) is served instead, marked stale: true in meta with checkedAt reflecting the original check; only when no prior answer exists does the response become 503 vies_unavailable (retry shortly), which is distinct from a number that VIES reports as invalid. Every response carries a disclaimer in meta noting the VIES dependency.
VIES protection. To keep the shared upstream healthy, lookups that reach VIES are capped independently of your plan's rate limit: 1/second per key plus a global ceiling across all keys (429 vies_throttled when exceeded). Results are cached for up to 24 hours, so repeat lookups of the same number are served instantly, don't count toward these caps, and are marked cached: true in meta with checkedAt reflecting the original VIES lookup.
- vatNumber*
- string · path
{
"data": {
"vatNumber": "NL001234567B01",
"valid": true,
"kvkNumber": "01234567",
"name": "Acme Amsterdam B.V.",
"countryCode": "NL",
"source": "VIES",
"checkedAt": "2026-07-02T10:15:00Z"
},
"meta": {
"requestId": "req_a1b2c3",
"tookMs": 240,
"cached": false,
"disclaimer": "VAT validation is performed against the external EU VIES service and reflects its response. Availability and results depend on VIES and are outside our control."
}
}
Account
Plan, limits and usage.
/usage
Current period usage and remaining allowances
{
"data": {
"plan": "growth",
"period": {
"start": "2026-06-01T00:00:00Z",
"resetsAt": "2026-07-01T00:00:00Z"
},
"autocomplete": {
"used": 4120,
"included": 30000
},
"basicFetch": {
"used": 1875,
"included": 25000
},
"enrichment": {
"used": 412,
"included": 1500
}
},
"meta": {
"requestId": "req_g7h8i9"
}
}
/me
Plan and limits for the authenticated key
{
"data": {
"plan": "growth",
"rateLimitPerSecond": 15,
"pageSizeMax": 50
},
"meta": {
"requestId": "req_j1k2l3"
}
}
Bouw als eerste op Companize
Meld je aan voor de wachtlijst voor vroege toegang, een gratis tier bij de lancering en updates onderweg. Geen spam, alleen het belangrijke nieuws.
We gebruiken je e-mailadres alleen om je over vroege toegang te informeren. Je kunt je altijd afmelden.