How to Query UK Vehicle MOT History & DVSA Specs in Python
If you are a developer, software team, or PropTech/AutoTech founder building automated data pipelines, you need reliable, structured access to real-time data.
Traditional web scraping approaches quickly break down due to rate limits, anti-bot defenses, and fragile layout selectors.
The Pain with Traditional Data Extraction
When building custom scrapers, engineering teams inevitably face:
- DVSA: DVSA gateway rate-limiting and complex corporate registration barriers.
- Legacy: Legacy XML/SOAP data schemas requiring custom parsing middleware.
- Fragile: Fragile HTML web scrapers failing whenever the gov.uk layout changes.
Many developers attempt to patch this by purchasing unmaintained scripts from generic marketplaces, only to find them crashing whenever target portals deploy updates.
The Modern Solution: PlotAPI
Instead of managing rotating residential proxy pools, solving CAPTCHAs, and maintaining fragile DOM parsers, modern data teams use PlotAPI.
PlotAPI exposes normalized UK vehicle registrations (VRMs) directly mapped to complete DVSA MOT test records, failure advisories, and vehicle specs with sub-300ms latency.
Complete Integration Example
Here is a production-ready example demonstrating how to extract this data with zero scraping overhead:
import requests
PLOTAPI_KEY = "your_api_key_here"
BASE_URL = "https://api.plotapi.co/v1/uk/vehicle"
def get_mot_history(vrm: str):
headers = {"Authorization": f"Bearer {PLOTAPI_KEY}"}
params = {"vrm": vrm, "include_mot_history": "true"}
response = requests.get(BASE_URL, headers=headers, params=params)
if response.status_code == 200:
data = response.json()
print(f"Vehicle: {data['make']} {data['model']} ({data['year_of_manufacture']})")
print(f"MOT Status: {data['mot_status']} | Expiry: {data['mot_expiry_date']}")
for test in data.get('mot_tests', [])[:3]:
print(f" - {test['completed_date']}: {test['test_result']} ({test['odometer_value']} {test['odometer_unit']})")
for rfr in test.get('rfr_and_comments', []):
print(f" * [{rfr['type']}] {rfr['text']}")
else:
print(f"Error: {response.status_code} - {response.text}")
if __name__ == "__main__":
get_mot_history("AB12CDE")
Key Architecture Benefits
- Predictable Latency: Sub-300ms global response times across all endpoints.
- Strictly Typed JSON: Guaranteed schemas with no raw HTML tags or missing fields.
- Enterprise Uptime: 99.9% availability backed by automated schema drift detection.
- AI & MCP Ready: Direct support for Cursor, Claude Desktop, and LangChain agents.
Start Building for Free
Stop fighting web scrapers and enterprise sales gating. Create your free PlotAPI Sandbox account and receive 50 complimentary requests every single month.