Vehicle Report API

By Vehicle API
Vehicle Report API

You need a single Transportation-focused API call that turns a VIN into specs plus official U.S. safety data you can trust. By the end of this guide, you’ll be able to integrate the Vehicle Report endpoint to decode a VIN and fetch recalls, complaint counts, and NCAP crash ratings in one response, understand its response envelope and error handling, and ship production-grade caching and reliability.

What the Vehicle Report endpoint does (and doesn’t)

The Vehicle Report endpoint consolidates multiple authoritative data sources into one JSON response. It decodes the VIN for year, make, model, trim, engine, transmission, and assembly plant, then enriches it with U.S.-market safety data when available.

Illustration: Vehicle Report API
  • VIN decoding coverage: Global. Data richness is fullest for U.S.-market vehicles.
  • Safety data (U.S. only): Recall campaigns, owner complaint counts, and NCAP ratings are matched by year + make + model.
  • If the VIN is non-U.S.: You still receive a 200 response with specs only (no recalls/complaints/NCAP).
  • Not a vehicle history report: No title, accident, or ownership history.
  • Dutch plates: Available in the API (via RDW open data) but do not include a VIN. This article focuses on the VIN Vehicle Report.

Base URL: https://vehicles-api.com/api/v1

Authentication: Use the X-API-Key header. Authorization: Bearer also works if you prefer.

For documentation, pricing, and a 7-day free trial, visit vehicles-api.com and the links throughout this article.

Endpoint

POST https://vehicles-api.com/api/v1/vin/report

One VIN in, one structured report out. The response is always returned in a consistent envelope with status, source, and data (or an error object when not successful).

Official cURL example

Copy and run the following cURL command. Replace YOUR_API_KEY with your key.

curl -X POST "https://vehicles-api.com/api/v1/vin/report" -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" -d '{"vin":"1HGCM82633A004352"}'

Official JSON example

This is the documented example. In production, recall campaigns and counts can change as NHTSA publishes updates.

{
"status": "success",
"source": "nhtsa",
"data": {
"vin": "1HGCM82633A004352",
"valid": true,
"year": 2003,
"make": "HONDA",
"model": "Accord",
"trim": "EX-V6",
"body": "Coupe",
"doors": 2,
"vehicle_type": "PASSENGER CAR",
"engine": {
"cylinders": 6,
"displacement_l": 3,
"fuel": "Gasoline"
},
"fuel_type": "Gasoline",
"electrification_level": null,
"ev_drive_unit": null,
"battery_kwh": null,
"charger_level": null,
"charger_power_kw": null,
"plant": {
"country": "UNITED STATES (USA)",
"city": "MARYSVILLE",
"state": "OHIO"
},
"manufacturer": "AMERICAN HONDA MOTOR CO., INC.",
"coverage": "us",
"recalls_count": 24,
"recalls": [
{
"campaign": "19V182000",
"component": "AIR BAGS:FRONTAL:DRIVER SIDE:INFLATOR MODULE",
"received": "2019-03-06",
"summary": "Replacement driver air bag inflator may explode.",
"consequence": "Sharp metal fragments may strike occupants.",
"remedy": "Dealers will replace the inflator, free of charge."
}
],
"complaints_count": 2013,
"safety_ratings": {
"match": "partial",
"vehicle_description": "2003 Honda Accord 2-DR.",
"overall": null,
"front": {
"driver": 5,
"passenger": 5
},
"side": {
"driver": 5,
"passenger": 5
},
"rollover": 4
}
}
}

What you’ll actually use from the response

The envelope:

  • status: "success" or "error". Always check this first.
  • source: Upstream source indicator (e.g., "nhtsa"). Use for auditability.
  • data: Present when status is success. Contains all decoded and safety fields.

Key decoded spec fields (always attempt to read with null checks):

  • vin, valid: The VIN echoed back and a boolean validity result.
  • year, make, model, trim: Core identifiers for marketplaces, dealer tools, and quoting flows.
  • body, doors, vehicle_type: Useful for filtering search results and UI labels.
  • engine: cylinders, displacement_l, fuel. For parts fitment, emissions rules, or underwriting.
  • fuel_type: Duplicate of engine.fuel in this example; treat as the canonical fuel type in your UI.
  • electrification_level, ev_drive_unit, battery_kwh, charger_level, charger_power_kw: Present for electrified vehicles; null in non-EV/HEV cases. Always null-check.
  • plant: country, city, state: Assembly details for compliance labeling or logistics.
  • manufacturer: OEM entity name.
  • coverage: "us" when U.S. safety datasets were attempted for this VIN’s YMM match.

