API access uses API Consumers and JWT bearer tokens. Create credentials in your dashboard, keep Client Secrets on your server, and request an audience-specific token before calling this API. See the API access and authentication guidance.
Our VINdecode API provides detailed vehicle specifications based on the submitted vehicle identification number (VIN). These specifications include the year, make, model, engine and transmission details, color, and both standard and optional equipment. This API method supports the submission of one VIN at a time and returns comprehensive specifications. The returned data includes the vehicle's country of origin, year/make/model details, engine and powertrain specifics, manufacturer-included options, and other specifications such as gross vehicle weight (GVW) and MSRP.
Our records show that some users with unlimited access to the VINdecode API tend to make excessive and sometimes unnecessary API calls. To maintain the overall health of our system, we may block traffic from a specific source once it reaches a certain level. This ensures that one user's actions do not negatively impact the larger community. We reserve the right to throttle excessive API calls or even refuse service if necessary.
REST API Description
Our VINdecode API provides programmatic access to our VIN decode database.
| Parameter Name | Parameter | Value | Used in Request |
| JWT Bearer Token * | Authorization header * | Bearer <jwt-token> | Authorization: Bearer <jwt-token> |
| Vehicle Identification Number * | VIN * | XXXXXXXXXXXXXXXXX | GET https://ws.vinquery.com/vindecode/v3?VIN=XXXXXXXXXXXXXXXXX&reportType=3 |
| Data Type * | reportType * | 0, 1, 2, 3 | GET https://ws.vinquery.com/vindecode/v3?VIN=XXXXXXXXXXXXXXXXX&reportType=3 |
| Partial VIN ** | partialVIN ** | TRUE or FALSE (default: FALSE) | GET https://ws.vinquery.com/vindecode/v3?VIN=XXXXXXXXXXXXXXXXX&reportType=3&partialVIN=TRUE |
| Data Format | format | XML or JSON (default: XML) | GET https://ws.vinquery.com/vindecode/v3?VIN=XXXXXXXXXXXXXXXXX&reportType=3&partialVIN=TRUE&format=JSON |
POST https://identity.vinquery.com/connect/token using an API Consumer with audience vinquery:api:vindecode.Data Types
| Data Code | Data Type | Data Format |
| 0 | Basic Data | ws_vindecode_bas.xml | ws_vindecode_bas.json |
| 1 | Standard Data | ws_vindecode_std.xml | ws_vindecode_std.json |
| 2 | Extended Data | ws_vindecode_ext.xml | ws_vindecode_ext.json |
| 3 | Lite Data | ws_vindecode_lit.xml | ws_vindecode_lit.json |
Lookup Tables
These tables are static. They don't change often, if at all.
| Body Style Show the complete list of all possible body styles used in our system. | ||||||||||||||||||||
| COUPE 2-DR | CREW CAB PICKUP 4-DR | CROSSOVER 4-DR | EXTENDED CAB PICKUP 4-DR | HATCHBACK 2-DR | HATCHBACK 4-DR | PASSENGER VAN | REGULAR CAB PICKUP 2-DR | SEDAN 4-DR | SPORT UTILITY 4-DR | SPORTS VAN | WAGON 4-DR | WAGON 5-DR | ||||||||
| Vehice Type Show the complete list of all possible vehicle types used in our system. | ||||||||||||||||
| BUS | MOTORCYCLE | MPV | PASSENGER | RECREATIONAL | TRAILER | VAN | LOW SPEED VEHICLE | ELECTRIC VEHICLE | DUMP TRUCK | TRACTOR TRUCK | SNOWMOBILE | ATV | ||||
| Fuel Type | |||||||||
| CNG | DIESEL | ELECTRIC | FFV | GAS | HYBRID | PLUG-IN HYBRID | HYDROGEN | LPG | No data |
| Engine Shape | ||||||||||||||||||||
| H12 | H4 | H6 | L2 | L3 | L4 | L5 | L6 | No data | NO ENGINE | ROTARY | V10 | V12 | V20 | V4 | V6 | V8 | VL | W12 | W16 | W8 |
| Driveline | ||||||||||||||||
| 10X4 | 10X6 | 12X6 | 4WD | 4X2 | 4X4 | 6X2 | 6X4 | 8X4 | 8X6 | AWD | FWD | FWD | AWD | RWD | RWD | AWD | 2WD | No data |
Error Codes
| Error Code (Key) | Description (Value) |
| 0 | Database Errors. |
| 2 | Valid VIN number. However, no data available for it at this moment. |
| 3 | Invalid VIN number: This VIN number did not pass checksum test |
| 4 | Invalid VIN number: A valid VIN number must be exactly 17 digits |
| 5 | Invalid VIN number: This VIN number contains invalid letters: I,O or Q. |
| 6 | Invalid report type. A valid report type should be 0 for BASIC, 1 for STANDARD, 2 for EXTENDED or 3 for LITE. |
| 8 | Service access denied: check that the bearer token is valid, unexpired, and issued for the VINdecode audience. |
| 9 | Report type missing: A report type (0,1,2 or 3) must be specified. |
| 10 | Insufficient balance for Basic Reports. |
| 11 | Insufficient balance for Standard Reports. |
| 12 | Insufficient balance for Extended Reports. |
| 13 | VIN missing: A VIN must be submitted as part of the querystring. |
| 14 | Invalid VIN number: The 10th digit of a VIN number cannot be letter U, letter Z or number 0. |
| 15 | Insufficient balance for Lite Reports. |
| 16 | A VIN can only contain alphanumeric characters. |
A sample error message returned in XML format:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<VINdecode version="3.0" report_type="EXTENDED" Date="8/27/2022">
<VIN number="1FTRF02W24KXXXXXX" status="FAILED">
<Message Key="3" Value="Invalid VIN number: This VIN number did not pass checksum test." />
</VIN>
</VINdecode>
A sample error message returned in JSON format:
{
"service": "vindecode",
"version": "3.0",
"date": "8/27/2022",
"vin": "1FTRF02W24KXXXXXX",
"status": "FAILED",
"message_key": "3",
"message": "Invalid VIN number: This VIN number did not pass the checksum test."
}
Known Issues
- A single VIN returns data related to multiple trim levels.
- A single trim level returns multiple transmissions, exterior colors, interior trims, ABS(Non-ABS |* 2-Wheel ABS |* 4-Wheel ABS) etc.
Occasionally, information coded by the manufacturer in a submitted VIN may not be sufficient for our VIN decode engine to narrow it down to a single trim level so all available records for that particular VIN will be returned. In this case, all available trim levels may have to be presented to end users so they can make a selection from those returned choices.
For instance, a decoded VIN may offer all exterior color choices that were available for a particular vehicle, but can't tell you what color the vehicle actually is - therefore all available color choices for the vehicle might have to be presented to end users so they can select the color or have the option to enter another color choice in case the vehicle was painted over.
* "|" is used as a delimiters or separator when a data item contains multiple choices.
Coding Examples (JWT Authentication)
VINdecode now uses JWT bearer authentication. Request a token from the Identity service with the VINdecode audience, then send that token to the VINdecode API in the Authorization header. Keep API Consumer credentials on your server.
# Request a JWT access token.
TOKEN=$(curl -s -X POST "https://identity.vinquery.com/connect/token" \
-H "Content-Type: application/json" \
-d '{"clientId":"YOUR_CLIENT_ID","clientSecret":"YOUR_CLIENT_SECRET","audience":"vinquery:api:vindecode"}' \
| jq -r '.jwtToken')
# Call the API with the bearer token.
curl -X GET "https://ws.vinquery.com/vindecode/v3?VIN=1FMCU0F76EUC78242&reportType=3&format=JSON" \
-H "Authorization: Bearer $TOKEN"
// JavaScript / Node.js server-side example.
const tokenResponse = await fetch("https://identity.vinquery.com/connect/token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
clientId: "YOUR_CLIENT_ID",
clientSecret: "YOUR_CLIENT_SECRET",
audience: "vinquery:api:vindecode"
})
});
const { jwtToken } = await tokenResponse.json();
const apiResponse = await fetch(
"https://ws.vinquery.com/vindecode/v3?VIN=1FMCU0F76EUC78242&reportType=3&format=JSON",
{ headers: { Authorization: `Bearer ${jwtToken}` } }
);
console.log(await apiResponse.json());
import requests
token_response = requests.post(
"https://identity.vinquery.com/connect/token",
json={
"clientId": "YOUR_CLIENT_ID",
"clientSecret": "YOUR_CLIENT_SECRET",
"audience": "vinquery:api:vindecode",
},
)
token_response.raise_for_status()
jwt_token = token_response.json()["jwtToken"]
response = requests.get(
"https://ws.vinquery.com/vindecode/v3",
params={"VIN": "1FMCU0F76EUC78242", "reportType": "3", "format": "JSON"},
headers={"Authorization": f"Bearer {jwt_token}"},
)
response.raise_for_status()
print(response.json())
<?php
$tokenRequest = json_encode([
'clientId' => 'YOUR_CLIENT_ID',
'clientSecret' => 'YOUR_CLIENT_SECRET',
'audience' => 'vinquery:api:vindecode'
]);
$tokenCurl = curl_init('https://identity.vinquery.com/connect/token');
curl_setopt_array($tokenCurl, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => $tokenRequest
]);
$tokenResult = json_decode(curl_exec($tokenCurl), true);
curl_close($tokenCurl);
$apiCurl = curl_init('https://ws.vinquery.com/vindecode/v3?VIN=1FMCU0F76EUC78242&reportType=3&format=JSON');
curl_setopt_array($apiCurl, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $tokenResult['jwtToken']]
]);
$response = curl_exec($apiCurl);
curl_close($apiCurl);
echo $response;
?>
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
String tokenBody = "{\"clientId\":\"YOUR_CLIENT_ID\",\"clientSecret\":\"YOUR_CLIENT_SECRET\",\"audience\":\"vinquery:api:vindecode\"}";
HttpRequest tokenRequest = HttpRequest.newBuilder()
.uri(URI.create("https://identity.vinquery.com/connect/token"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(tokenBody))
.build();
String tokenJson = client.send(tokenRequest, HttpResponse.BodyHandlers.ofString()).body();
String jwtToken = tokenJson.replaceAll(".*\\\"jwtToken\\\"\\s*:\\s*\\\"([^\\\"]+)\\\".*", "$1");
HttpRequest apiRequest = HttpRequest.newBuilder()
.uri(URI.create("https://ws.vinquery.com/vindecode/v3?VIN=1FMCU0F76EUC78242&reportType=3&format=JSON"))
.header("Authorization", "Bearer " + jwtToken)
.GET()
.build();
String response = client.send(apiRequest, HttpResponse.BodyHandlers.ofString()).body();
System.out.println(response);
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
func main() {
tokenPayload := []byte(`{"clientId":"YOUR_CLIENT_ID","clientSecret":"YOUR_CLIENT_SECRET","audience":"vinquery:api:vindecode"}`)
tokenResp, err := http.Post("https://identity.vinquery.com/connect/token", "application/json", bytes.NewReader(tokenPayload))
if err != nil {
panic(err)
}
defer tokenResp.Body.Close()
var tokenResult struct {
JwtToken string `json:"jwtToken"`
}
if err := json.NewDecoder(tokenResp.Body).Decode(&tokenResult); err != nil {
panic(err)
}
req, err := http.NewRequest("GET", "https://ws.vinquery.com/vindecode/v3?VIN=1FMCU0F76EUC78242&reportType=3&format=JSON", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+tokenResult.JwtToken)
apiResp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer apiResp.Body.Close()
body, _ := io.ReadAll(apiResp.Body)
fmt.Println(string(body))
}
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using var http = new HttpClient();
var tokenPayload = "{\"clientId\":\"YOUR_CLIENT_ID\",\"clientSecret\":\"YOUR_CLIENT_SECRET\",\"audience\":\"vinquery:api:vindecode\"}";
var tokenResponse = await http.PostAsync(
"https://identity.vinquery.com/connect/token",
new StringContent(tokenPayload, Encoding.UTF8, "application/json"));
tokenResponse.EnsureSuccessStatusCode();
using var tokenJson = JsonDocument.Parse(await tokenResponse.Content.ReadAsStringAsync());
var jwtToken = tokenJson.RootElement.GetProperty("jwtToken").GetString();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://ws.vinquery.com/vindecode/v3?VIN=1FMCU0F76EUC78242&reportType=3&format=JSON");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", jwtToken);
var response = await http.SendAsync(request);
response.EnsureSuccessStatusCode();
Console.WriteLine(await response.Content.ReadAsStringAsync());
