Every endpoint of the KentekenFeed API, with its parameters, the fields it returns and its errors. The reference is generated from the same OpenAPI document the API is tested against, so it matches what the API answers.
Load the OpenAPI document into Postman or Insomnia, or generate a client from it.
Authorization: Bearer kf_live_… or X-Api-Key: kf_live_…. Create keys in the portal.
Errors
{"error": {"code", "message", "request_id", "details?"}}. code is stable; message is for people.
Formats
JSON. Timestamps in ISO-8601 UTC, dates as YYYY-MM-DD. Amounts are numbers in euros: in a vehicle with _eur in the name (catalog_price_eur), in analytics without (catalog_price). Every response has an X-Request-Id.
Vehicles
Look up a vehicle by its registration, and see which RDW datasets the API holds and how fresh they are.
Look up a vehicle
get/vehicles/{registration}
What RDW’s open data holds about one vehicle, by its registration: technical data, inspections, defects and recalls.
One vehicle (vehicles:read, plan with the vehicle API). Billed only on 200.
The vehicle.v1 record. Choose the view
(compact by default, full, or raw RDW names) and, for compact and full, the sections to include.
Invalid parameters are 422 validation_failed and are not billed.
Six letters and digits, separators allowed (AB-123-C).
viewquerystring
compact (default) leaves out fields RDW has no value for and empty collections; full returns every field (null when unavailable) and every collection; raw returns the typed values under RDW dataset and column names.
Values
compactfullraw
Default
compact
includequerystring
Comma-separated sections to return (vehicle, technical, environment, status, inspections, history); registration and metadata are always returned. Unknown names are a 422. Not with view=raw.
Example
technical,environment
Responses
200The vehicle, as {data} with the response metadata inside data.
Count, group and measure the vehicles in the register, or the defects found at inspections.
Fields you can filter, group and measure
Use these names in filter[…], group_by and metrics, for vehicles and for defects alike. They are the field names per dataset, the same as field in the feed; a vehicle response names the same fields differently (trade_name is vehicle.model there, catalog_price is vehicle.fiscal.catalog_price_eur). Fields from a linked dataset start with its name, such as fuels.fuel. GET /analytics/fields returns the same list.
Attributes (22)
Filter on one or more values and group by value. Yes/no fields take true or false.
makestring
Make.
trade_namestring
Trade name (model) given by the manufacturer.
vehicle_typestring
Kind of vehicle in RDW wording, e.g. "Personenauto" or "Bedrijfsauto".
body_stylestring
Body arrangement in RDW wording, e.g. "hatchback" or "stationwagen".
primary_colorstring
Main colour in RDW wording.
secondary_colorstring
Second colour in RDW wording.
european_vehicle_categorystring
European vehicle category, e.g. M1 or N1.
fuel_efficiency_classstring
Fuel efficiency label, A to G.
odometer_judgementstring
RDW judgement of the odometer history in RDW wording, e.g. "Logisch" or "Onlogisch".
insuredboolean
Whether third-party liability (WAM) insurance is registered; null when not applicable.
exportedboolean
Whether the vehicle has been exported.
taxiboolean
Whether the vehicle is registered as a taxi.
open_recallboolean
Whether a recall is open for the vehicle.
registration_allowedboolean
Whether the vehicle can currently be registered to an owner.
fuels.fuelstring
Fuel in RDW wording, e.g. "Benzine", "Diesel" or "Elektriciteit".
fuels.emission_codestring
Emission standard (Euro class) code.
fuels.hybrid_classstring
Hybrid class: OVC-HEV (externally chargeable) or NOVC-HEV.
bodies.body_type_descriptionstring
European description of the body type.
recalls.recall_codestring
RDW reference code of the recall campaign.
recalls.statusstring
Status as reported by the manufacturer, in RDW wording.
defects.defect_codestring
Code of the defect in the RDW defect catalogue.
defects.approval_typestring
Kind of approval of the inspection station.
Dates (5)
Filter on a period with gte, gt, lte or lt, and group by year or month.
first_admission_datedate
Date the vehicle was first admitted to the road, in any country.
first_registration_nl_datedate
Date the vehicle was first registered to an owner in the Netherlands.
registration_datedate
Date of the current registration to an owner (tenaamstelling).
apk_expiry_datedate
Date the periodic inspection (APK) expires.
defects.report_datedate
Date of the inspection report the defect belongs to.
Numbers (17)
Filter on a range and measure with avg, min, max, sum or median, such as metrics=median:catalog_price.
catalog_priceinteger
Catalogue price including VAT and BPM, in euros.
gross_bpminteger
Gross BPM (registration tax) at first registration, in euros.
empty_massinteger
Mass of the empty vehicle in kg.
curb_massinteger
Ready-to-drive mass (massa rijklaar) in kg.
max_massinteger
Permitted maximum mass in kg.
displacementinteger
Engine displacement in cc.
cylindersinteger
Number of cylinders.
seatsinteger
Number of seats, the driver included.
doorsinteger
Number of doors.
lengthinteger
Length in cm.
widthinteger
Width in cm.
wheelbaseinteger
Wheelbase in cm.
power_to_mass_rationumber
Power per ready-to-drive mass, in kW/kg.
fuels.co2_combined_wltpnumber
Combined CO2 emission in g/km (WLTP).
fuels.fuel_consumption_combined_wltpnumber
Combined fuel consumption in l/100 km (WLTP).
fuels.electric_range_electric_only_wltpnumber
Range of a pure electric vehicle in km (WLTP).
fuels.net_max_power_electricnumber
Net maximum electric power in kW.
Limits of one request
Up to 2 levels in group_by, outer first, such as make,trade_name.
Up to 100 groups per level with limit, 20 by default, largest first.
Up to 50 values per filter, separated by commas.
Up to 5 metrics, as operation:field with avg, min, max, sum or median.
Grouping a date by :month spans at most 120 months, with a filter on that date that has a start and an end.
List the fields
get/analytics/fields
The fields you can filter, group and measure, and the limits of one request. Free.
The fields analytics can filter, group and measure, the subjects and the limits (not billed)
Count the vehicles in the register, filtered and grouped as you choose, with averages, sums or medians. Exported and deregistered vehicles are counted; registration_allowed says whether a vehicle can be registered to an owner, not whether it may be on the road.
Count vehicles in the register, grouped and measured (vehicles:read, plan with analytics). One analytics query per 200.
Counts every vehicle in RDW's open register, exported and deregistered ones included
(filter[registration_allowed]=true for vehicles that can be on the road). A child dataset
field (fuels.fuel) filters on and groups by the vehicle's rows of that dataset, and count
is still vehicles. Answers are cached until the next sync; a cached answer is still billed.
filter[make]=TESLA,BMW (any of the values, any case; booleans take true/false), filter[first_admission_date][gte]=2020-01-01 (dates as YYYY-MM-DD and metrics take gte, gt, lte, lt). At most 50 values per field.
group_byquerystring
Up to 2 comma-separated fields, outer first, e.g. make,trade_name. Dates take :year or :month (month needs a filter on that date spanning at most 120 months).
metricsquerystring
Up to 5 comma-separated operation:field (avg, min, max, sum, median), e.g. avg:catalog_price.
limitqueryinteger
Groups per level, largest first.
Default
20
Minimum
1
Maximum
100
Responses
200The analytics.v1 answer.
Headers:X-RateLimit-LimitX-RateLimit-Remaining
dataobjectrequired
Fields (5)
countintegerrequired
Vehicles (subject vehicles) or defect findings (subject defects).
vehiclesinteger
Subject defects only: the distinct vehicles the counted defects were found on.
metricsmap of number | nullrequired
Keyed by the requested operation:field; null when no vehicle in the group has a value.
Count the defects found at inspections, by defect code or grouped as you choose, with the number of vehicles they were found on.
Count defects found at inspections, by defect code unless grouped otherwise (vehicles:read, plan with analytics). One analytics query per 200.
count is defect findings (one per defect row of an inspection report) and vehicles the
distinct vehicles they were found on. defects.* filters select the findings counted;
vehicle filters select the vehicles. Defect code groups carry the description and article
of the code's latest catalogue version.
filter[make]=TESLA,BMW (any of the values, any case; booleans take true/false), filter[first_admission_date][gte]=2020-01-01 (dates as YYYY-MM-DD and metrics take gte, gt, lte, lt). At most 50 values per field.
group_byquerystring
Up to 2 comma-separated fields, outer first, e.g. make,trade_name. Dates take :year or :month (month needs a filter on that date spanning at most 120 months).
metricsquerystring
Up to 5 comma-separated operation:field (avg, min, max, sum, median), e.g. avg:catalog_price.
limitqueryinteger
Groups per level, largest first.
Default
20
Minimum
1
Maximum
100
Responses
200The analytics.v1 answer.
Headers:X-RateLimit-LimitX-RateLimit-Remaining
dataobjectrequired
Fields (5)
countintegerrequired
Vehicles (subject vehicles) or defect findings (subject defects).
vehiclesinteger
Subject defects only: the distinct vehicles the counted defects were found on.
metricsmap of number | nullrequired
Keyed by the requested operation:field; null when no vehicle in the group has a value.
Start with a snapshot of the whole register, then read the changes from its cursor and keep up. A change is a difference between two successive versions of RDW’s open data. Batches show what each import brought; mutation files put a day of changes in one file.
How cursors work
A cursor is a bookmark in the feed. Every change has a position, a number that only goes up. A cursor marks a position, and GET /mutations?after=<cursor> returns the changes that came after it, oldest first.
Reading the feed page by page
GET /mutations?after=CURSOR_1→ 1,000 changes · next_cursor: CURSOR_2 · has_more: true
GET /mutations?after=CURSOR_2→ 412 changes · next_cursor: CURSOR_3 · has_more: false
later: GET /mutations?after=CURSOR_3→ the changes imported since
Where you get a cursor
cursor of a snapshot: where the snapshot ends. Start here after loading its files.
GET /mutations/checkpoint: the newest change. Start here to follow the feed from now on.
meta.next_cursor of every page of /mutations: where that page ends. Continue here.
start_cursor of a batch: where one import begins, to read that import again.
No after at all: from the oldest change the feed still holds.
Good to know
Save next_cursor once you have processed a page, also when data is empty, and continue from it next time. When has_more is false you are up to date; new batches arrive a few times a day.
Store a cursor as it is. It is a sealed string: you cannot build or change one yourself.
A cursor only works with the filters it came with (registration, dataset, type). Other filters give 400 cursor_filter_mismatch; to change filters, start from a checkpoint with the new ones.
Following next_cursor never skips a change. After an error you may get a change twice: skip an id you already processed.
The feed holds changes for 90 days. An older cursor gives 410 cursor_expired; start again from the latest snapshot.
A range mutation file takes two cursors: the changes after after up to until.
Read changes
get/mutations
The detected changes in order, page by page from a cursor. Keep the last cursor and continue from it next time.
mutation.v1 records in position order (mutations:read, plan with the feed). Not billed.
The vehicle.v1 record: the register and its child datasets arranged in sections.
In the compact view (default) a field is either absent or has a value: null fields and empty
collections are left out, false and 0 are kept. In the full view every field is present (null when
RDW has no value) and every collection is present (empty when there are no records). include limits the
response to the named sections; registration and metadata are always present. Field names, units and
nesting are the same in both views. Units are RDW's own (cm, kg, kW, km/h, g/km, l/100 km, Wh/km, km, dB(A),
rpm, l, EUR) and are named in the field.
Fuels and energy sources with power, emissions, consumption, range and noise per record. NEDC and WLTP figures are separate fields; weighted figures (plug-in hybrids) are separate from combined ones.
fuel_efficiency_classstring | null
Fuel efficiency label, A to G.
gas_installation_typestring | null
Type of gas (LPG/CNG) installation.
fuelsarray of object
Fields (9)
sequenceinteger | null
Order of this fuel for the vehicle.
typestring | null
Fuel in RDW wording, e.g. "Benzine", "Diesel" or "Elektriciteit".
Electric consumption of a pure electric vehicle (WLTP, Wh/km).
external_charging_wltp_wh_per_kmnumber | null
Electric consumption of an externally chargeable hybrid (WLTP, Wh/km).
rangeobject
Fields (4)
electric_kmnumber | null
Electric range (km).
external_charging_kmnumber | null
Electric range of an externally chargeable vehicle (km).
electric_only_wltp_kmnumber | null
Range of a pure electric vehicle (WLTP, km).
external_charging_wltp_kmnumber | null
Electric range of an externally chargeable hybrid (WLTP, km).
noiseobject
Fields (3)
driving_dbnumber | null
Noise level while driving (dB(A)).
stationary_dbnumber | null
Noise level when stationary with the engine running (dB(A)).
measurement_rpmnumber | null
Engine speed during the stationary noise measurement (rpm).
VehicleHistory
Dated records: objects added to the vehicle and recalls with their status.
added_objectsarray of object
Fields (8)
typestring | null
Kind of object, e.g. "LPG Installatie" or "Tachograaf".
makestring | null
Make of the object.
make_codestring | null
Make code of the object.
version_sequenceinteger | null
Version sequence number of the object.
classificationstring | null
Classification of the object.
mounted_datestring (date) | null
Date the object was mounted.
removed_datestring (date) | null
Date the object was removed.
gas_tank_capacity_lnumber | null
Capacity of the gas tank (l).
recallsarray of object
Fields (3)
codestring | null
RDW reference code of the recall campaign (referentiecode_rdw).
statusobject
Fields (2)
codestring | null
Status code: O for open, P when the manufacturer reports the vehicle as repaired, or another RDW code.
descriptionstring | null
Status as reported by the manufacturer, in RDW wording.
campaignobject | null
The recall campaign from the RDW recall register, or null when it is not in the register. Its code is the recall's code.
Fields (17)
published_datestring (date) | null
Date RDW published the recall in its register.
reporting_partystring | null
Manufacturer or distributor that reported the recall.
manufacturer_referencestring | null
The manufacturer's own code for the recall.
defect_descriptionstring | null
Description of the defect the recall is for.
defect_categorystring | null
Part of the vehicle the defect concerns.
consequencesstring | null
Consequences of the defect the user may notice.
remedystring | null
What is done to repair the defect.
risk_assessmentstring | null
RDW risk assessment of the defect.
remarksstring | null
Additional remarks from RDW.
info_urlstring | null
Website with more information from the manufacturer or distributor.
info_phonestring | null
Phone number for more information.
announced_datestring (date) | null
Date the manufacturer announced the recall.
reported_datestring (date) | null
Date the recall was reported to RDW.
owners_to_be_informed_datestring (date) | null
Date by which owners are to be informed.
owners_informed_datestring (date) | null
Date owners were informed.
vehicles_totalinteger | null
Number of vehicles in the recall worldwide.
vehicles_nationalinteger | null
Number of vehicles in the recall in the Netherlands.
VehicleIdentity
Identity, classification, appearance, body and type approval.
typestring | null
Kind of vehicle (voertuigsoort) in RDW wording, e.g. "Personenauto", "Bedrijfsauto", "Motorfiets" or "Aanhangwagen".
makestring | null
Make.
modelstring | null
Trade name (handelsbenaming) as registered by RDW, used as the model name.
colorsobject
Fields (2)
primarystring | null
Main colour in RDW wording.
secondarystring | null
Second colour in RDW wording.
bodyobject
Fields (6)
stylestring | null
Body arrangement in RDW wording, e.g. "hatchback" or "stationwagen".
extended_cabboolean | null
Whether the cab is extended.
aerodynamic_devices_codestring | null
Code for aerodynamic devices fitted, as recorded by RDW.
typesarray of object
Fields (5)
sequenceinteger | null
Sequence number of the body; specifications and classes are those of this body.
codestring | null
European body type code, e.g. AB.
descriptionstring | null
European description of the body type.
specificationsarray of object
Fields (3)
sequenceinteger | null
Sequence number of the specification.
codestring | null
European body code of an approved complete or completed vehicle.
descriptionstring | null
European description of the specification.
classesarray of object
Fields (3)
sequenceinteger | null
Sequence number of the class.
codestring | null
Vehicle class code set at approval.
descriptionstring | null
Description of the vehicle class.
unmatched_specificationsarray of object
Body specifications whose body_sequence matches no body in types.
Fields (4)
body_sequenceinteger | null
Sequence number of the body this belongs to.
sequenceinteger | null
Sequence number of the specification.
codestring | null
European body code of an approved complete or completed vehicle.
descriptionstring | null
European description of the specification.
unmatched_classesarray of object
Vehicle classes whose body_sequence matches no body in types.
Fields (4)
body_sequenceinteger | null
Sequence number of the body this belongs to.
sequenceinteger | null
Sequence number of the class.
codestring | null
Vehicle class code set at approval.
descriptionstring | null
Description of the vehicle class.
seatsinteger | null
Number of seats, the driver included.
passenger_seats_legalinteger | null
Legal number of passenger seats.
standing_placesinteger | null
Number of standing places.
wheelchair_placesinteger | null
Number of wheelchair places.
doorsinteger | null
Number of doors.
wheelsinteger | null
Number of wheels.
categoryobject
Fields (5)
europeanstring | null
European vehicle category, e.g. M1 or N1.
european_additionstring | null
Addition to the European vehicle category.
european_version_additionstring | null
Addition to the European category of the version.
national_subcategorystring | null
Dutch subcategory of the vehicle.
european_subcategoriesarray of object
Fields (3)
sequenceinteger | null
Sequence number of the subcategory.
codestring | null
European code for the special-purpose body type.
descriptionstring | null
Description of the subcategory.
type_approvalobject
Fields (6)
typestring | null
Type code from the type approval.
variantstring | null
Variant code from the type approval.
versionstring | null
Version (uitvoering) code from the type approval.
numberstring | null
EU or national type approval number.
amendment_sequenceinteger | null
Sequence number of the amendment to the EU type approval.
designation_numberstring | null
Designation number (aanwijzingsnummer), where one applies.
chassis_number_locationstring | null
Where the chassis number (VIN) is stamped.
fiscalobject
Fields (2)
catalog_price_eurinteger | null
Catalogue price including VAT and BPM (EUR).
gross_bpm_eurinteger | null
Gross BPM (registration tax) at first registration (EUR).
particularsarray of object
Fields (5)
sequenceinteger | null
Sequence number of the particular.
codeinteger | null
Code of the particular.
descriptionstring | null
Description of the code, e.g. "Wielbasis:".
valuestring | null
Variable text completing the description, e.g. "1155-1825".
unitstring | null
Unit of the value, e.g. "cm".
VehicleInspections
Current expiry dates, the odometer judgement and the inspection reports with their defects.
apkobject
Fields (1)
expiry_datestring (date) | null
Date the periodic inspection (APK) expires.
tachographobject
Fields (1)
expiry_datestring (date) | null
Date the tachograph inspection expires.
odometerobject
Fields (3)
last_registration_yearinteger | null
Year the odometer reading was last registered.
judgementstring | null
RDW judgement of the odometer history in RDW wording, e.g. "Logisch" or "Onlogisch".
explanation_codestring | null
Code explaining the odometer judgement.
inspection_registerarray of object
Records of RDW's separate inspection register (dataset Keuringen): the current inspection expiry as that register has it, normally one record with the same date as apk.expiry_date.
Fields (1)
expiry_datestring (date) | null
Date the current inspection expires.
reportsarray of object
Fields (6)
report_datestring (date) | null
Date the inspection station filed the report.
report_timestring | null
Time the report was filed, as HH:MM. Date, time and approval type code together identify a report.
approval_typeobject
Fields (2)
codestring | null
Code of the kind of approval the inspection station holds.
descriptionstring | null
Kind of approval, e.g. "APK Lichte voertuigen" or "APK Zware voertuigen".
report_typestring | null
Kind of report, e.g. a periodic inspection.
expiry_datestring (date) | null
Inspection expiry date resulting from this report.
defectsarray of object
Fields (4)
codestring | null
Code of the defect in the RDW defect catalogue.
countinteger | null
How many times the defect was found.
descriptionstring | null
Description of the defect.
article_numberstring | null
Article number in the inspection rules.
unmatched_defectsarray of object
Defects whose report (same date, time and approval type code) is not in the register, kept here with their own report fields instead of being attached to another report.
Fields (7)
report_datestring (date) | null
Date of the inspection report the defect belongs to.
report_timestring | null
Time of the inspection report, as HH:MM.
approval_typeobject
Fields (2)
codestring | null
Code of the kind of approval the inspection station holds.
descriptionstring | null
Kind of approval of the inspection station.
codestring | null
Code of the defect in the RDW defect catalogue.
countinteger | null
How many times the defect was found.
descriptionstring | null
Description of the defect.
article_numberstring | null
Article number in the inspection rules.
VehicleMetadata
About this response: schema, source, which view and sections, and how fresh the data is.
schema_version"vehicle.v1"required
Public schema version of the record. A breaking change gets a new version; additive changes do not.
source"RDW"required
The data source: RDW open data (opendata.rdw.nl). GET /datasets names the datasets.
viewstringrequired
The view this response is in.
Values
compactfullraw
sectionsarray of string | nullrequired
Sections in this response, in order (registration always); null in the raw view.
data_versionstringrequired
Hash of the synced dataset versions the record was built from; changes with every sync.
stalebooleanrequired
True when any dataset in datasets is stale (see Freshness). Stale data is still served.
retrieved_atstring (date-time)required
When this response was produced (UTC). Not a data timestamp: see datasets for RDW publication (source_published_at) and sync (last_checked_at) times.
Freshness per dataset (public name): when RDW published the version served, when the sync last checked RDW, and whether it is stale.
VehicleRaw
The raw view (view=raw): the same typed values under RDW's own dataset and column names, for
customers who know RDW's open data. One key per RDW dataset: the register as an object, each child
dataset as a list of objects; every mapped column present, null when RDW has no value. Columns the API never
exposes (RDW API links, columns RDW does not fill) are absent. Enrichments appear under the reference
dataset's names: gebrek_omschrijving and gebrek_artikel_nummer in geconstateerde_gebreken,
terugroep_actie (object or null) in terugroepacties.