KVK Number, RSIN or VAT Number: Which ID to Store?
A Dutch company has a KVK number, an RSIN, a VAT number and a branch number. Learn which one to use as your primary key and how to link the rest.
You are designing a customer table and need a column that identifies a Dutch company. A colleague says “just use the VAT number”. Someone else says “the KVK number, obviously”. A third person mentions the RSIN. All three are right about something, and a wrong choice only shows up months later, when the first sole trader signs up and your VAT column stays empty.
This article compares the four numbers a Dutch company can have, explains what each one is good for, and ends with a data model that holds up in practice.
Four numbers, four jobs
The Dutch system does not have one company number but several, each issued for a different purpose. Mixing them up is the most common mistake in integrations with Dutch data.
The KVK number has 8 digits and identifies the registration in the Trade Register. The RSIN has 9 digits and identifies a legal entity for tax purposes. The VAT number looks like NL + 9 digits + B + 2 digits and identifies the VAT-liable unit. The branch number (vestigingsnummer) has 12 digits and identifies one location or branch of a company.
The practical split is easy to remember. The KVK number answers “does this company exist and who is it”, the VAT number answers “what do I put on the invoice”, the RSIN shows up in tax and reporting contexts, and the branch number answers “which location do we mean”. For the details of each, see our pages on the KVK number and the RSIN.
Why the KVK number is your primary key
If you can only store one number, store the KVK number. Every company in the Trade Register has one: a BV, a foundation, a partnership and a sole trader alike. It is public, it is stable, and it is what you can look up in the register at any time.
Compare that with the alternatives. The VAT number does not exist for every company, because someone who is not VAT-liable has none, and some entrepreneurs are exempt. The RSIN does not exist for sole traders at all. A name is not unique, as we showed in searching a Dutch company by name. The KVK number is the only identifier you will find on every record.
There is one catch: the number identifies the registration, not the person behind it. A sole trader who closes one business and starts another gets a new KVK number. If you want to follow a person over time, you need extra data from your own process, not from the register.
The RSIN and the VAT number are derived, not interchangeable
The most persistent myth is that the VAT number can be built from the KVK number as NL + KVK number + B01. It cannot. A KVK number has 8 digits, and the numeric block of a Dutch VAT number has 9, because it is the RSIN. For a BV or NV, NL + RSIN + B01 is a good candidate, but even that is a rule of thumb. A fiscal unity or a second subnumber breaks the pattern, so always check the result against VIES before it goes on an invoice. We explain the rule in detail in deriving a VAT number from a KVK number.
For sole traders the pattern does not apply at all. Since 2020 their VAT identification number is issued at random, deliberately unrelated to any other number, so it can be published without exposing a citizen service number. Such a company has a KVK number and a VAT number, but no RSIN and no way to derive one from the other.
This is why the KVKBase API returns the VAT number only for legal entities. When you ask for the extended profile with vat=true, a BV comes back with a validated VAT number, and a sole trader or VOF gets vat: null. That is not an error, it is how the register works.
curl "https://api.kvkbase.nl/v1/lookup/12345678?enrich=true&vat=true" \
-H "Authorization: Bearer your_api_key"
If you already have a VAT number from a customer, for example typed into a checkout form, you can check it separately for 1 token via /v1/validate/vat/{vatNumber}. The API reference lists all parameters.
A data model that holds up
Put the KVK number in a column of its own, as text and not as an integer, because leading zeros are possible. Make it unique per company record, or per customer account if you work B2B. Everything else hangs off it.
Store the VAT number in a separate nullable column, together with the date you last validated it. VAT numbers change status: a company can be deregistered for VAT while it is still in the Trade Register. A “validated on” date tells you how old your knowledge is, and it lets you re-check before a large invoice.
Keep the RSIN only if you actually need it, for instance for annual accounts or a tax integration, and store it as nullable too. Give branches their own table with a foreign key to the company and the 12-digit branch number as key. The difference between the two is covered in branch number versus KVK number.
create table company (
kvk_number text primary key,
name text not null,
rsin text,
vat_number text,
vat_checked_at timestamptz
);
create table branch (
branch_number text primary key,
kvk_number text not null references company (kvk_number)
);
Validate on the way in
A number someone typed is a claim, not a fact. Check the format first: a KVK number is exactly 8 digits, and our article on KVK number validation rules shows what you can and cannot check offline. Then look the number up, so you know the company exists, is active and has the name the customer says it has.
Do this once, at the moment the number enters your system, and store the result. After that you work with the KVK number internally and only look up fresh data when you need it, for example in a periodic refresh or when a status change is reported.
Summary
Use the KVK number as your key, treat the VAT number as an optional validated attribute, keep the RSIN if your use case calls for it, and give every branch its own record. That covers sole traders, BVs and everything in between without special cases in your code.
Want to see what a company looks like in all these numbers at once? Create a KVKBase account, look up a KVK number with enrich=true&vat=true and compare the identifiers in one response.