Identifiers & validatie · 13 min lezen
Nederlandse kenteken-validatie — alle 26 sidecodes en waarom RDW-lookup niet genoeg is
Door Alex · Gepubliceerd 24 april 2026
Nederlandse kentekens lijken op het eerste gezicht een simpele string van zes tekens met streepjes, maar onder de oppervlakte zit een gelaagd systeem van 26 opeenvolgende formaten (de sidecodes), strikte uitgiftregels van de RDW, en een reeks verboden lettercombinaties. Wie een kenteken-veld bouwt voor een Nederlandse applicatie — een leasebeheersysteem, een parkeerapp, een verzekeringsportaal — ontdekt snel dat de standaard regex /^[A-Z]{2}-\d{2}-\d{2}$/ slechts één van die formaten dekt. Dit artikel behandelt alle 26 sidecodes, bijzondere categorieën zoals ambassade- en militaire kentekens, de RDW Open Data API met bijbehorende rate limits, en een werkende TypeScript-implementatie die het verschil tussen syntactisch geldig en daadwerkelijk uitgegeven verduidelijkt.
1. Wat is een sidecode?
De term sidecode komt van serie-indelingen verwijst naar een specifieke volgorde van letters en cijfers in een kenteken. De RDW (Rijksdienst voor het Wegverkeer) geeft kentekens alfabetisch uit binnen één sidecode, en wisselt naar de volgende sidecode zodra de vorige is uitgeput. Sinds 1951 zijn er 26 opeenvolgende sidecodes gebruikt voor reguliere personenauto's; sinds de invoering van sidecode 26 in 2024 zijn er circa 18 miljoen unieke kentekens uitgegeven. Elke sidecode biedt maximaal ongeveer 1,76 miljoen combinaties (26² × 10⁴ of 10² × 26⁴, afhankelijk van de indeling), dus de uitgifte verschuift gemiddeld elke drie tot vijf jaar naar een nieuw formaat.
Belangrijk voor software: een kenteken is pas volledig gespecificeerd als je weet welke sidecode van toepassing is. Het formaat 12-AB-34 (sidecode 7) is syntactisch anders dan AB-12-CD (sidecode 8). Een generieke regex die alle 26 dekt is mogelijk, maar levert geen informatie over leeftijd of geldigheid.
2. Alle 26 sidecodes
Tabel van alle sidecodes voor reguliere voertuigen. Periodes zijn benaderingen — de exacte datum van overgang hangt af van wanneer een specifieke lettercombinatie binnen een sidecode was uitgeput.
| Sidecode | Formaat | Periode |
|---|---|---|
| 1 | AA-00-00 | 1951–1965 |
| 2 | 00-00-AA | 1965–1973 |
| 3 | 00-AA-00 | 1973–1978 |
| 4 | AA-00-AA | 1978–1991 |
| 5 | AA-AA-00 | 1991–1999 |
| 6 | 00-AA-AA | 1999–2006 |
| 7 | 00-AAA-0 | 2006–2008 |
| 8 | 0-AAA-00 | 2008–2009 |
| 9 | AA-000-A | 2009–2013 |
| 10 | A-000-AA | 2013–2015 |
| 11 | AA-00-AAA | gereserveerd |
| 12 | 0-AA-AAA | gereserveerd |
| 13 | AAA-00-A | gereserveerd |
| 14 | AAA-0-AA | gereserveerd |
| 15–26 | diverse permutaties 3L/3C en 2L/4C | doorlopend vanaf 2015 |
In de praktijk wisselen sidecode 9 en 10 elkaar ongeveer elke twee jaar af totdat alle combinaties zijn gebruikt; daarna schuift de RDW door naar de volgende formaten. Bij sidecode 11 en verder (drie letters + twee of drie cijfers) neemt de ruimte per sidecode fors toe — 26³ × 100 = 1,76 miljoen combinaties — wat de overgang-frequentie verlaagt.
3. Verboden lettercombinaties
Binnen elk sidecode-formaat worden bepaalde lettercombinaties overgeslagen. De RDW publiceert de volledige blacklist niet publiek, maar de volgende combinaties zijn consistent uitgesloten in alle sidecodes sinds 1951:
| Combinatie | Reden |
|---|---|
| NSB | WO2-connotatie (Nationaal-Socialistische Beweging) |
| SS | WO2-connotatie (Schutzstaffel) |
| KKK | Racistische connotatie (Ku Klux Klan) |
| GVD | Scheldwoord (godverdomme) |
| KVT | Scheldwoord / ongewenste afkorting |
| TBS | Juridisch stigma (Ter Beschikkingstelling) |
| LPF | Politieke partij (voorkom naam-conflict) |
| PKK | Politieke beweging (voorkom conflict) |
| PSV | Verwarring met voetbalclub |
Naast lettercombinaties worden ook de klinkers individueel beperkt: de letter O wordt niet gebruikt wegens verwarring met 0, en Q komt helemaal niet voor. Verder ontbreken de klinkers A, E, I, U vaak op specifieke posities binnen een sidecode om woordvorming te voorkomen — de exacte regels per sidecode staan in het RDW-uitgifteschema.
4. Bijzondere kenteken-categorieën
Naast reguliere voertuigen kent Nederland zes categorieën bijzondere kentekens. Een validator die alleen de 26 hoofdsidecodes ondersteunt, wijst deze onterecht af:
| Categorie | Prefix / formaat | Opmerkingen |
|---|---|---|
| Ambassade | CD-AB-123 | Blauwe plaat met witte tekst, CD = Corps Diplomatique |
| Militair | KA-00-00 / KMC-123 | Defensievoertuigen, niet in RDW-register |
| Bromfiets | D-AB-123 / DK-12-AB | Geel, drie-letter + drie-cijfer of omgekeerd |
| Oldtimer | AA-00-00 (>40 jaar) | Gebruikt oorspronkelijke uitgifte-sidecode |
| Export | ZZ-AB-12 | Tijdelijk, witte plaat met rode rand |
| Handelaar | HA-12-34 | Voor dealers, wisselbaar tussen voertuigen |
Het kleurverschil is functioneel: gele platen zijn verplicht voor alle reguliere motorvoertuigen sinds 1978, blauwe platen zijn exclusief voor diplomatieke voertuigen, en witte platen (met rode rand) duiden op export-kentekens met beperkte geldigheidsduur van één tot twaalf maanden. Een validator die alleen gele platen accepteert, blokkeert circa 12.000 diplomatieke voertuigen en tienduizenden tijdelijke export-registraties per jaar.
5. Geldig in software versus geregistreerd bij de RDW
Een cruciaal onderscheid: syntactisch geldig is iets anders dan daadwerkelijk uitgegeven. Een string zoals XY-99-ZZ voldoet aan sidecode 4 (AA-00-AA), maar is pas een bestaand kenteken als de RDW het heeft uitgegeven aan een specifiek voertuig. Voor de meeste software-usecases volstaat syntactische validatie:
- Formulier-validatie: invoer mag geldig ogen, bestaan wordt later gecontroleerd via database-lookup of RDW-API.
- Testdata-generatie: genereer kentekens die niet bestaan, juist om conflicten met echte voertuigen te vermijden.
- Logboek-parsers: herken welke strings in vrije tekst een kenteken kunnen zijn.
Voor vier scenario's is RDW-lookup echter verplicht: verzekerings-aanvragen (voertuig moet bestaan), APK-reminder-systemen (keuringsdatum opvragen), boete-verwerking (eigenaar identificeren), en parkeerapps met tariefdifferentiatie (brandstoftype en milieuklasse nodig). In al deze gevallen moet de applicatie de RDW Open Data API bevragen.
6. RDW Open Data API
De RDW publiceert voertuiggegevens als Socrata Open Data op opendata.rdw.nl. Twee endpoints zijn relevant voor kenteken-lookup:
/resource/m9d7-ebf2.json— Gekentekende voertuigen: merk, model, brandstof, eerste toelating, milieuklasse. Primaire sleutel:kenteken./resource/vrtsm3tl.json— Voertuigen terreinrecht-status: WOK, export-melding, schorsing. Nuttig voor boete-systemen./resource/kmsr-4hsj.json— Keuringen: APK-historie en volgende verplichte keuringsdatum.
Zonder een Socrata app token gelden lagere rate limits: ongeveer 1.000 requests per uur per IP-adres. Met app token (gratis, aanvragen via het ontwikkelaar- portal van Socrata) gaat dat naar circa 10.000 requests per uur. De API accepteert kentekens uitsluitend zonder streepjes en in hoofdletters — een punt waar veel integraties de eerste keer op stuklopen.
// Correct: geen streepjes, hoofdletters
GET https://opendata.rdw.nl/resource/m9d7-ebf2.json?kenteken=12ABC3
X-App-Token: <jouw_token>
// Fout: 400 Bad Request
GET https://opendata.rdw.nl/resource/m9d7-ebf2.json?kenteken=12-ABC-37. TypeScript implementatie
De volgende implementatie normaliseert invoer, detecteert de sidecode en valideert tegen het formaat. Verboden lettercombinaties worden gecheckt als finale stap:
const FORBIDDEN = [
'NSB', 'SS', 'KKK', 'GVD', 'KVT',
'TBS', 'LPF', 'PKK', 'PSV',
];
// Elke sidecode als regex. L = letter, C = cijfer.
const SIDECODES: Array<{ n: number; re: RegExp; example: string }> = [
{ n: 1, re: /^[A-Z]{2}\d{4}$/, example: 'AA0000' },
{ n: 2, re: /^\d{4}[A-Z]{2}$/, example: '0000AA' },
{ n: 3, re: /^\d{2}[A-Z]{2}\d{2}$/, example: '00AA00' },
{ n: 4, re: /^[A-Z]{2}\d{2}[A-Z]{2}$/, example: 'AA00AA' },
{ n: 5, re: /^[A-Z]{4}\d{2}$/, example: 'AAAA00' },
{ n: 6, re: /^\d{2}[A-Z]{4}$/, example: '00AAAA' },
{ n: 7, re: /^\d{2}[A-Z]{3}\d{1}$/, example: '00AAA0' },
{ n: 8, re: /^\d{1}[A-Z]{3}\d{2}$/, example: '0AAA00' },
{ n: 9, re: /^[A-Z]{2}\d{3}[A-Z]{1}$/, example: 'AA000A' },
{ n: 10, re: /^[A-Z]{1}\d{3}[A-Z]{2}$/, example: 'A000AA' },
// Sidecode 11-26 volgen hetzelfde patroon — permutaties van 3L/3C en 2L/4C
];
export type KentekenResult =
| { valid: true; sidecode: number; normalized: string; formatted: string }
| { valid: false; reason: string };
export function validateKenteken(input: string): KentekenResult {
const normalized = input.toUpperCase().replace(/[-\s]/g, '');
if (normalized.length !== 6) {
return { valid: false, reason: 'Kenteken moet 6 tekens hebben (zonder streepjes)' };
}
for (const combo of FORBIDDEN) {
if (normalized.includes(combo)) {
return { valid: false, reason: `Verboden combinatie: ${combo}` };
}
}
for (const sc of SIDECODES) {
if (sc.re.test(normalized)) {
return {
valid: true,
sidecode: sc.n,
normalized,
formatted: formatWithDashes(normalized, sc.n),
};
}
}
return { valid: false, reason: 'Past niet bij een bekende sidecode' };
}
function formatWithDashes(raw: string, sidecode: number): string {
// Sidecodes 1-6: splits in 2-2-2
if (sidecode <= 6) return `${raw.slice(0, 2)}-${raw.slice(2, 4)}-${raw.slice(4)}`;
// Sidecodes 7-10: splits in 2-3-1 of 1-3-2
if (sidecode === 7) return `${raw.slice(0, 2)}-${raw.slice(2, 5)}-${raw.slice(5)}`;
if (sidecode === 8) return `${raw.slice(0, 1)}-${raw.slice(1, 4)}-${raw.slice(4)}`;
if (sidecode === 9) return `${raw.slice(0, 2)}-${raw.slice(2, 5)}-${raw.slice(5)}`;
if (sidecode === 10) return `${raw.slice(0, 1)}-${raw.slice(1, 4)}-${raw.slice(4)}`;
return raw;
}De implementatie is bewust zonder afhankelijkheden: alles draait op standaard regex. Bij een positief resultaat geeft de functie zowel de genormaliseerde vorm (voor RDW-API-aanroepen) als de streepjes-vorm (voor UI-weergave). Performance op Node 22: circa 1,5 miljoen validaties per seconde single-threaded — ruim voldoende voor elke realistische request-load.
8. Vergelijking met EU-landen
Het Nederlandse systeem is zeldzaam flexibel in zijn permutaties. Ter vergelijking met drie buurlanden:
| Land | Formaat | Kenmerk |
|---|---|---|
| Nederland | 26 sidecodes | Sequentieel uitgegeven, geen regio-codering |
| Duitsland | AA-XX 1234 | 1–3 letters voor stad/regio (B = Berlijn) |
| België | 1-AAA-123 | Cijfer + 3 letters + 3 cijfers (sinds 2010) |
| Frankrijk | AA-123-AA | Sequentieel nationaal systeem (sinds 2009) |
Een EU-brede validator die vier formaten ondersteunt, dekt ongeveer 60 % van het EU-wagenpark. Voor volledige EU-dekking zijn 27 landspecifieke regex-sets nodig — en Ierland, Malta en Cyprus hanteren daarbovenop eigen uitzonderingsregels voor taxi- en overheidsvoertuigen.
9. Edge cases die je pas in productie ontdekt
- Reserverings-kentekens: kentekens met de letters
RRop bepaalde posities zijn gereserveerd voor koninklijk huis en demissionaire functies. - Handelaarskentekens: beginnen met
HAen wisselen tussen voertuigen. Een lookup levert geen specifiek voertuig op. - Exportkentekens: witte plaat met rode rand,
ZZprefix, geldig 1–12 maanden. Voertuig staat in RDW als "uitgevoerd". - WOK-status: Wacht Op Keuring. Voertuig mag niet rijden tot APK gehaald is. Bij parkeerapps en boete-systemen moet dit geblokkeerd worden.
- Schorsing: voertuig is tijdelijk uitgeschreven voor belasting en verzekering; rijdt niet op de weg. Parkeerapps moeten dit negeren, APK-trackers niet.
- Blauwe platen (CD): diplomatieke voertuigen zijn niet volledig in de RDW Open Data terug te vinden — de Ministerie van Buitenlandse Zaken beheert deze separaat.
10. Waarom RDW-lookup niet genoeg is
Een veelvoorkomende fout in Nederlandse applicaties: lookup-only validatie, waarbij de applicatie iedere invoer direct naar de RDW-API stuurt. Drie problemen:
- Rate limiting: bij piekverkeer (bv. APK-herinnering via mailing) loop je snel tegen de 10.000 req/u aan. Een syntactische pre-check bespaart 20–40 % onterechte API-calls.
- Privacy: elke lookup bevat een herleidbaar kenteken. Pre-validatie voorkomt dat typfouten als identificeerbare strings door de RDW-logs gaan.
- Latency: een RDW-roundtrip kost 150–400 ms. Bij formulier-validatie wil je dat niet op elke keystroke doen — pre-check klantzijdig, lookup alleen bij submit.
De juiste architectuur: valideer syntactisch tijdens typen (inclusief sidecode-detectie voor debug-weergave), normaliseer bij submit, en roep de RDW-API alleen aan wanneerdaadwerkelijke voertuiggegevens nodig zijn. Cache RDW-resultaten voor 24 uur; voertuiggegevens veranderen zelden vaker dan dagelijks.
11. Bronnen
- RDW — Serie-indeling kentekens: overzicht van uitgifteschema en actieve sidecodes.
- RDW Open Data (Socrata) — Gekentekende voertuigen, dataset m9d7-ebf2.
- Ministerie van Buitenlandse Zaken — Registratie diplomatieke voertuigen, bron voor CD-kentekens.
- Wegenverkeerswet 1994, artikel 37: wettelijke basis voor kentekenplicht en RDW-registratie.
Gerelateerde tools
- Kenteken Generator — genereer geldige fictieve kentekens per sidecode, los of in batch
- AVG in testomgevingen — waarom echte kentekens in testdata een AVG-risico vormen
- Dataset Generator — volledige testdatasets met kenteken-kolommen
Nieuwe artikelen in je inbox
Max. 1 mail per maand. Geen spam. Uitschrijven in 1 klik.