US Driver License OCR
Automatically extract data from US Driver Licenses
Mindee’s US Driver License OCR API uses deep learning to automatically, accurately, and instantaneously parse your Driver License details. In under a second, the API extracts a set of data from your PDFs or photos of Driver Licenses, including:
- State
- Driver License ID
- Expiry Date
- Date Of Issue
- Last Name
- First Name
- Address
- Date Of Birth
- Restrictions
- Endorsements
- Driver License Class
- Sex
- Height
- Weight
- Hair Color
- Eye Color
- Document Discriminator
- Photo
- Signature
The US Driver License OCR API supports the horizontal format for adult drivers in all U.S. states. Full support for vertical formats and underage driver's licenses cannot be guaranteed at this time. Also driver's licenses outside the US states are not supported in this model.
Set up the API
Before making any API calls, you need to have created your API key.
- You'll need a US Driver License. You can use the sample document provided below.
- Access your Receipt API by clicking on the US Driver License card in the Document Catalog
- From the left navigation, go to documentation > API Reference, you'll find sample code in popular languages and command line.
curl -X POST \\
https://api.mindee.net/v1/products/mindee/us_driver_license/v1/predict \\
-H 'Authorization: Token my-api-key-here' \\
-H 'content-type: multipart/form-data' \\
-F document=@/path/to/your/file.png
import json
import requests
api_key = "my-api-key-here"
account = "mindee"
endpoint = "us_driver_license"
version = "1.0"
url = f"https://api.mindee.net/v1/products/{account}/{endpoint}/v{version}/predict"
with open("/path/to/the/file.ext", "rb") as file_handle:
files = {"document": file_handle}
headers = {"Authorization": f"Token {api_key}"}
response = requests.post(url, files=files, headers=headers)
json_response = response.json()
if not response.ok:
raise RuntimeError(json_response["api_request"]["error"])
print(json.dumps(json_response["document"], indent=2))
// works for NODE > v10
const axios = require("axios");
const fs = require("fs");
const FormData = require("form-data");
const apiKey = "my-api-key-here";
const account = "mindee";
const endpoint = "us_driver_license";
const version = "1.0";
async function makeRequest(filePath) {
let data = new FormData();
data.append("document", fs.createReadStream(filePath));
const config = {
method: "POST",
url: `https://api.mindee.net/v1/products/${account}/${endpoint}/v${version}/predict`,
headers: {
Authorization: `Token ${apiKey}`,
...data.getHeaders()
},
data
}
try {
let response = await axios(config)
console.log(response.data);
} catch (err) {
console.error(err);
process.exit(1);
}
}
makeRequest("/path/to/the/file.ext");
require 'uri'
require 'net/http'
require 'net/https'
url = URI('https://api.mindee.net/v1/products/mindee/us_driver_license/1.0/predict')
file = '/path/to/the/file.ext'
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request['Authorization'] = 'Token my-api-key-here'
request.set_form([['document', File.open(file)]], 'multipart/form-data')
response = http.request(request)
puts response.read_body
<form onsubmit="mindeeSubmit(event)" >
<input type="file" id="my-file-input" name="file" />
<input type="submit" />
</form>
<script type="text/javascript">
const mindeeSubmit = (evt) => {
evt.preventDefault()
let myFileInput = document.getElementById('my-file-input');
let myFile = myFileInput.files[0]
if (!myFile) { return }
let data = new FormData();
data.append("document", myFile, myFile.name);
let xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("POST", "https://api.mindee.net/v1/products/mindee/us_driver_license/v1/predict");
xhr.setRequestHeader("Authorization", "Token my-api-key-here");
xhr.send(data);
}
</script>
using Mindee;
using Mindee.Parsing;
string apiKey = "my-api-key-here";
string filePath = "/path/to/the/file.ext";
MindeeClient mindeeClient = MindeeClientInit.Create(apiKey);
CustomEndpoint myEndpoint = new CustomEndpoint(
endpointName: "us_driver_license",
accountName: "mindee",
version: "1.0"
);
var documentParsed = await mindeeClient
.LoadDocument(new FileInfo(filePath))
.ParseAsync(myEndpoint);
System.Console.WriteLine(documentParsed.ToString());
import com.mindee.MindeeClient;
import com.mindee.input.LocalInputSource;
import com.mindee.parsing.common.PredictResponse;
import com.mindee.product.custom.CustomV1;
import com.mindee.http.Endpoint;
import java.io.File;
import java.io.IOException;
public class SimpleMindeeClient {
public static void main(String[] args) throws IOException {
String apiKey = "my-api-key-here";
String filePath = "/path/to/the/file.ext";
// Init a new client
MindeeClient mindeeClient = new MindeeClient(apiKey);
// Load a file from disk
LocalInputSource inputSource = new LocalInputSource(new File(filePath));
// Configure the endpoint
Endpoint endpoint = new Endpoint(
"us_driver_license",
"mindee",
"1.0"
);
// Parse the file
PredictResponse<CustomV1> response = mindeeClient.parse(
inputSource,
endpoint
);
// Print a summary of the response
System.out.println(response.toString());
// Print a summary of the predictions
// System.out.println(response.getDocument().toString());
// Print the document-level predictions
// System.out.println(response.getDocument().getInference().getPrediction().toString());
// Print the page-level predictions
// response.getDocument().getInference().getPages().forEach(
// page -> System.out.println(page.toString())
// );
}
}
- Replace my-api-key-here with your new API key, or use the "select an API key" feature and it will be filled automatically.
- Copy and paste the sample code of your desired choice in your application, code environment or terminal.
- Replace
/path/to/my/file
with the path to your receipt.
Always remember to replace your API key!
- Run your code. You will receive a JSON response with the receipt details.
API Response
Here is the full JSON response you get when you call the API:
{
"api_request": {
"error": {},
"resources": [
"document"
],
"status": "success",
"status_code": 201,
"url": "https://api.mindee.net/v1/products/mindee/us_driver_license/v1/predict"
},
"document": {
"id": "8ef614fa-17b4-4aa0-b64f-6ffe96c70d98",
"name": "sample_receipt.jpg",
"n_pages": 1,
"is_rotation_applied": true,
"inference": {
"started_at": "2023,-05-06T16:37:28",
"finished_at": "2023-05-06T16:37:29",
"processing_time": 1.755,
"pages": [
{
"id": 0,
"orientation": {"value": 0},
"prediction": { .. },
"extras": {}
}
],
"prediction": { .. },
"extras": {}
}
}
}
You can find the prediction within the prediction
key found in two locations:
- In
document > inference > prediction
for document-level predictions: it contains the different fields extracted at the document level, meaning that for multi-pages PDFs, we reconstruct a single receipt object using all the pages. - In
document > inference > pages[ ] > prediction
for page-level predictions: it gives the prediction for each page independently. With images, there is only one element on this array, but with PDFs, you can find the extracted data for each PDF page.
Each predicted field may contain one or several values:
- a
confidence
score - a
polygon
highlighting the information location - a
page_id
where the information was found (document level only)
{
"extras": {},
"finished_at": "2023-06-02T08:56:47.718732",
"is_rotation_applied": true,
"pages": [
{
"extras": {},
"id": 0,
"orientation": {"value": 0},
"prediction": {
"address": {
"confidence": 0.98,
"polygon": [
[0.318, 0.513],
[0.659, 0.513],
[0.659, 0.586],
[0.318, 0.586]
],
"value": "123 SAMPLE ST JEFFERSON CITY MO 65105"
},
"dl_class": {
"confidence": 0.99,
"polygon": [
[0.402, 0.293],
[0.428, 0.293],
[0.428, 0.339],
[0.402, 0.339]
],
"value": "F"
},
"contour": {
"polygon": [
[-0.03, -0.047],
[1.029, -0.047],
[1.029, 1.046],
[-0.03, 1.046]
]
},
"date_of_birth": {
"confidence": 0.75,
"polygon": [
[0.705, 0.35],
[0.871, 0.35],
[0.871, 0.388],
[0.705, 0.388]
],
"value": "1979-02-14"
},
"dd_number": {
"confidence": 0.99,
"polygon": [
[0.37, 0.896],
[0.569, 0.896],
[0.569, 0.938],
[0.37, 0.938]
],
"value": "101230320002"
},
"driver_license_id": {
"confidence": 0.99,
"polygon": [
[0.399, 0.345],
[0.595, 0.345],
[0.595, 0.396],
[0.399, 0.396]
],
"value": "T123456789"
},
"endorsements": {
"confidence": 0.99,
"polygon": [
[0.378, 0.606],
[0.414, 0.606],
[0.414, 0.652],
[0.378, 0.652]
],
"value": "M"
},
"expiry_date": {
"confidence": 0.95,
"polygon": [
[0.705, 0.295],
[0.872, 0.295],
[0.872, 0.335],
[0.705, 0.335]
],
"value": "2026-02-14"
},
"eye_color": {
"confidence": 0.99,
"polygon": [
[0.557, 0.757],
[0.629, 0.757],
[0.629, 0.799],
[0.557, 0.799]
],
"value": "BRO"
},
"first_name": {
"confidence": 0.99,
"polygon": [
[0.317, 0.45],
[0.642, 0.45],
[0.642, 0.502],
[0.317, 0.502]
],
"value": "SAMANTHA DRIVER"
},
"hair_color": {
"confidence": 0,
"polygon": [],
"value": null
},
"height": {
"confidence": 0.99,
"polygon": [
[0.378, 0.757],
[0.464, 0.757],
[0.464, 0.799],
[0.378, 0.799]
],
"value": "5-06"
},
"issued_date": {
"confidence": 0.98,
"polygon": [
[0.722, 0.793],
[0.87, 0.793],
[0.87, 0.827],
[0.722, 0.827]
],
"value": "2020-01-05"
},
"last_name": {
"confidence": 0.99,
"polygon": [
[0.318, 0.401],
[0.458, 0.401],
[0.458, 0.45],
[0.318, 0.45]
],
"value": "SAMPLE"
},
"orientation": {
"confidence": 0.99,
"degrees": 0
},
"photo": {
"polygon": [
[0.032, 0.265],
[0.302, 0.265],
[0.302, 0.83],
[0.032, 0.83]
]
},
"restrictions": {
"confidence": 0.99,
"polygon": [
[0.486, 0.653],
[0.514, 0.653],
[0.514, 0.695],
[0.486, 0.695]
],
"value": "A"
},
"sex": {
"confidence": 0.99,
"polygon": [
[0.377, 0.714],
[0.402, 0.714],
[0.402, 0.754],
[0.377, 0.754]
],
"value": "F"
},
"signature": {
"polygon": [
[0.035, 0.827],
[0.321, 0.827],
[0.321, 0.926],
[0.035, 0.926]
]
},
"state": {
"confidence": 1,
"polygon": [
[0.296, 0.057],
[0.703, 0.047],
[0.704, 0.166],
[0.297, 0.176]
],
"value": "MO"
},
"weight": {
"confidence": 0.82,
"polygon": [
[0.55, 0.713],
[0.638, 0.713],
[0.638, 0.754],
[0.55, 0.754]
],
"value": "125"
}
}
}
],
"prediction": {
"address": {
"confidence": 0.98,
"page_id": 0,
"polygon": [
[0.318, 0.513],
[0.659, 0.513],
[0.659, 0.586],
[0.318, 0.586]
],
"value": "123 SAMPLE ST JEFFERSON CITY MO 65105"
},
"dl_class": {
"confidence": 0.99,
"page_id": 0,
"polygon": [
[0.402, 0.293],
[0.428, 0.293],
[0.428, 0.339],
[0.402, 0.339]
],
"value": "F"
},
"contour": {
"page_id": 0,
"polygon": [
[-0.03, -0.047],
[1.029, -0.047],
[1.029, 1.046],
[-0.03, 1.046]
]
},
"date_of_birth": {
"confidence": 0.75,
"page_id": 0,
"polygon": [
[0.705, 0.35],
[0.871, 0.35],
[0.871, 0.388],
[0.705, 0.388]
],
"value": "1979-02-14"
},
"dd_number": {
"confidence": 0.99,
"page_id": 0,
"polygon": [
[0.37, 0.896],
[0.569, 0.896],
[0.569, 0.938],
[0.37, 0.938]
],
"value": "101230320002"
},
"driver_license_id": {
"confidence": 0.99,
"page_id": 0,
"polygon": [
[0.399, 0.345],
[0.595, 0.345],
[0.595, 0.396],
[0.399, 0.396]
],
"value": "T123456789"
},
"endorsements": {
"confidence": 0.99,
"page_id": 0,
"polygon": [
[0.378, 0.606],
[0.414, 0.606],
[0.414, 0.652],
[0.378, 0.652]
],
"value": "M"
},
"expiry_date": {
"confidence": 0.95,
"page_id": 0,
"polygon": [
[0.705, 0.295],
[0.872, 0.295],
[0.872, 0.335],
[0.705, 0.335]
],
"value": "2026-02-14"
},
"eye_color": {
"confidence": 0.99,
"page_id": 0,
"polygon": [
[0.557, 0.757],
[0.629, 0.757],
[0.629, 0.799],
[0.557, 0.799]
],
"value": "BRO"
},
"first_name": {
"confidence": 0.99,
"page_id": 0,
"polygon": [
[0.317, 0.45],
[0.642, 0.45],
[0.642, 0.502],
[0.317, 0.502]
],
"value": "SAMANTHA DRIVER"
},
"hair_color": {
"confidence": 0,
"page_id": null,
"polygon": [],
"value": null
},
"height": {
"confidence": 0.99,
"page_id": 0,
"polygon": [
[0.378, 0.757],
[0.464, 0.757],
[0.464, 0.799],
[0.378, 0.799]
],
"value": "5-06"
},
"issued_date": {
"confidence": 0.98,
"page_id": 0,
"polygon": [
[0.722, 0.793],
[0.87, 0.793],
[0.87, 0.827],
[0.722, 0.827]
],
"value": "2020-01-05"
},
"last_name": {
"confidence": 0.99,
"page_id": 0,
"polygon": [
[0.318, 0.401],
[0.458, 0.401],
[0.458, 0.45],
[0.318, 0.45]
],
"value": "SAMPLE"
},
"photo": {
"page_id": 0,
"polygon": [
[0.032, 0.265],
[0.302, 0.265],
[0.302, 0.83],
[0.032, 0.83]
]
},
"restrictions": {
"confidence": 0.99,
"page_id": 0,
"polygon": [
[0.486, 0.653],
[0.514, 0.653],
[0.514, 0.695],
[0.486, 0.695]
],
"value": "A"
},
"sex": {
"confidence": 0.99,
"page_id": 0,
"polygon": [
[0.377, 0.714],
[0.402, 0.714],
[0.402, 0.754],
[0.377, 0.754]
],
"value": "F"
},
"signature": {
"page_id": 0,
"polygon": [
[0.035, 0.827],
[0.321, 0.827],
[0.321, 0.926],
[0.035, 0.926]
]
},
"state": {
"confidence": 1,
"page_id": 0,
"polygon": [
[0.296, 0.057],
[0.703, 0.047],
[0.704, 0.166],
[0.297, 0.176]
],
"value": "MO"
},
"weight": {
"confidence": 0.82,
"page_id": 0,
"polygon": [
[0.55, 0.713],
[0.638, 0.713],
[0.638, 0.754],
[0.55, 0.754]
],
"value": "125"
}
},
"processing_time": 1.755,
"product": {
"features": [
"state",
"driver_license_id",
"expiry_date",
"issued_date",
"last_name",
"first_name",
"address",
"date_of_birth",
"restrictions",
"endorsements",
"dl_class",
"sex",
"height",
"weight",
"hair_color",
"eye_color",
"dd_number",
"photo",
"signature"
],
"name": "Mindee/us_driver_license",
"type": "standard",
"version": "1.0"
},
"started_at": "2023-06-02T08:56:45.963610"
}
Extracted driver license data
Depending on the field type specified, additional attributes can be extracted from the driver license object. Using the above driver license example the following are the basic fields that can be extracted.
- State
- Driver License ID
- Expiry Date
- Date Of Issue
- Last Name
- First Name
- Address
- Date Of Birth
- Restrictions
- Endorsements
- Driver License Class
- Sex
- Height
- Weight
- Hair Color
- Eye Color
- Document Discriminator
- Photo
- Signature
State
- state: The state is classified, issued in a two-letter code (alpha code). All US states are supported, the following list shows which code belongs to which state:
AL Alabama
AK Alaska
AZ Arizona
AR Arkansas
CA California
CO Colorado
CT Connecticut
DE Delaware
DC District of Columbia
FL Florida
GA Georgia
HI Hawaii
ID Idaho
IL Illinois
IN Indiana
IA Iowa
KS Kansas
KY Kentucky
LA Louisiana
ME Maine
MD Maryland
MA Massachusetts
MI Michigan
MN Minnesota
MS Mississippi
MO Missouri
MT Montana
NE Nebraska
NV Nevada
NH New Hampshire
NJ New Jersey
NM New Mexico
NY New York
NC North Carolina
ND North Dakota
OH Ohio
OK Oklahoma
OR Oregon
PA Pennsylvania
RI Rhode Island
SC South Carolina
SD South Dakota
TN Tennessee
TX Texas
UT Utah
VT Vermont
VA Virginia
WA Washington
WV West Virginia
WI Wisconsin
WY Wyoming
{
"state": {
"confidence": 1,
"polygon": [
[0.296, 0.057],
[0.703, 0.047],
[0.704, 0.166],
[0.297, 0.176]
],
"value": "MO"
}
}
Driver License ID
- driver_license_id: Unique ID number of the document.
{
"driver_license_id": {
"confidence": 0.99,
"polygon": [
[0.399, 0.345],
[0.595, 0.345],
[0.595, 0.396],
[0.399, 0.396]
],
"value": "T123456789"
}
}
Expiry Date
- expiry_date: The ISO formatted expiry date of the document in the ISO 8601 format.
{
"expiry_date": {
"confidence": 0.95,
"polygon": [
[0.705, 0.295],
[0.872, 0.295],
[0.872, 0.335],
[0.705, 0.335]
],
"value": "2026-02-14"
}
}
Date Of Issue
- issued_date: The ISO formatted date of issue of the document in the ISO 8601 format.
{
"issued_date": {
"confidence": 0.98,
"polygon": [
[0.722, 0.793],
[0.87, 0.793],
[0.87, 0.827],
[0.722, 0.827]
],
"value": "2020-01-05"
}
}
Last Name
- last_name: The last name of the document holder. It does not matter whether it is in the same line as the first name or not. If there are several surnames, all surnames are output together.
{
"last_name": {
"confidence": 0.99,
"polygon": [
[0.318, 0.401],
[0.458, 0.401],
[0.458, 0.45],
[0.318, 0.45]
],
"value": "SAMPLE"
}
}
First Name
- first_name: The first name of the document holder. It does not matter whether it is in the same line as the last name or not. If there are several first names, all first names are output together.
{
"first_name": {
"confidence": 0.99,
"polygon": [
[0.317, 0.45],
[0.642, 0.45],
[0.642, 0.502],
[0.317, 0.502]
],
"value": "SAMANTHA DRIVER"
}
}
Address
- address: The address of the document holder is output as one value, regardless of its format. This contains everything that is noted on the document at this position. As with all fields, the output contains the coordinates of the bounding box and a confidence factor in addition to the actual value.
{
"address": {
"confidence": 0.98,
"polygon": [
[0.318, 0.513],
[0.659, 0.513],
[0.659, 0.586],
[0.318, 0.586]
],
"value": "123 SAMPLE ST JEFFERSON CITY MO 65105"
}
}
Date Of Birth
- date_of_birth: The ISO formatted date of birth of the document holder in the ISO 8601 format.
{
date_of_birth": {
"confidence": 0.75,
"polygon": [
[0.705, 0.35],
[0.871, 0.35],
[0.871, 0.388],
[0.705, 0.388]
],
"value": "1979-02-14"
}
}
Restrictions
- restrictions: These are all the restrictions that apply to the document holder. In any case, only one value is output. This contains everything that is noted on the document at this position.
{
"restrictions": {
"confidence": 0.99,
"polygon": [
[0.486, 0.653],
[0.514, 0.653],
[0.514, 0.695],
[0.486, 0.695]
],
"value": "A"
}
}
Endorsements
- endorsements: An endorsement is an extra driving privilege in addition to those automatically given to that class of driver. In any case, only one value is output. This contains everything that is noted on the document at this position.
{
"endorsements": {
"confidence": 0.99,
"polygon": [
[0.378, 0.606],
[0.414, 0.606],
[0.414, 0.652],
[0.378, 0.652]
],
"value": "M"
}
}
Driver License Class
- driver_license_class: The driving license class defines which types of vehicles the document holder is allowed to drive. This can be one or more letters. In any case, only one value is output. This contains everything that is noted on the document at this position.
{
"dl_class": {
"confidence": 0.99,
"polygon": [
[0.402, 0.293],
[0.428, 0.293],
[0.428, 0.339],
[0.402, 0.339]
],
"value": "F"
}
}
Sex
- sex: A letter indicating the sex of the document holder. Usually, this is "M" or "F". In some states, it may also be indicated as "X" at this point.
{
"sex": {
"confidence": 0.99,
"polygon": [
[0.377, 0.714],
[0.402, 0.714],
[0.402, 0.754],
[0.377, 0.754]
],
"value": "F"
}
}
Height
- height: Two-part number indicating the height of the document owner. Both numbers are separated by a dash and stand for foot in the first place and inches for the numbers after the dash.
{
"height": {
"confidence": 0.99,
"polygon": [
[0.378, 0.757],
[0.464, 0.757],
[0.464, 0.799],
[0.378, 0.799]
],
"value": "5-06"
}
}
Weight
- weight: Three-digit number indicating the weight of the document owner in pounds.
{
"weight": {
"confidence": 0.82,
"polygon": [
[0.55, 0.713],
[0.638, 0.713],
[0.638, 0.754],
[0.55, 0.754]
],
"value": "125"
}
}
Hair Color
- hair_color: Output in a code consisting of three letters representing the color of the document owner's hair.
{
"hair_color": {
"confidence": 0,
"polygon": [],
"value": null
}
}
Eye Color
- eye_color: Output in a code consisting of three letters representing the color of the document owner's eyes.
{
"eye_color": {
"confidence": 0.99,
"polygon": [
[0.557, 0.757],
[0.629, 0.757],
[0.629, 0.799],
[0.557, 0.799]
],
"value": "BRO"
}
}
Document Discriminator
- dd_number: It is an internal number that state agencies use to identify a particular document, such as your driver's license, from other documents that may have been issued in the past.
{
"dd_number": {
"confidence": 0.99,
"polygon": [
[0.37, 0.896],
[0.569, 0.896],
[0.569, 0.938],
[0.37, 0.938]
],
"value": "101230320002"
},
}
Photo
- photo: Graphic elements are generally not supported. The output value is therefore only the bounding box in which the recognized image is located. If there is no image on the document, no coordinates will be output.
{
"photo": {
"polygon": [
[0.032, 0.265],
[0.302, 0.265],
[0.302, 0.83],
[0.032, 0.83]
]
}
}
Signature
- signature: As before, graphic elements are generally not supported. The output value is therefore only the bounding box in which the recognized signature is located. If there is no signature on the document, no coordinates will be output.
{
"signature": {
"polygon": [
[0.035, 0.827],
[0.321, 0.827],
[0.321, 0.926],
[0.035, 0.926]
]
}
}
Questions?
Join our Slack
Updated about 2 months ago