U.S. safety data (available when coverage includes the U.S. and a YMM match is found):

  • recalls_count: Integer count of recall campaigns matching year + make + model.
  • recalls: Array of structured recall items:
    • campaign: NHTSA campaign ID string.
    • component: Affected component.
    • received: Date the campaign was recorded by NHTSA (YYYY-MM-DD).
    • summary, consequence, remedy: Human-readable safety context for your UI.
  • complaints_count: Count of owner complaints from NHTSA for the YMM match.
  • safety_ratings: NCAP star ratings and match metadata:
    • match: e.g., "partial" indicates a partial attribute match to an NCAP configuration.
    • vehicle_description: The configuration label from NCAP.
    • overall, front.driver, front.passenger, side.driver, side.passenger, rollover: Star ratings or null if not available.

Null fields are expected for non-applicable technologies (e.g., EV data on gasoline vehicles) or when NHTSA/NCAP has incomplete coverage for the specific configuration. Do not assume presence; always handle nulls gracefully in production UIs and data pipelines.

JavaScript example (Node.js)

This example calls the same endpoint, checks the envelope, and reads commonly used fields. It demonstrates safe null handling for optional safety data.

import fetch from 'node-fetch';

const API_URL = 'https://vehicles-api.com/api/v1/vin/report';
const API_KEY = 'YOUR_API_KEY'; // Or use Authorization: Bearer

