Key

Every call needs your key in the Authorization header as a Bearer token. The key is secret: use it from your own server, never in code that runs in the browser.

Authorization: Bearer YOUR_KEY

Get a free key

Endpoints

GET /v1/plates/{country}/{plate}

Looks up a number plate. country is DK or NL. Upper or lower case, spaces and dashes in the plate do not matter.

GET /v1/catalog/{country}/makes

Every make in a country with its number of vehicles, most first. country is dk, nl, fi or all (the sum of the countries). Finland is in the catalogue only, not in lookups. Slugs are the same in every country.

GET /v1/catalog/{country}/makes/{make_slug}/models

Every model of a make, gathered across the registers, so ID.3 and ID.3 Pro 150 kW are one model. make_slug is the slug from the list of makes. A country only shows models with vehicles in that country.

Without ?type= the catalogue shows cars and vans (car,van). You can give one or more vehicle types separated by commas, e.g. ?type=motorcycle. The catalogue only has car, van and motorcycle, and a model needs at least 100 vehicles in total. The response may be cached for a day.

Catalogue response

[
  { "name": "Volkswagen", "slug": "volkswagen", "count": 312456 },
  { "name": "Toyota", "slug": "toyota", "count": 254321 },
  …
]

Fields

The response always has every field. A field with no value is null. Text fields are in the language of the source (Danish from the Danish Motor Register, Dutch from RDW), while the _code fields are the same for both countries. Dates are YYYY-MM-DD. We never provide information about the owner.

FieldTypeExampleCountriesDescription
country string "DK" DK · NL The country from the address: DK or NL.
plate string "AB12345" DK · NL The number plate in capitals, without spaces or dashes.
make string "Volkswagen" DK · NL Make.
model string "Golf" DK · NL Model.
variant string "1.5 TSI EVO 150 DSG7" DK Variant, as written in the register.
make_slug string "volkswagen" DK · NL The make as a slug, as in the register.
model_slug string "golf" DK · NL The model as a slug, as in the register.
catalog_make_slug string "volkswagen" DK · NL The make in the catalogue. null if the make is not in the catalogue.
catalog_model_slug string "golf" DK · NL The model in the catalogue, e.g. id-3 for an ID.3 Pro 150 kW. null if the model is not in the catalogue.
vehicle_type string "Personbil" DK · NL Vehicle type in the language of the source.
vehicle_type_code string "car" DK · NL Vehicle type as a code. See the codes below.
body_type string "Stationcar" DK · NL Body type in the language of the source.
colour string "Rød" DK · NL Colour in the language of the source.
colour_code string "red" DK · NL Colour as a code.
doors integer 5 DK · NL Number of doors.
seats integer 5 DK · NL Number of seats, including the driver.
fuel string "Benzin" DK · NL Fuel in the language of the source.
fuel_code string "petrol" DK · NL Fuel as a code. Hybrids are told apart from plug-in hybrids.
power_kw number 110 DK · NL Engine power in kW. Multiply by 1.36 for metric horsepower.
engine_volume_cc integer 1498 DK · NL Engine capacity in cm³.
cylinders integer 4 DK · NL Number of cylinders.
kerb_weight_kg integer 1310 DK · NL Kerb weight in kg. Rarely filled in for Danish cars.
total_weight_kg integer 1830 DK · NL Permitted total weight in kg.
towbar boolean true DK Whether the vehicle is registered with a towbar.
max_trailer_weight_kg integer 1500 DK · NL Maximum braked trailer weight in kg.
max_trailer_weight_unbraked_kg integer 670 DK · NL Maximum unbraked trailer weight in kg.
status string "Registreret" DK Registration status.
usage string "Privat personkørsel" DK Usage.
first_registration date "2019-04-25" DK · NL First registration.
model_year integer 2019 DK Model year.
vin string "WVWZZZAUZKP000000" DK Vehicle identification number (VIN).
euro_norm string "Euro VI" DK · NL Euro emission standard.
co2_g_km number 116 DK · NL CO₂ emissions in g/km.
last_inspection date "2025-04-01" DK Date of the latest inspection.
next_inspection date "2027-04-25" NL When the APK (MOT) expires. Netherlands only.
odometer_km integer 77000 DK Odometer reading at the latest inspection.
odometer_date date "2025-04-01" DK Date of the odometer reading.
source string "dmr" DK · NL dmr (Danish Motor Register) or rdw (RDW).
data_date date "2026-11-01" DK · NL The date of the data the response is based on.

Example response

