Waiting for review
Reported entries
Recently decided
Your admin API key
For your own apps, scripts and plate readers. It isn’t counted and has no allowance (up to 1,200 requests a minute). Send it in the X-API-Key header. While you’re signed in, the API page’s Try it box uses it automatically.
Paid API subscribers
Keys for outside services
Saved to the server’s .env file (the previous copy is kept as .env.bak). Secret keys are never shown again, only their last 4 characters. To change one, type the new value; leave a box empty to keep what’s there. Saving asks for your password.
API requests per hour
Last 24 hours, your local time. Calls from apps, scripts and plate readers, not the website itself.
Most looked-up plates today
Opened on the site or checked through the API. Repeats by the same visitor within a minute aren’t counted.
Most viewed, all time
Last 24 hours
The register
“Live now” counts people (by connection and browser) seen in the last 5 minutes. “Last 60 minutes” resets if the server restarts; 24-hour and all-time figures are saved.
Create a free account
- Add police vehicles to the register
- A free API key with 5 plate lookups a day
- Your name on Top contributors
Shown publicly on vehicles you add. A nickname is fine.
At least 10 characters.
By creating an account you agree to the terms and privacy notice.
Your API key
Use it in plate readers, apps and scripts. Send it in the X-API-Key header. See the API guide.
Keep it private. Don’t put it in public web pages.
Plan and usage
Messages
Settings
Changing it signs you out on your other devices.
Your paid key replaces the free one.
Removes your account and API key. Vehicles you added stay in the register without your name.
Top contributors
Ranked by vehicles added and approved, then photos. Want to be on here? Create a free account and add a vehicle.
Contact us
Questions, corrections, removal requests or help with the API. We reply by email, usually within two working days.
We only use your email to reply to you. See the privacy notice.
Thanks, your message has been sent.
We’ll reply to . Check your spam folder if you don’t hear back in a couple of days.
Privacy notice
Last updated: 20 October 2026
Who we are
BlueLight DB is a community-run register of police vehicles, operated by [your name or organisation], who is the data controller. Contact us any time through the contact form.
What we collect and why
- Vehicle submissions: the plate, vehicle details and where you saw it or found it (including any link you add). Used to check and publish entries, and linked to your account.
- Your account: your email address, display name and password (stored only as a one-way hash we can’t read). Your display name is shown publicly on the vehicles you add and on Top contributors, so a nickname is fine. Your email is used to sign you in, for password resets and for messages about your API plan; we don’t show it to anyone. Your API key is stored encrypted so you can view it on your account page. You can delete your account at any time from that page; vehicles you added stay in the register without your name.
- View and lookup counts: we count how often each listed vehicle is opened or looked up. To avoid counting the same person twice we briefly remember your IP address in memory (for a minute or two); it isn’t saved with the counts.
- Reports: what’s wrong with an entry, plus an email address if you choose to give one, so we can follow up.
- Contact messages: your name, email and message, so we can reply.
- API customers: your email, plan and usage. Payments are handled by Stripe; we never see or store your card details.
- Technical data: IP addresses, used to apply rate limits and to protect the site from abuse, and anonymised visitor counts. We don’t use advertising or tracking cookies.
Cookies and storage
We set one cookie, and only for admins who sign in. Your browser also remembers your light or dark theme and, if you enter one, your API key for the current session. Nothing is used to track you across other sites.
Legal basis
We rely on our legitimate interests in running an accurate public register and keeping it secure, and on contract for paid API plans.
Who we share it with
Stripe (payments) and our email provider (to send replies). We don’t sell personal data.
How long we keep it
Contact messages and reports: up to 12 months after they’re resolved. API account records: as long as you’re a customer, plus any period the law requires for financial records. Backups are kept for 14 days.
Number plates
The register lists vehicles operated by police forces. A vehicle that has been sold may now belong to a private owner; if that’s you, ask us to remove it on the removal requests page.
Your rights
You can ask to see, correct or delete your personal data, or object to how we use it, through the contact form. If you’re unhappy with our answer you can complain to the Information Commissioner’s Office at ico.org.uk.
Terms of use
Last updated: 20 October 2026
About the register
BlueLightDB is run by volunteers from information the public sends in. We check entries before publishing them, but we can’t guarantee every detail is correct or up to date. We are not affiliated with any police force, the Home Office or the DVLA.
Using the site and API
- Only submit vehicles seen in public or listed in a public source, and don’t include people’s faces, names or personal details.
- Don’t use the register to obstruct the police, to harass anyone, or for anything unlawful.
- Don’t try to get around rate limits, scrape the site in bulk, or resell the data without our permission.
- If you republish data, credit “BlueLightDB community register”.
Paid API plans
Plans renew monthly and are billed by Stripe. Prices are shown before VAT, which is added at checkout where it applies. You can switch or cancel any time from your account; a cancellation takes effect at the end of the period you’ve paid for. Each plan includes a monthly number of requests; we may pause keys that are abused or linked to payment disputes. Your legal rights as a consumer are not affected.
Our liability
The service is provided “as is”. We aren’t liable for decisions made using the data, or for losses caused by it being wrong or unavailable, except where the law doesn’t allow us to limit liability.
Changes and law
We may update these terms and will change the date above when we do. These terms are governed by the law of England and Wales.
Removal requests
We want the register to be accurate and fair. You can ask us to correct or remove an entry, and we’ll look at every request.
Who can ask
- Police forces and other emergency services, for example for an operational or security reason.
- The current owner of a vehicle that is no longer a police vehicle.
- Anyone with a privacy or safety concern about an entry.
How to ask
The quickest way is the Report button on the vehicle. For anything that needs a reply, use the contact form and choose “Removal or takedown request”. Include the plate and why it should be removed. Please don’t send personal documents.
What happens next
We aim to respond within two working days. While we look into a request we may hide the entry. If we decide to keep it, we’ll tell you why.
Public API
Everything in the Fleet Explorer is available as JSON, for your own apps, maps, bots, plate readers or spreadsheets. Only approved entries are returned.
Base URL:
- Plate lookups need an API key. Create a free account and you get one straight away, with 5 lookups a day. Paid plans give a monthly allowance.
- The search and listing endpoints (
/api/vehicles,/api/filters) work without a key, up to 600 requests per 15 minutes per IP address (IPv6: per /64 block). - All responses are JSON. Errors look like
{"error":"…","field":"vrm"}with a 4xx or 5xx status. - Reading endpoints work from any website (CORS is open), from a server, or from the command line. Over a limit you get
429. Cache results where you can. - Please credit “BlueLight DB community register” and link back if you republish the data.
Plans
Every account starts on Free. Upgrade for a bigger allowance; your key stays the same. Switch or cancel any time. No setup fee.
Paid allowances reset on the 1st of each month, Free on midnight each day (UTC). A batch lookup counts one per plate. Payments are handled securely by Stripe. Your key, usage and billing are on your account page.
Using your API key
Send it in the X-API-Key header (or Authorization: Bearer …) on any GET endpoint. Keep it on your server or device. Don’t put it in public web pages.
curl -H "X-API-Key: frk_your_key_here" "/api/lookup/AB21XYZ"
| Response header | Meaning |
|---|---|
X-Quota-Limit | Requests included in your plan each month (Free: lookups each day). |
X-Quota-Remaining | Requests left this month (Free: today). |
X-Quota-Reset | When the count resets (UTC). |
| Status | Meaning |
|---|---|
401 | No key sent (plate lookups need one), or the key is wrong or has been replaced. |
402 | The key is suspended or the subscription isn’t active. Check your account page. |
429 | Daily (Free) or monthly allowance, or the per-minute burst limit, reached. Check Retry-After. |
Plate lookup (for plate readers / ANPR)
Give it a plate, get a straight yes or no. This is the endpoint to use from a plate reader, dashcam or app.
/api/lookup/:plateExact match only. Spaces and case don’t matter, so AB21XYZ, ab21 xyz and AB21 XYZ are the same.
curl -H "X-API-Key: frk_your_key_here" "/api/lookup/AB21XYZ"
{
"vrm": "AB21 XYZ",
"found": true,
"police": true,
"vehicle": {
"id": 42, "vrm": "AB21 XYZ", "force": "Kent", "make": "BMW",
"model": "530d Touring", "type": "Roads policing",
"fuel": "Diesel", "year": 2021, "fleetStatus": "In service",
"added": "2026-06-14 09:12:33"
}
}
Not in the register:
{ "vrm": "CD22 ABC", "found": false, "police": false, "vehicle": null }
| Field | Meaning |
|---|---|
police | Use this one. true if the plate is listed and the vehicle is still with the police (In service or Out of service). |
found | true if the plate is in the register at all. A vehicle that has been sold or decommissioned is found: true but police: false, because it may now be in private hands. |
vehicle | The full entry, or null if not found. |
A plate that isn’t 2–8 letters and numbers gives 400. The response can be cached for 60 seconds.
Several plates at once
/api/lookup?plates=AB21XYZ,CD22ABCUp to 50 plates, comma-separated. Returns {"results":[…]} in the same order, one entry per plate in the format above. Invalid plates come back with "error":"Invalid plate." instead of failing the whole request. Counts as one request.
Good to know
- This is a community register.
police: falsemeans “not listed”, not “definitely not a police vehicle”. Unmarked cars especially may be missing. - Only approved entries are checked. Plates waiting for review aren’t returned.
- Plate readers misread characters (
0/O,1/I,8/B). If you need to check likely misreads, send them together in one batch request.
// Example: call this when your reader sees a plate
async function isPolice(plate) {
const res = await fetch(`/api/lookup/${encodeURIComponent(plate)}`,
{ headers: { "X-API-Key": process.env.FLEET_API_KEY } });
if (!res.ok) return false; // invalid plate, bad key or limit reached
const data = await res.json();
return data.police; // true / false
}
# Python
import os, requests
def is_police(plate):
r = requests.get(f"/api/lookup/{plate}", timeout=3,
headers={"X-API-Key": os.environ["FLEET_API_KEY"]})
return r.ok and r.json()["police"]
/api/vehiclesSearch and list vehicles, a page at a time.
| Parameter | Description |
|---|---|
q | Free-text search. Matches the plate (spaces ignored, so AB21XYZ = AB21 XYZ), make and model. |
force | Exact police force name, e.g. Thames Valley. |
make | Vehicle make, not case-sensitive, e.g. bmw. |
type | Exact vehicle type, e.g. Roads policing. |
sort | added (newest first, default), viewed (most viewed on the site first), vrm (plate A–Z) or force. |
page | Page number, starting at 1. |
pageSize | Results per page, 1–50. Default 8. |
Example
curl "/api/vehicles?force=Kent&type=Roads%20policing&pageSize=2"
{
"total": 14,
"page": 1,
"pageSize": 2,
"pages": 7,
"items": [
{
"id": 42,
"vrm": "AB21 XYZ",
"force": "Kent",
"make": "BMW",
"model": "530d Touring",
"type": "Roads policing",
"fuel": "Diesel",
"year": 2021,
"fleetStatus": "In service",
"added": "2026-06-14 09:12:33"
},
…
]
}
Vehicle fields
| Field | Description |
|---|---|
id | Number. Stable ID for this entry. |
vrm | Number plate, formatted with a space for current-style plates. |
force, make, model, type | Text. |
fuel | One of the fuel types below, or an empty string if not known. |
year | Number, or null if not known. |
engineCc, engine | Engine size in cc (e.g. 2494) and as shown on the site ("2.5L"). Both null if not known or electric. |
fleetStatus | One of the statuses below. |
added | When it was submitted, UTC, YYYY-MM-DD HH:MM:SS. |
/api/vehicles/:idOne vehicle by its id, in the same format as the items above. Unknown or unapproved IDs give 404.
curl "/api/vehicles/42"
/api/filtersThe values in use, for building your own dropdowns. forces, makes and types only list values that have at least one vehicle. allForces, allTypes, allFuels and allStatuses list every accepted value.
curl "/api/filters"
Fuel types:
Statuses:
Vehicle types:
Police forces:
/api/submissionsSubmit a vehicle for review. It won’t appear until an admin approves it. Limit: 8 per hour per IP. Send the header X-Requested-With: fetch on every POST.
| Field | Description |
|---|---|
vrm* | Number plate, 2–8 letters and numbers. |
force*, type* | Must match the lists above exactly. |
make*, model* | Text. |
source* | How you know about it, 3–300 characters, e.g. Spotted in public: M20 J9, May 2026. |
fuel, year, fleetStatus, sourceUrl, notes | Optional. fleetStatus defaults to In service. |
curl -X POST "/api/submissions" \
-H "Content-Type: application/json" \
-H "X-Requested-With: fetch" \
-d '{"vrm":"AB21 XYZ","force":"Kent","make":"BMW","model":"530d Touring",
"type":"Roads policing","fuel":"Diesel","year":2021,
"source":"Spotted in public: M20 J9, May 2026"}'
Returns 201 with {"ok":true,"id":43}. A plate that is already listed or waiting gives 409.
/api/vehicles/:id/reportFlag an entry as wrong or a privacy concern. Body: {"reason":"…","contact":"optional email"}. The reason must be at least 5 characters. Limit: 10 per hour.
Using it from JavaScript
// Fetch every Volvo, 50 at a time
const base = "/api/vehicles";
let page = 1, all = [], pages = 1;
do {
const res = await fetch(`${base}?make=Volvo&pageSize=50&page=${page}`);
if (!res.ok) throw new Error((await res.json()).error);
const data = await res.json();
all.push(...data.items);
pages = data.pages;
} while (page++ < pages);
console.log(all.length, "vehicles");
Python
import requests
r = requests.get("/api/vehicles", params={"q": "AB21XYZ"})
r.raise_for_status()
for v in r.json()["items"]:
print(v["vrm"], v["force"], v["make"], v["model"], v["fleetStatus"])
Try it
Run any GET request against the live API and see the response. No account? You get one free plate lookup a day here to see what you’d get. When you’re signed in, lookups here use your own key (and count towards its allowance).
Response will appear here.