A while ago I wrote a list of free APIs for side projects, and it became my most-read post on DEV. This is the grown-up version: free government APIs I've actually used in production.
I'm co-founder of TrustCheck, a platform that helps people in Ghana check a business, a price or a car before they pay. Our free used-car checker runs almost entirely on the APIs below. None of them need an API key, a sign-up or a credit card.
Every example here is a real request I ran while writing this post. Copy it into your terminal and it works.
1. NHTSA vPIC: decode any VIN
What it gives you: make, model, year, engine size, fuel type, where the car was built, and more, from a 17-character VIN.
curl "https://vpic.nhtsa.dot.gov/api/vehicles/DecodeVinValues/1HGCM82633A004352?format=json"
{
"Make": "HONDA",
"Model": "Accord",
"ModelYear": "2003",
"DisplacementL": "2.998832712",
"FuelTypePrimary": "Gasoline",
"PlantCountry": "UNITED STATES (USA)",
"ErrorCode": "0"
}
Build idea: "Does the ad match the car?" A seller says 2015. The VIN says 2009. In Ghana that matters even more now, because used cars 15 years and older can no longer be imported.
Gotcha: check ErrorCode. "0" is a clean decode. Cars built for other markets (Japan, the Gulf, Europe) often decode only partly, so show what you got and say what's missing.
2. NHTSA Recalls: every open safety recall
What it gives you: recalls for a make, model and year: the component, what goes wrong, and the fix.
curl "https://api.nhtsa.gov/recalls/recallsByVehicle?make=honda&model=accord&modelYear=2003"
The 2003 Accord has 24 recalls. Each result includes Component, Summary, Consequence, Remedy, and flags like parkIt (don't drive it) and overTheAirUpdate.
Gotcha: model names must be spelled the way NHTSA spells them. I once showed "0 recalls" for a GMC Sierra that has 6, because recalls are filed under "SIERRA 1500", not "Sierra". API #5 is the fix.
3. NHTSA Complaints: what real owners reported
What it gives you: complaints filed by owners, with crash, fire, injury and death counts, the components involved, and the owner's own description.
curl "https://api.nhtsa.gov/complaints/complaintsByVehicle?make=honda&model=accord&modelYear=2003"
That returns 2,013 complaints. Each has crash, fire, numberOfInjuries, components and a summary in the owner's words.
Build idea: count complaints by component and show "the top 3 things that break on this car". It's more useful to a buyer than any spec sheet.
Gotcha: this endpoint can take several seconds on popular models. Call it in parallel with the others, and cache the result. Complaint data doesn't change hourly.
4. NHTSA 5-Star Safety Ratings, with crash test photos
What it gives you: official crash test ratings, plus links to crash test photos (US government work, public domain).
It's two steps. First find the vehicle ID:
curl "https://api.nhtsa.gov/SafetyRatings/modelyear/2017/make/toyota/model/corolla"
# → { "VehicleDescription": "2017 Toyota Corolla 4 DR FWD", "VehicleId": 11142 }
Then get the ratings:
curl "https://api.nhtsa.gov/SafetyRatings/VehicleId/11142"
{
"OverallRating": "5",
"OverallFrontCrashRating": "4",
"RolloverRating": "4",
"FrontCrashPicture": "https://static.nhtsa.gov/crashTest/images/2017/v09984P085.JPG"
}
Build idea: put the crash test photo next to the stars. People understand a crumpled car faster than a number.
5. NHTSA Products: the model-name fixer
What it gives you: NHTSA's own list of model names for a make and year. It isn't exciting on its own, but it's what makes APIs 2 and 3 reliable.
curl "https://api.nhtsa.gov/products/vehicle/models?modelYear=2017&make=gmc&issueType=r"
# → "SAVANA PASSENGER 2500", "CANYON", "ACADIA LIMITED", ...
Users type "RX 350"; NHTSA says "RX350". Users type "Sierra"; recalls are under "SIERRA 1500". I download this list once (it's cached for 30 days), strip spaces and punctuation from both sides, and match. When the name a user typed finds nothing, I retry with NHTSA's spelling.
Lesson: when one provider has several APIs, don't assume they share identifiers.
6. US EPA fueleconomy.gov: real fuel consumption
What it gives you: official city, highway and combined fuel economy for almost every car sold in the US since 1984.
It works like a menu: model list → engine options → vehicle.
curl -H "Accept: application/json" \
"https://www.fueleconomy.gov/ws/rest/vehicle/menu/options?year=2017&make=Toyota&model=Corolla"
# → [{ "text": "Auto (AV-S7), 4 cyl, 1.8 L", "value": "38154" }, ...]
curl -H "Accept: application/json" "https://www.fueleconomy.gov/ws/rest/vehicle/38154"
# → { "city08": "28", "highway08": "35", "comb08": "31", "fuelType": "Regular", "displ": "1.8" }
Gotcha: without the Accept: application/json header you get XML.
Build idea: convert to litres per 100 km (235.215 / mpg) and multiply by your local fuel price. We show "about GH₵ X a month in fuel" using the town figure and Ghana's current official fuel price. Nobody buys a car per mile-per-gallon; they buy it per month.
7. Bank of Ghana: official exchange rates and Treasury bill rates
What it gives you: the central bank's daily interbank exchange rates and weekly Treasury bill rates.
I'll be honest: this one isn't a documented API. The Bank of Ghana publishes these as public tables on bog.gov.gh, and the page loads them as structured data. We read them once a day, cache them, and only ever request those fixed pages.
Build idea: a "dollar to cedi today" tool that shows the official rate, so people can tell how far a street or shop rate is from it. Or a Treasury bill calculator that tells someone what GH₵1,000 earns in 91 days at this week's rate.
Gotcha: if a government only publishes HTML tables, be a good citizen. Identify your bot in the User-Agent, fetch rarely, cache aggressively, and never hammer the site.
How I use them without getting blocked or slow
-
Run independent calls in parallel. Recalls, ratings and fuel economy don't depend on each other. In Laravel I use
Http::pool(). - Cache by how often the data changes. Model lists: 30 days. Recalls and complaints: 7 days. Exchange rates: a day.
- Cache partial failures briefly. If one API was down, cache that answer for 15 minutes, not a week.
- Warm popular pages at night. We preload common model-years in small batches between 1 and 5:30 am.
- Say where the data comes from. "Source: NHTSA" on the page builds more trust than any design.
Over to you
The US government has the best-documented free vehicle data I've found anywhere. What free government APIs from your own country should more developers know about? I'd love to build a list in the comments, especially from African countries.
I'm Elliot, co-founder of TrustCheck, an enterprise technical writer and a researcher. I write about what I learn building software for the Ghanaian market. The car checker from this post is free at trustcheckapp.com/tools/car-check.
Top comments (3)
Memory safety and zero-cost abstractions only deliver their promise when you understand the underlying cache hierarchy and syscall overhead.
Rewriting services without profiling memory allocation patterns just trades one set of bottlenecks for another. Systems engineering always comes down to mechanical sympathy with the hardware.
Ha, fair point in general, but nothing here needs that much tuning. Most of these APIs are a single GET request. Have you built anything on public data where you live? Curious what's available outside
This is the kind of practical list I wish more people shared — not just the endpoints, but the gotchas that actually cost you time. The model-name mismatch is a great catch; I've seen the same kind of naming drift quietly break lookups in small-business tools, where a "no results" answer looks like a clean answer when it isn't. I also liked the caching rules, especially caching a partial failure for 15 minutes instead of a week. And putting "Source: NHTSA" right on the page is spot on — showing where the data came from builds more trust than any design polish.