For developers & chat assistants
Vehicle facts, in JSON.
Look up manufacturer-reported vehicle specifications and public recall campaigns using a complete VIN. No API key or payment required by the application.
OpenAPI specificationMake a lookup
Send a GET request to /api/decode?vin=1HGCM82633A004352, or POST a JSON object with a vin field to /api/decode. Both methods use the same data and request budget.
This browser example uses the current deployment’s origin:
const vin = "1HGCM82633A004352";
const response = await fetch(
"/api/decode?" + new URLSearchParams({ vin })
);
const result = await response.json();
if (!response.ok) throw new Error(result.error);
console.log(result.vehicle);
console.log(result.sources);
console.log(result.reportUrl);For server tools, resolve the path against https://freevininfo.com. Complete request and response schemas are in the OpenAPI specification. Browser clients can use CORS without cookies or credentials. No bulk lookup endpoint is provided.
Interpret the results correctly
vehiclecontains the available decoded fields. Empty strings mean the source did not report a value.sourcesnames the datasets and includes each dataset’s actual retrieval timestamp and cache lifetime.recallStatusmust beavailablebefore interpreting therecallsarray. If it isunavailable, an empty array is not a negative result.- Campaigns match year, make, and model. They do not establish an open recall or repair status for the exact VIN.
sources.recalls.vinSpecificRepairStatusis alwaysnot_checked. coveragedescribes included data, excluded records, and interpretation limits. Accident, damage, title, theft, salvage, ownership, and odometer history are not included.reportUrlis a human-readable report link on freevininfo.com. For preview testing, use/report/followed by the normalized VIN on that deployment.
Specifications cache for up to 30 days; campaigns refresh daily. Cite the named source, retrieval date, and report link when presenting the results. A VIN decode does not establish ownership, current condition, or whether a vehicle is safe to buy.
Usage limits
The application applies a best-effort burst limit of 20 requests per 60 seconds per client per running server instance. GET and POST share a budget, including unsuccessful requests. OPTIONS requests do not consume it.
This in-memory limit resets when a process restarts and is not shared across scaled instances or regions. It is not a guaranteed global quota or a spending cap. Bulk use is not supported. A distributed limit is a separate production-hardening step if traffic grows.
Responses include X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset (Unix seconds), and X-RateLimit-Scope: instance. HTTP 429 includes Retry-After in seconds. Wait at least that long before retrying; use backoff for upstream failures.
Errors
| Status | Meaning |
|---|---|
| 400 | Missing or malformed VIN, or invalid JSON. |
| 422 | VIN could not be confidently decoded or its check digit failed. |
| 429 | Per-instance burst limit reached. |
| 500 | Unexpected server failure. |
| 502 | Unexpected upstream response. |
| 503 | NHTSA timed out or is temporarily unavailable. |
Error responses include an error message and a stable code. Preview authentication errors originate from Vercel and may have a different response format.
Privacy and fair use
Send only the VIN. Do not submit names, addresses, registration documents, or payment details. Lookup URLs may be logged by hosting infrastructure. The per-instance limiter holds a hashed client-IP identifier in memory; IP addresses can still appear in hosting logs. Local development uses one shared caller bucket.
Keep attribution and coverage limits with results. Do not describe the response as a full vehicle history or damage check. The optional NICB link in the website is an external lookup, not an integrated API dataset.