async function getVehicleReport(vin) {
const res = await fetch(API_URL, {
method: 'POST',
headers: {
'X-API-Key': API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({ vin })
});

// Handle HTTP-level errors early
if (!res.ok) {
// A 4xx/5xx will still typically include the envelope; try to parse it
const maybeJson = await res.text();
try {
const parsed = JSON.parse(maybeJson);
throw new Error(`HTTP ${res.status}: ${parsed?.error?.message || 'Request failed'}`);
} catch {
throw new Error(`HTTP ${res.status}: ${maybeJson}`);
}
}

const json = await res.json();
if (json.status !== 'success') {
const code = json?.error?.code || 'unknown_error';
const message = json?.error?.message || 'Vehicle API returned an error';
throw new Error(`${code}: ${message}`);
}

const d = json.data;

// Core specs
const specs = {
vin: d.vin,
valid: d.valid,
year: d.year,
make: d.make,
model: d.model,
trim: d.trim,
body: d.body,
doors: d.doors,
vehicleType: d.vehicle_type,
engine: {
cylinders: d.engine?.cylinders ?? null,
displacementL: d.engine?.displacement_l ?? null,
fuel: d.engine?.fuel ?? d.fuel_type ?? null
},
plant: {
country: d.plant?.country ?? null,
city: d.plant?.city ?? null,
state: d.plant?.state ?? null
},
manufacturer: d.manufacturer
};

// Safety data (US only, may be null or empty)
const safety = {
coverage: d.coverage || null,
recallsCount: d.recalls_count ?? 0,
recalls: Array.isArray(d.recalls) ? d.recalls : [],
complaintsCount: d.complaints_count ?? 0,
ncap: {
match: d.safety_ratings?.match ?? null,
vehicleDescription: d.safety_ratings?.vehicle_description ?? null,
overall: d.safety_ratings?.overall ?? null,
front: d.safety_ratings?.front ?? null,
side: d.safety_ratings?.side ?? null,
rollover: d.safety_ratings?.rollover ?? null
}
};

return { specs, safety, source: json.source };
}

// Example usage
getVehicleReport('1HGCM82633A004352')
.then(({ specs, safety, source }) => {
console.log('Source:', source);
console.log('Specs:', specs);
console.log('Safety:', safety);
})
.catch(err => {
console.error('Vehicle Report error:', err.message);
});

Response envelope and errors

All responses follow the same envelope:

  • On success: { "status": "success", "source": "...", "data": { ... } }
  • On error: { "status": "error", "error": { "code": "...", "message": "..." } }

Check HTTP status codes first; then check the JSON envelope’s status. Your application should not assume that a non-2xx response omits JSON—attempt to parse and surface error.code and error.message to logs for debugging. Do not rely on undocumented fields.

Rate limits, monthly quota, and retries

Plans include rate limits and monthly call quotas. If you hit a limit, the server may return an HTTP 429 along with the standard error envelope. Do not guess absolute numbers; consult the Documentation for plan-specific throughput and quotas.

  • Backoff: On 429 or transient 5xx, implement exponential backoff with jitter.
  • Idempotency: Decoding a VIN is read-only; safe to retry on network or 5xx errors.
  • Timeouts: Set sensible client timeouts and instrument latency metrics.

Starter is $19/month, and every plan includes a 7-day free trial. You can start testing in minutes via Register.

Caching strategies for production

VIN decoding results are stable for a given VIN. Safety data (recalls, complaints, NCAP) change over time as NHTSA updates datasets. This leads to a two-tier caching strategy:

  • Cache specs: year, make, model, trim, engine, plant—these are stable. You can cache long-lived entries keyed by VIN.
  • Refresh safety data: recalls_count, recalls[], complaints_count, safety_ratings can change. Consider a periodic refresh cadence appropriate for your use case (e.g., background jobs) rather than re-querying on every read.
  • Null safety fields: For non-U.S. VINs or configurations without NCAP coverage, fields may be null. Do not thrash the API attempting to populate irretrievable data; cache the null result with a reasonable TTL and re-check occasionally.

If you operate marketplaces or fleet dashboards, aggregate recall and complaint counts via lightweight scheduled tasks to avoid adding latency on user page loads.

Field-by-field implementation guidance

Core identification and UI labels

  • year, make, model, trim: Use to drive breadcrumb labels, search filters, and SEO-friendly slugs. Always uppercase-normalize make where needed.
  • body, doors, vehicle_type: Standardize strings for your filters; do not create mismatched categories.

Engine and fuel

  • engine.cylinders, engine.displacement_l: Numeric fitment and display fields. Unit is liters for displacement.
  • fuel_type and engine.fuel: When both appear, prefer fuel_type for top-level UI. Keep engine.fuel for parts and diagnostics displays.

Electrification fields

  • electrification_level, ev_drive_unit, battery_kwh, charger_level, charger_power_kw: Only populated for electrified vehicles. Nulls are expected for gasoline and diesel vehicles. Avoid displaying “0 kWh” when battery_kwh is null.

Plant and manufacturer

  • plant.country, plant.city, plant.state, manufacturer: Useful for compliance labeling and regional analytics. Present them as-is; do not infer geography beyond what’s returned.

Safety data specifics (U.S. only)

  • recalls_count/recalls: Display the count prominently. Provide an expandable list of recall items with campaign ID, summary, consequence, and remedy. “received” is a YYYY-MM-DD string; display in user locale as needed.
  • complaints_count: Use as an indicator; do not inflate confidence by normalizing across model years without context.
  • safety_ratings: Ratings are integers representing NCAP stars or null when not rated. Show partial matches with a note explaining that the NCAP configuration may differ slightly from the exact trim.

Handling non-U.S. VINs

The endpoint returns 200 with specs for non-U.S. VINs. Expect the U.S.-specific safety fields to be absent or null. Your UI should:

  • Show core specs confidently.
  • Hide or de-emphasize U.S.-only sections if coverage is not “us”.
  • Cache the result and schedule a re-check rather than retrying every request.

Security, PII, and compliance

  • VINs are not PII, but treat user-submitted identifiers as sensitive in logs. Mask VINs in client-side error messages where appropriate.
  • Use HTTPS only (the API enforces TLS). Do not embed API keys in client code served to browsers.
  • For server-to-server calls, store the X-API-Key in your secret manager and rotate as per your org’s policy.

MCP server for agents and tools

If you’re building Transportation agents or IDE-integrated workflows, the same Vehicle Report capability is available through the Model Context Protocol (MCP) server at MCP. This is useful when your agent runtime prefers MCP tools instead of direct HTTP requests.

Operational tips that save time

  • Idempotent replays: You can safely replay failed reads from queues without side effects.
  • Logging: Log the envelope’s source field to correlate upstream issues (e.g., scheduled maintenance in public datasets).
  • Pagination: Not applicable for this endpoint; all data relevant to the VIN returns in a single object.
  • Timestamps: “received” in recalls is a date string; there are no timezone ambiguities in this field.
  • SLA expectations: Because safety data originates from U.S. public datasets, plan for occasional upstream refresh variance. Cache and retry appropriately.

For additional details and edge cases, see the Documentation. You can also explore more at vehicles-api.com.

Testing checklist

  • Verify envelope parsing: status, source, data.
  • Exercise null-handling on electrification and NCAP fields.
  • Simulate 4xx/5xx and ensure retries/backoff logic works.
  • Cache a known VIN and confirm UI loads from cache without calling the API unnecessarily.
  • Add monitoring for recall count deltas to detect upstream data changes over time.

FAQ

Does the Vehicle Report include title, accident, or ownership history?
No. This is not a vehicle history report. It provides decoded specs plus U.S. recalls, complaint counts, and NCAP ratings where available.

What happens with a non-U.S. VIN?
You receive a 200 response with decoded specs. U.S.-only safety data may be absent or null. Use coverage and null checks to adjust your UI.

How should I cache results?
Cache decoded specs by VIN for long periods. Refresh U.S. safety data on a periodic schedule, since recalls and complaint counts can change as NHTSA updates datasets.

What error format should I expect?
All responses use the same envelope. On error, check error.code and error.message for a machine-readable code and a human-readable message. You may also see HTTP 429 if you exceed your plan limits.

Can I use MCP instead of HTTP?
Yes. Use the Model Context Protocol server described at MCP when building Transportation agents or IDE-integrated tools.

Ready to integrate the Vehicle Report API with a 7-day free trial? Create your key and start testing in minutes: Register.

Keep reading