All vehicles being sold in the United States of America are required to have an identification code known as VIN (vehicle identification number). VINs were first used in 1954. VINs are uniformly structured and contain important information about the vehicle.
Since 1981, the National Highway Traffic Safety Administration (NHTSA) has been using a fixed 17-character VIN format. A standard VIN number consists of 4 major sections: manufacturer identifier, vehicle attributes, check digit, and vehicle identification section.
Why do we need a VIN number and a VIN-decoder?
Running a VIN check or otherwise known as a VHR (Vehicle History Report) can save you money and headaches in the future. Shelling out a few dollars can save you thousands once you get to know about your prospective car’s history.
Where can I find a VIN-decoder?
In this article, we will look at the process of creating an application using a vin-decoder using the RapidAPI service. RapidAPI is the world’s largest API marketplace that was founded in 2015 where over a million developers find and connect to thousands of public APIs in more than 40 categories. It also allows them to share and collaborate on internal APIs.
First of all, we start with registration. You can use your social accounts or email. Depending on which registration method you choose, the service may require you to enter additional information.
In the process of registering you as a user, RapidAPI does not require payment data or any type of payment. Now we have access to the database with more than 20,000 public APIs.
To search and navigate the service, we can use the search bar or category menu. In order to find the API we need, let’s write its name in the search bar. The search is carried out in real-time and results don’t take long to show up.
After the service has displayed the results, click on an individual result for a more detailed description including capabilities and pricing policy. By going to the VIN-decoder page, you are given the opportunity to familiarize yourself with the information in the fields:
- Endpoints (description of the API and instructions to connect on many programming languages)
- About (info about functionality, updates and contact info)
- Discussions (field for asking questions or just leave a comment)
- Pricing (choose a plan that best matches the scale you need for your application)
You can also view the analytics of the connector based on three values: popularity, success rates, and latency.
A Freemium API includes a free tier (a Basic plan) that we can use for a test launch of the application within the limitations specified. Let’s take a look at the table below describing the limits of different plans.
Now we can choose a plan for the scale of use and provide payment information to pay for a monthly plan and/or for payment requests in case of exceeding the monthly limits. After entering payment details and confirmation, RapidAPI redirects us to the page with a list of resources provided by the vin-decoder API. On this page, we have three sections, which have a ready-to-use toolkit that we can manipulate for testing endpoints.
What tools are available for us
1. List of resources
In this section, we can find and navigate all resources that are provided by vin-decoder at RapidAPI. This connector contains the following resources:
– Decode Vin (GET) available in 3 versions;
– Salvage Check (GET);
– USA Plate Number Lookup (POST);
To obtain relevant data after sending a GET request to Decode VIN, we will use the latest version, V2.0. This version contains more information about the car.
2. Parameters of request to the endpoint
Header Parameters
To correctly send the request from the app to the vin-decoder, we must put API-Key and Host in headers. The key assigned to each user is unique. It is used to authenticate requests in every RapidAPI connector. You can create a new API Key and delete the compromised one from the Developer Dashboard in a few steps. You can also view the analytics specific to each app in your account.
Required Parameters
We send data to the body of each request to process it. In our case, for two endpoints (Decoder Vin, Salvage check), only a VIN number is required.
The USA Plate Number Lookup resource requires plate number and state.
3. Response
If the resource has accepted the request and successfully processed it, we will receive a response with the code 200 containing the information we need.
Decode Vin (GET)
Salvage Check (GET)
USA Plate Number Lookup (POST)
How can we build our application?
Well, we signed up for the Basic plan and got acquainted with the resources and answers provided by the vin-decoder. To create the application we will be using Python. Let’s get acquainted with possible connection methods that RapidAPI provides. To build requests, we are offered code options that use third-party libraries. Among them are Requests which we will use, Unirest, and the standard HTTP library. We also need the Flask framework. The most important thing to have installed is Python version 3 or later.
To prepare the environment, we will use these commands:
# Сreate project folder mkdir vin_decoder cd vin_decoder # Сreate and activate virtual environment python -m venv vin-decoder-venv source ./vin-decoder-venv/bin/activate # Install the dependencies necessary for the application to work pip install requests, flask
The environment is ready now, so let’s start to design our one-page application. This application will be created using Flask. It will have three resources for transmitting data that we will get by connecting the VIN-decoder. After the application is loaded, it will send ajax requests based on the received data from the user. After sending an ajax request to one of the resources, depending on the user’s choice, it will return JSON for further processing and display on the page.
In the project directory, create an app.py file that will contain the Flask application and resources connecting to the VIN-decoder. Open the file and insert this code:
Import the necessary modules and create Flask instance:
# import necessary modules and classes import requests from flask import ( Flask, Blueprint, render_template, jsonify, request ) # create instance of Flask app = Flask(__name__)
Define header for connecting to the VIN-decoder:
Since we already mentioned the headers above in the section about tools, you know where to get them.
headers = { 'x-rapidapi-host': "vindecoder.p.rapidapi.com", 'X-rapidapi-key': "<your rapidAPI unique key>"}
Define resources for connecting and get data from VIN-decoder:
1. Decode-vin:
@app.route('/decode_vin', methods=['GET']) def decode_vin(): url = "https://vindecoder.p.rapidapi.com/v2.0/decode_vin" vin = str(request.args.get('vin')) if len(vin) == 17: querystring = {"vin": vin} response = requests.get(url, headers=headers, params=querystring) if response.status_code == 200: return jsonify(response.json())
The app will send an ajax request to this resource from the interface containing the VIN-number. Data will be processed through the Flask module “requests”. If the resource receives such a request and there is data in its body, then it will validate the data, confirming that the number consists of 17 characters. In case of successful validation, it sends a request to the VIN-decoder API. Then it must check the response code. If it is 200, then it returns JSON.
2. Salvage Check
@app.route('/salvage_check', methods=['GET']) def salvage_check(): url = "https://vindecoder.p.rapidapi.com/salvage_check" vin = str(request.args.get('vin')) if len(vin) == 17: querystring = {"vin": vin} response = requests.get(url, headers=headers, params=querystring) if response.status_code == 200: return jsonify(response.json())
As you can see, the code for this resource is not much different from the previous one, since it requires the same VIN number. However, there is a difference in the URL.
3. USA Plate Number Lookup
@app.route('/usa_plate_number_lookup', methods=['GET', 'POST']) def usa_plate_number_lookup(): url = "https://vindecoder.p.rapidapi.com/api/v4/decode_plate" plate, state = request.args['plate'], request.args['state'] if len(plate) >=5 and len(plate) <= 7 and state != 'State': payload = f"state={state}&plate={plate}" headers.update({'content-type': 'application/x-www-form-urlencoded'}) response = requests.post(url, data=payload, headers=headers) del headers['content-type'] if response.status_code == 200: return jsonify(response.json()
The concept of this resource is similar to the previous one. The resource receives data from the user interface, validates it, sends a request to the VIN-decoder, gets a response, checks the response code, and sends JSON to the interface. Unlike the previous resource, there is no need for a VIN-number. The data required is a plate number and a short state name. Since the resource will send a POST request to the VIN-decoder, it must add the type of the request’s body and delete it after receiving the response.
Define a route for rendering interface
For a one-page application, we will use the HTML template, which will be done with Flask, using render_template. Flask uses the Jinja template engine, which allows you to transfer data to display it on the page. In the USA Plate Number Lookup resource, the user must specify the plate number and state. Let’s pass the list of state abbreviations to render_template, and then see how you can use Jinja to display them on an HTML page. We have not yet created an HTML file, but let’s imagine that we already have it and we named it index.html. Then the code will look as follows.
@app.route('/') def index(): return render_template('index.html', states=states)
Let’s go up to our app.py file to the lines of code with the imports and add a list of states after them.
states = [ 'State','AL','AK','AZ','AR','CA','CO','CT','DE','DC','FL','GA','GU','HI','ID','IL','IN','IA','KS','KY','LA','ME','MD','MA','MI','MN','MS','MO','MT','NE','NV','NH','NJ','NM','NY','NC','ND','OH','OK','OR','PA','PR','RI','SC','SD','TN','TX','VI','UT','VT','VA','WA','WV','WI','WY' ]
Now it’s time to write an HTML template. To do this, create the “templates” folder in the root folder of the application. Let’s go into it and create the index.html file. When the file is created we can use this HTML structure.
<!DOCTYPE html> <html> <head> <title>VIN Decoder APP</title> <link rel="stylesheet" href="/static/css/style.css" type="text/css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"> </script></head> <body style="background-color: #F7FFF7;"> <div class='content'> <div class="container-fluid logo operational">Vin decoder</div> <div class="container-fluid d-flex operational"> <form id="form_to_api" action=""> <div id="decoder_salvage" class="form-group mr-3"> <input id='vin' class="form-control decoder salvage" placeholder="please enter your vin number" type="text"> <small class="form-text text-muted ml-1">17-character VIN format, example: 4F2YU09161KM33122</small></div> <div id="post_plate_number" class="form-group d-flex mr-3 invisible"> <div class="mr-1"> <input id='plate' class="form-control mr-3" autocomplete='off' placeholder="please enter your plate" type="text"> <small class="form-text text-muted ml-1">5-7 characters long, example: 6NTE470</small></div> <div> <select id="state" class="custom-select"> {% for state in states %} <option value={{ state }}>{{ state }}</option> {% endfor %} </select> </div></div></form> <div class="ml-3"> <select id="select_resource" class="custom-select"> <option value="decode_vin">Decoder VIN</option> <option value="salvage_check">Salvage check</option> <option value="usa_plate_number_lookup">USA Post Plate Number</option> </select></div></div> <div id='response' class='container-fluid response'></div></div> <script src="/static/js/main.js" type="text/javascript" charset="utf-8"> </script> </body> </html>
As you can see in the template, Bootstrap styles are used, so you need to connect CDN for their work. Custom CSS is also used. To display styles in an HTML page, you need to specify the path where the css file is located. Flask provides access to the static folder that we have created in the root of the project. Since we will include a js script in the future, which is also located in the static folder, let’s separate them into different folders: CSS and js. In the CSS folder, place the style.css file with the following rules.
.logo { text-align: center; font-size: 4em; } .operational { margin-left: auto; margin-right: auto; justify-content: center; height: 120px; width: 75%; padding-top: 25px; } .valid:focus { box-shadow: 0 0 0 0.2rem rgb(9, 249, 69) !important; } .invalid { color: red; box-shadow: 0 0 0 0.2rem red !important; } .response { margin-left: auto; margin-right: auto; width: 50%; color: #1d1f21; } .detail_none { display: none; } .with_items:hover { background-color: #e8ffba; }
We don’t want to create a heap of forms and buttons on the page of our application, which is why we implement dynamic switching of forms and corresponding resources for them, depending on the user’s choice. To implement this, we will use ajax and jQuery. First of all, we create the main.js file in the js folder and put the following code into it.
In this block of code, we determine how events related to forms and selects will be processed. When choosing a resource, we take its value, pass it through the condition, and display the appropriate form for entering data. It may happen that we will also collect data already present in the displayed form. The next step is the validation of entered data and, if successful, sending a request for a resource. In a similar way, we process events directly from the forms for entering data, but here we no longer manipulate turning on and off the forms themselves.
$(function(){ let resource; $('select#select_resource').on('keyup change', function() { resource = $(this).children("option:selected").val(); console.log(resource) if (resource == 'decode_vin' || resource == 'salvage_check') { $('#decoder_salvage').show() $('#post_plate_number').addClass('invisible'); } else { $('#decoder_salvage').hide() $('#post_plate_number').removeClass('invisible'); } elements = $('#form_to_api').find($('#vin, #plate, #state')) if (validationInput(elements, resource)) { sendRequest(resource, getParams(elements, resource)) } else { renderHtml('') } }) $('#form_to_api, #vin, #post_plate_number').on('keyup change', function() { resource = $("#select_resource").val() elements = $(this.elements) if (validationInput(elements, resource)) { sendRequest(resource, getParams(elements, resource)) } else { renderHtml('') } })
In our case, all responses from the server will be overwritten in the #response block. An event for which we are processing in order to reveal an element that will contain a list.
$(".content").on('click', '#response', function (e) { var class_to_show = e.target.id $(`.${class_to_show}`).toggleClass('detail_none') }) })
For data validation, we will use the principle of red and green colors that is clear and understandable to everyone. Valid limits for data are known to us. We implement class switching for valid and invalid data.
validationInput = function(elements, resource) { [vin, plate, state] = elements.map(function(i,element){return element;}) var valid = false if (resource == 'usa_plate_number_lookup') { if (plate.value.length >= 5 && plate.value.length <= 7 && resource == 'usa_plate_number_lookup') { $(plate).addClass('valid') if (state.value !== 'State') { valid = true $(state).removeClass('invalid') $(state).addClass('valid') } else { $(state).addClass('invalid') $(state).removeClass('valid') } } else { $(plate).removeClass('valid') } } else { if (vin.value.length == 17 && ['decode_vin', 'salvage_check'].includes(resource)) { $(vin).toggleClass('valid') valid = true } else { $(vin).removeClass('valid') } } return valid }
After successful validation, the data is sent in the request body, described in the function below
getParams = function (elements, resource) { [vin, plate, state] = elements.map(function(i,element){return element.value;}) if (resource == 'usa_plate_number_lookup') { data = {plate, state} } else { data = {vin} } return data }
When the data is collected, we send a request for a resource that is transferred to the function from the <select> block.
sendRequest = function (url, data) { $.ajax({ cache: false, url, type: 'GET', data, dataType: 'json', success: function(response) { renderHtml(response) } }) }
If the request is successfully processed and a response is received, we display it on the page. Using the hide () and show () methods, we create an animated data display. Also, with each request, we will overwrite the #response block with the data from the response.
renderHtml = function(response) { $('#response').hide() $('#response').empty().append(responseToHtml(response)) $('#response').show('slow') }
In this function, we will concatenate HTML elements with data from the response. Since resources return a response with different keys to the data, we will write their keys to the list. Using the loop, we determine which key is present in the response and process its data.
responseToHtml = function (response) { let data = ['specification', 'info', 'data'] var htmlPartOfResponse = '<ul class="list-group">' for (var i in data) { var field = data[i] if (response[field]) { for (var key in response[field]) { if ( !response[field][key] ) { htmlPartOfResponse += `<li class="list-group-item disabled">${key.replace('_', ' ').toUpperCase()}: ${response[field][key]}</li>` } else { if ( Array.isArray(response[field][key]) ) { listPart = parseListItemsToHtml(key, response[field]) htmlPartOfResponse += listPart } else { htmlPartOfResponse += `<li class="list-group-item">${key.replace('_', ' ').toUpperCase()}: ${response[field][key]}</li>` } } } } } htmlPartOfResponse += '</ul>' return htmlPartOfResponse }
In this function, we added a check to see if an array is present in the value. This is necessary since some data contains nested elements that also need to be included in the display on the page. If the condition is satisfactory, we go through the contents of the array adding its values to a separate block, which will be hidden and displayed when you click on the parent element. This is how it looks.
parseListItemsToHtml = function (key, data) { listItems = `<li id=${key} href='' class="list-group-item d-flex justify-content-between align-items-center with_items">${key.replace('_', ' ').toUpperCase()}:<span class="badge badge-primary badge-pill">${data[key].length}</span></li>` for (var i in data[key]) { listItems += `<li class="list-group-item detail_none font-italic ${key}" style="text-align: center;">${data[key][i]}</li>` } return listItems }
Start The Application
The application has now been created. We only need to add a point of entry and run it. To do this, add the line to the bottom of the app.py file:
if __name__=='__main__': app.run()
In the terminal at the root of the application folder, run the command:
python app.py
Now head over to http://127.0.0.1:5000/ in your browser, and you should see our application.
Conclusion
In this article, we have considered RapidAPI, its features, and its interface. We have also shown you a way to quickly and easily integrate the VIN-decoder API into our applications. Of course, the application features can be more extensive and functional. For example, you may include the possibility of authorization, create a personal account with your personal data, incorporate notifications of changes, and many others.
Using the VIN-decoder you can be sure that you will know everything about the car before buying it especially about serious accidents in the past that could make it dangerous for you and your loved ones.
Leave a Reply