{
  "country": "DK",
  "plate": "AB12345",
  "make": "Volkswagen",
  "model": "Golf",
  "variant": "1.5 TSI EVO 150 DSG7",
  "make_slug": "volkswagen",
  "model_slug": "golf",
  "catalog_make_slug": "volkswagen",
  "catalog_model_slug": "golf",
  "vehicle_type": "Personbil",
  "vehicle_type_code": "car",
  "body_type": "Stationcar",
  "colour": "Rød",
  "colour_code": "red",
  "doors": 5,
  "seats": 5,
  "fuel": "Benzin",
  "fuel_code": "petrol",
  "power_kw": 110,
  "engine_volume_cc": 1498,
  "cylinders": 4,
  "kerb_weight_kg": null,
  "total_weight_kg": 1830,
  "towbar": true,
  "max_trailer_weight_kg": 1500,
  "max_trailer_weight_unbraked_kg": 670,
  "status": "Registreret",
  "usage": "Privat personkørsel",
  "first_registration": "2019-04-25",
  "model_year": 2019,
  "vin": "WVWZZZAUZKP000000",
  "euro_norm": "Euro VI",
  "co2_g_km": 116,
  "last_inspection": "2025-04-01",
  "next_inspection": null,
  "odometer_km": 77000,
  "odometer_date": "2025-04-01",
  "source": "dmr",
  "data_date": "2026-11-01"
}

Codes

The code fields always have one of these values, so you can sort without translating. If we do not know the value, the code is other.

vehicle_type_codecar, van, truck, bus, motorcycle, moped, trailer, caravan, tractor, other
fuel_codepetrol, diesel, electric, hybrid_petrol, hybrid_diesel, plugin_hybrid, lpg, cng, hydrogen, other
colour_codeblack, white, grey, silver, blue, red, green, yellow, orange, brown, beige, purple, other

Error codes

On an error you get an HTTP status code and a JSON response with the field error. Errors do not count as lookups.

{ "error": "not_found" }
StatuserrorMeaning
400 unsupported_country The country is neither DK nor NL (in the catalogue: dk, nl, fi or all).
400 invalid_type A code in ?type= does not exist (catalogue only).
401 unauthorized The key is missing, wrong or disabled.
403 key_paused The key is paused because of unusual usage. The response has a message. Write to kontakt@platerunner.dk.
404 not_found The number plate is not in the register.
429 rate_limited More than 20 calls per second. Wait the number of seconds in Retry-After.
429 monthly_limit_reached This month’s lookups are used. Buy an extra package or a bigger plan.
502 upstream_unavailable RDW is not responding right now (Netherlands only). Try again shortly.
503 catalog_unavailable The catalogue is temporarily unavailable. Try again shortly.
503 dk_data_unavailable The Danish data is temporarily unavailable. Try again shortly.

Limits

Every response from /v1/plates and /v1/catalog with a valid key, errors included, has three headers with this month's usage:

HeaderExampleMeaning
X-Lookups-Used 1234 Lookups used this month, this call included.
X-Lookups-Limit 15000 The month’s limit including extra packages. unlimited on Unlimited.
X-Lookups-Reset 2026-12-01 The first day of next month (UTC), when the lookups start over.

See pricing

Examples

The examples read the key from the environment variable PLATERUNNER_KEY.

curl

curl https://api.platerunner.dk/v1/plates/DK/AB12345 \
  -H "Authorization: Bearer YOUR_KEY"

JavaScript

const response = await fetch('https://api.platerunner.dk/v1/plates/DK/AB12345', {
  headers: { Authorization: `Bearer ${process.env.PLATERUNNER_KEY}` },
});
if (response.status === 404) {
  // The plate is not in the register
} else if (!response.ok) {
  const { error } = await response.json();
  throw new Error(error);
}
const vehicle = await response.json();
console.log(vehicle.make, vehicle.model, vehicle.power_kw);

PHP

<?php
$ch = curl_init('https://api.platerunner.dk/v1/plates/DK/AB12345');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('PLATERUNNER_KEY')],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$vehicle = json_decode($body, true);
if ($status === 200) {
    echo $vehicle['make'] . ' ' . $vehicle['model'];
} else {
    echo 'Error: ' . $vehicle['error'];
}

Python

import os
import requests

response = requests.get(
    "https://api.platerunner.dk/v1/plates/DK/AB12345",
    headers={"Authorization": f"Bearer {os.environ['PLATERUNNER_KEY']}"},
    timeout=10,
)
if response.status_code == 200:
    vehicle = response.json()
    print(vehicle["make"], vehicle["model"], vehicle["power_kw"])
else:
    print("Error:", response.json()["error"])