Dutch vehicle data, as an API and a daily feed.
Look up registrations, keep your own vehicle database current and analyse the register, with one API.
- We import RDW’s open data, join 16 datasets per registration and normalise the fields, so you don’t have to build and maintain that yourself.
- Changes come per registration and per field, with the old and the new value, ready to process.
- Try it here with a real registration, no account needed.
Prices are public on the plans page. Creating an account is free; you only pay once you activate a plan.
Try it with a real registration and see live answers from the API: what is known now, which changes we detected, and how many of that make and model are registered.
What RDW’s open data holds about this vehicle right now, in one request to the vehicle API.
GET /api/v1/vehicles/AB-123-C
The differences we found for this registration between successive versions of the open data, field by field with the old and the new value. The mutation feed gives you these changes for every registration, or only for yours.
GET /api/v1/mutations?registration=AB123C&limit=4
The feed has no changes to this registration in the last 90 days.
The changes can’t be fetched right now. That is down to the demo, not to this registration.
next_cursor
Store the cursor and carry on later where you left off.
This vehicle next to every other of the same make and model that can be registered to an owner, counted over the whole register.
There is no analysis to show for this vehicle right now: it has no make and model in the open data, or the analysis can’t be fetched at the moment.
GET /api/v1/analytics/vehicles
?filter[make]=…
&filter[trade_name]=…
&filter[registration_allowed]=true
&group_by=first_admission_date:year
&metrics=avg:catalog_price,median:catalog_price,
min:catalog_price,max:catalog_price
GET /api/v1/analytics/defects
?filter[make]=…
&filter[trade_name]=…
&filter[registration_allowed]=true
&limit=5
No defects have been found on this make and model at inspections yet.
The defects can’t be fetched right now. That is down to the demo, not to this vehicle.
· position
What you don’t have to build yourself
RDW’s open data is free, but turning it into a dependable data source is work that keeps coming back. We take that work off your hands.
- RDW imports
- Downloading millions of rows per dataset, checking them and retrying when it goes wrong. We check several times a day whether there is a new version.
- Joining datasets
- RDW keeps fuels, axles, bodies, inspections, defects and recalls in separate datasets. You get them per registration in one response.
- Normalising
- English field names, fixed types and the unit in the name, instead of text columns in varying notations.
- Detecting changes
- We compare every new version with the previous one and deliver the differences per registration and per field. No need to diff two full versions yourself.
One plate, six ways to use it
Whether a plate is typed into a form, read by a camera or stored in a fleet list, the API answers in one request and the feed shows what changed since the previous version of the open data.
-
Dealers, marketplaces and workshop software
Fill in a vehicle from its plate
Type a plate and the make, trade name, colour, fuel, first admission date and list price are there. Nothing to copy over from the registration card.
vehicle.make vehicle.model vehicle.colors.primary environment.fuels[0].type registration.first_admission_date
-
Garages, lease and fleet management
APK reminders and inspection history
Know when the APK of each vehicle expires and what was found at earlier inspections, and remind your customers in time.
inspections.apk.expiry_date inspections.odometer.judgement inspections.reports[] inspections.reports[].defects[]
-
Fleets, lease companies and insurers
Watch recalls and insurance
Follow the feed for your registrations and see an open recall, an export or the end of a liability insurance as soon as we have processed that change in RDW’s open data.
status.open_recall status.insured history.recalls[] GET /api/v1/mutations?registration=…
-
Anyone with a vehicle database of their own
Keep your own copy current
Load a snapshot once, then process the changes from the feed: every change names its field with the old and the new value, so you update rows instead of importing everything again.
snapshots GET /api/v1/mutations?after=… next_cursor
-
Valuation, import and lease calculations
Calculate with price and tax
List price, gross BPM, first admission date, fuel, CO₂ emissions and mass: the inputs for a valuation, a company car tax or an import calculation.
vehicle.fiscal.catalog_price_eur registration.first_admission_date environment.fuels[0].type technical.weights
-
Researchers and data teams
Analyse the whole register
Count and compare every vehicle in RDW’s open data in one request, by make, fuel or age, or count the defects found at inspections. Or download the register as JSONL or CSV, one file per dataset, and follow the feed.
GET /api/v1/analytics/vehicles GET /api/v1/analytics/defects snapshots CSV
From account to first answer in four steps
-
Create an account
An account is free and gives you access to the portal. You can send API requests once you have a plan.
-
Choose a plan
A monthly or yearly plan, or pay as you go without a fixed fee. You pay through Stripe; the prices are on the plans page.
-
Create an API key
One per application if you like, each with only the access it needs.
-
Send a request
The registration in the URL, your key as a Bearer token in the
Authorizationheader, and the vehicle comes back as JSON.
Following the feed works the same way: start from a snapshot and read on from its cursor. How the feed works
Request
curl https://api.kentekenfeed.nl/api/v1/vehicles/GLZ-84-H \
-H "Authorization: Bearer your-api-key" \
-H "Accept: application/json"
$vehicle = Http::withToken('your-api-key')
->acceptJson()
->get('https://api.kentekenfeed.nl/api/v1/vehicles/GLZ-84-H')
->json('data');
const response = await fetch('https://api.kentekenfeed.nl/api/v1/vehicles/GLZ-84-H', {
headers: { Authorization: 'Bearer your-api-key', Accept: 'application/json' },
});
const { data: vehicle } = await response.json();
import requests
response = requests.get(
"https://api.kentekenfeed.nl/api/v1/vehicles/GLZ-84-H",
headers={"Authorization": "Bearer your-api-key"},
)
vehicle = response.json()["data"]
Response 200 OK
{ "data": { "registration": { "plate": "GLZ84H", "first_admission_date": "2018-03-14" }, "vehicle": { "make": "VOLKSWAGEN", "model": "GOLF", "colors": { "primary": "ZWART" }, "fiscal": { "catalog_price_eur": 31625 } }, "environment": { "fuels": [{ "type": "Benzine", "power": { "net_max_kw": 110 } }] }, "status": { "insured": true, "open_recall": false }, "inspections": { "apk": { "expiry_date": "2027-11-18" }, "odometer": { "judgement": "Geen oordeel" } }, … }}
16 RDW vehicle datasets, in one answer
- datasets
- 16
- From the basic register to inspections, defects and recalls.
- fields in a vehicle response
- 180+
- Each with an English name, a fixed type and its unit in the name.
- names or addresses
- 0
- RDW’s open data has no owner details, so neither does KentekenFeed.
- Checked several times a day
- RDW decides when a dataset gets a new version. We check for one several times a day, and every response says per dataset when RDW published it and when we last checked.
- The same values everywhere
- API, feed and snapshots share types and units. The feed, the snapshots and analytics use the same field names per dataset; a lookup arranges those fields in sections, and every change in the feed says with
pathwhere its field is in it. - Honest about delays
- A dataset not checked in the last 36 hours is marked
stale: true, so you decide what to do with it. Ask forview=fulland a field RDW has no value for isnull.
Start with a free account
Prices are public on the plans page. An account is free; you only pay once you activate a plan, and you can cancel at any time.