Vehicles API Reference
Search anonymised MOT results, compare pass rates, and find common failure reasons.
Base URL: https://api.govdata.dev/v1
Search MOT tests
GET /v1/vehicles/mot-tests returns index-backed, paginated individual test results. Use it for statistical exploration, not vehicle-history checks.
/v1/vehicles/mot-tests
Waiting for request...
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
make |
string | No | — | Case-insensitive make prefix. |
model |
string | No | — | Case-insensitive model prefix. |
test_year |
integer | No | — | Year of test; this slice contains 2025. |
fuel_type |
string | No | — | Enum label such as petrol, diesel, electric, or unknown. |
result |
string | No | — | Enum label such as passed, failed, or pass_with_rectification. |
postcode_area |
string | No | — | High-level station postcode area. |
first_use_year_from |
integer | No | — | Inclusive first-use year lower bound. |
first_use_year_to |
integer | No | — | Inclusive first-use year upper bound. |
page |
integer | No | 1 | One-based page. |
per_page |
integer | No | 25 | Results per page, maximum 100. |
curl -H "Authorization: Bearer YOUR_API_KEY" "https://api.govdata.dev/v1/vehicles/mot-tests?make=LEXMOTO&test_year=2025"
uri = URI("https://api.govdata.dev/v1/vehicles/mot-tests?make=LEXMOTO&test_year=2025")\nres = Net::HTTP.get_response(uri, {"Authorization" => "Bearer YOUR_API_KEY"})
response = requests.get("https://api.govdata.dev/v1/vehicles/mot-tests", headers={"Authorization": "Bearer YOUR_API_KEY"}, params={"make": "LEXMOTO", "test_year": 2025})
const response = await fetch("https://api.govdata.dev/v1/vehicles/mot-tests?make=LEXMOTO&test_year=2025", { headers: { Authorization: "Bearer YOUR_API_KEY" } });
Response
{"data":[{"test_id":1326094865,"test_date":"2025-01-08","test_year":2025,"test_class":"1","test_type":"NT","result":"pass_with_rectification","odometer":{"reading":6,"unit":"mi"},"postcode_area":"BH","make":"LEXMOTO","model":"ADRENALINE 125 EFi","colour":"BLACK","fuel_type":"petrol","cylinder_capacity_cc":125,"first_use_date":"2017-09-05"}],"meta":{"api_version":"v1","licence":"Open Government Licence v3.0","source":"DVSA anonymised MOT test results","source_url":"https://open.data.dvsa.gov.uk/mot-anonymised/index.html","test_year":2025,"coverage":"results_only"},"pagination":{"total":1,"page":1,"per_page":25,"total_pages":1}}
Error response
{"error":{"code":"invalid_parameter","message":"fuel_type is not recognised.","documentation_url":"https://docs.govdata.dev/errors/invalid_parameter"}}
MOT pass rates
GET /v1/vehicles/mot-pass-rates reads the importer-built aggregate table, so requests never scan 42.7 million raw rows.
/v1/vehicles/mot-pass-rates
Waiting for request...
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
make |
string | No | — | Case-insensitive make prefix. |
model |
string | No | — | Case-insensitive model prefix. |
fuel_type |
string | No | — | Normalised fuel label. |
vehicle_age_band |
string | No | — | 0-3, 4-6, 7-9, 10-14, 15-19, or 20+. |
test_year |
integer | No | 2025 | Test year. |
page |
integer | No | 1 | One-based page. |
per_page |
integer | No | 25 | Results per page, maximum 100. |
curl -H "Authorization: Bearer YOUR_API_KEY" "https://api.govdata.dev/v1/vehicles/mot-pass-rates?make=LEXMOTO&fuel_type=petrol"
uri = URI("https://api.govdata.dev/v1/vehicles/mot-pass-rates?make=LEXMOTO&fuel_type=petrol")\nres = Net::HTTP.get_response(uri, {"Authorization" => "Bearer YOUR_API_KEY"})
response = requests.get("https://api.govdata.dev/v1/vehicles/mot-pass-rates", headers={"Authorization": "Bearer YOUR_API_KEY"}, params={"make": "LEXMOTO", "fuel_type": "petrol"})
const response = await fetch("https://api.govdata.dev/v1/vehicles/mot-pass-rates?make=LEXMOTO&fuel_type=petrol", { headers: { Authorization: "Bearer YOUR_API_KEY" } });
Response
{"data":[{"make":"LEXMOTO","model":"ADRENALINE 125 EFi","first_use_year_band":"2015-2019","vehicle_age_band":"7-9","fuel_type":"petrol","test_year":2025,"statistics":{"tests":2,"passes":2,"pass_rate":1.0}}],"meta":{"api_version":"v1","licence":"Open Government Licence v3.0","source":"DVSA anonymised MOT test results","source_url":"https://open.data.dvsa.gov.uk/mot-anonymised/index.html","test_year":2025,"coverage":"results_only","aggregation":"normal_initial_tests"},"pagination":{"total":1,"page":1,"per_page":25,"total_pages":1}}
Common MOT failure reasons
GET /v1/vehicles/mot-failures returns the most common DVSA reason-for-rejection categories for a make and model. It is designed for reliability comparisons and used-vehicle research; requests read only the importer-built aggregate and never scan the 92.5 million detail rows.
/v1/vehicles/mot-failures
Waiting for request...
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
make |
string | Yes | — | Case-insensitive make prefix. |
model |
string | Yes | — | Case-insensitive model prefix. |
rfr_type |
string | Yes | — | fail, prs, advisory, minor, or unknown. |
dangerous_only |
boolean | Yes | false | Only reasons in DVSA's Dangerous deficiency category. |
test_year |
integer | Yes | 2025 | Test year. |
page |
integer | Yes | 1 | One-based page. |
per_page |
integer | Yes | 25 | Results per page, maximum 100. |
curl -H "Authorization: Bearer YOUR_API_KEY" "https://api.govdata.dev/v1/vehicles/mot-failures?make=LEXMOTO&model=MICHIGAN&rfr_type=fail"
uri = URI("https://api.govdata.dev/v1/vehicles/mot-failures?make=LEXMOTO&model=MICHIGAN&rfr_type=fail")\nres = Net::HTTP.get_response(uri, {"Authorization" => "Bearer YOUR_API_KEY"})
response = requests.get("https://api.govdata.dev/v1/vehicles/mot-failures", headers={"Authorization": "Bearer YOUR_API_KEY"}, params={"make": "LEXMOTO", "model": "MICHIGAN", "rfr_type": "fail"})
const response = await fetch("https://api.govdata.dev/v1/vehicles/mot-failures?make=LEXMOTO&model=MICHIGAN&rfr_type=fail", { headers: { Authorization: "Bearer YOUR_API_KEY" } });
Response
{"data":[{"make":"LEXMOTO","model":"MICHIGAN 125","test_year":2025,"rfr_type":"fail","defect_category":"Major","defect_description":"pin or bush excessively worn","dangerous":false,"statistics":{"failures":1,"affected_tests":1}}],"meta":{"api_version":"v1","licence":"Open Government Licence v3.0","source":"DVSA anonymised MOT failure items","source_url":"https://open.data.dvsa.gov.uk/mot-anonymised/index.html","test_year":2025,"coverage":"failure_items","aggregation":"make_model_reason"},"pagination":{"total":1,"page":1,"per_page":25,"total_pages":1}}
failures counts item rows; affected_tests counts distinct anonymised tests. Repeated defects can therefore make the first value larger.
Errors
{"error":{"code":"invalid_parameter","message":"rfr_type is not recognised.","documentation_url":"https://docs.govdata.dev/errors/invalid_parameter"}}
Invalid filters return 400. This collection has no addressable resource, so 404 is not applicable; no request body is validated, so 422 is not applicable.
Data notes
Coverage: result and failure/RfR coverage for the 2025 test year. Failure aggregates become complete after the initial production failure-item import finishes.
Method: pass rates use normal initial tests (NT) with pass, fail, or pass-with-rectification outcomes. A PRS outcome counts as a final pass.
Source and cadence: DVSA anonymised MOT test results, refreshed annually after publication, reused under the Open Government Licence v3.0 with Crown copyright attribution.
Failure detail: coded reasons, deficiency categories, and locations are decoded with DVSA's published lookup tables. The dangerous flag is derived from the post-May 2018 Dangerous deficiency category; the legacy D-mark is not used. Unknown codes remain explicitly unknown. Raw per-test failure detail is not exposed: anonymised test IDs are not useful vehicle identifiers, while the consumer use case is served more safely and efficiently by the indexed aggregate.
This is an anonymised statistical dataset. It contains no registration or VIN and is not an official DVSA vehicle-history service. Make/model, fuel, mileage, and first-use values can be incomplete or entered incorrectly; small groups are not predictions of an individual vehicle's reliability.