A trim row or a VIN lookup gives you a vehicle_id. Recalls are the safety notices for that id: the component, what can happen, and the remedy. You do not send a VIN, a mileage, or a ZIP code to this call. The id is enough.
The example id 358404 is in the same 2011 pickup family as the trim ids around 358402. Use the id you actually stored.
👉 To access this endpoint, you must obtain an API key: https://steadyapi.com/register
Authentication
Every call uses a Bearer token from your SteadyAPI dashboard.
Documentation:
https://docs.steadyapi.com/#authenticating-requests
headers = {
'Authorization': 'Bearer YOUR_API_KEY'
}
Where this fits
GET /v1/vehicles/make, then GET /v1/vehicles/model, then GET /v1/vehicles/trims produces vehicle_id. GET /v1/vehicles/vin can produce one without the trim list. Price is GET /v1/vehicles/car-value, which also wants mileage. This recalls call wants only vehicleId. A make id or a model id is the wrong number.
Recalls for one vehicle
Endpoint: GET /v1/vehicles/recalls
Documentation:
https://docs.steadyapi.com/#autohub-api-GETapi-v1-vehicles-recalls
Parameters
vehicleId— required vehicle id, such as358404
There is no date filter and no page parameter. You get the notices on file for that id. meta.total_recalls is the count. An id with no notices comes back as an empty recalls list and a total of 0.
Python
import requests
url = "https://api.steadyapi.com/v1/vehicles/recalls"
headers = {"Authorization": "Bearer YOUR_API_KEY"}
response = requests.get(url, headers=headers, params={"vehicleId": trim["vehicle_id"]})
response.raise_for_status()
payload = response.json()
print(payload.get("meta", {}).get("total_recalls"))
for recall in payload.get("body", {}).get("recalls", [])[:8]:
print(recall.get("report_date"), recall.get("component"), recall.get("nhtsa_campaign_id"))
Annotated sample
{
"type": "Recall",
"component": "Suspension:rear:axle:spindle",
"summary": "GENERAL MOTORS IS RECALLING CERTAIN MODEL YEAR 2011 CADILLAC ESCALADE EXT, CHEVROLET AVALANCHE",
"consequence": "THE DRIVER MAY HEAR A BANGING NOISE COMING FROM THE AXLE.",
"remedy": "DEALERS WILL INSTALL A NEW REAR AXLE CROSS PIN FREE OF CHARGE.",
"report_date": "",
"nhtsa_campaign_id": "",
"manufacturer_recall_no": ""
}
Store component, summary, consequence, and remedy. type is the notice type, often Recall. report_date, nhtsa_campaign_id, manufacturer_recall_no, potential_affected_units, and manufacture_dates are on every row, and they are often empty strings. Do not drop a notice because the campaign id is blank. The summary text is the record. For vehicle 358404, meta.total_recalls is 7. The component above is one of those notices.
Practical use
Empty strings are normal on the id fields. Check summary and component before you decide a row is useless. meta.total_recalls of 0 with an empty list means no notices came back for that id.
Neighboring trim ids are different vehicles. 358402 and 358404 are not the same pickup. Price and recalls for one trim do not apply to the next row in the trim list.
This route does not accept mileage or priceType. Those belong on car value. Sending only vehicleId is the full request.
👉 Get your API key and check recalls: https://steadyapi.com/register