EU Driver License OCR

Automatically extracts data from EU Driver Licenses

Mindee’s EU 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:

  • Country Code
  • Document ID
  • Driver License Category
  • Last Name
  • First Name
  • Date Of Birth
  • Place Of Birth
  • Expiry Date
  • Issue Date
  • Issue Authority
  • MRZ
  • Address
  • Photo
  • Signature

The EU Driver License OCR API supports the horizontal format for adult drivers in all EU countries. Driver's licenses outside the EU countries are not supported in this model.

Set up the API

📘

Before making any API calls, you need to have created your API key.

  1. You'll need a EU Driver License. You can use the sample document provided below.
  1. Access your Receipt API by clicking on the EU Driver License card in the Document Catalog
  1. 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/eu_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 = "eu_driver_license"

version = "1"


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 = "eu_driver_license";

const version = "1";


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'


api_key = "my-api-key-here"

account = "mindee"

endpoint = "eu_driver_license"

version = "1"


url = URI("https://api.mindee.net/v1/products/#{account}/#{endpoint}/v#{version}/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 #{api_key}"

request.set_form([['document', File.open(file)]], 'multipart/form-data')


response = http.request(request)

if !response.kind_of? Net::HTTPSuccess

  raise response.msg

end

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://infergate.staging-xsdj4gia.mindee.net/v1/products/mindee/eu_driver_license/v1/predict");

        xhr.setRequestHeader("Authorization", "Token my-api-key-here");

        xhr.send(data);

    }

</script>
using Mindee;

using Mindee.Input;

using Mindee.Http;

using Mindee.Parsing;


string apiKey = "my-api-key-here";

string filePath = "/path/to/the/file.ext";


// Construct a new client

MindeeClient mindeeClient = new MindeeClient(apiKey);


// Load an input source as a path string

// Other input types can be used, as mentioned in the docs

var inputSource = new LocalInputSource(filePath);


// Set the endpoint configuration

CustomEndpoint myEndpoint = new CustomEndpoint(

    endpointName: "eu_driver_license",

    accountName: "mindee",

    version: "1"

);


var response = await mindeeClient

    .ParseAsync(inputSource, myEndpoint);


// Print a summary of the predictions

System.Console.WriteLine(response.Document.ToString());


// Print the document-level predictions

// System.Console.WriteLine(response.Document.Inference.Prediction.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(

        "eu_driver_license",

        "mindee",

        "1"

    );


    // 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())

//    );

  }


}
<?php


// cURL install check

if (!function_exists('curl_init')) {

    exit("cURL isn't installed for " . phpversion());

}

$API_KEY = 'my-api-key-here';

$FILE_PATH = '/path/to/my/file.pdf';

$MIME_TYPE = 'application/pdf'; // change according to the file type

$ACCOUNT = 'mindee';

$VERSION = '1';

$ENDPOINT = 'eu_driver_license';


// Open a cURL session to send the document

$ch = curl_init();


// Setup headers

$headers = array(

  "Authorization: Token $API_KEY"

);


// Add our file to the request

$data = array(

  "document" => new CURLFile(

      $FILE_PATH,

      $MIME_TYPE,

      substr($FILE_PATH, strrpos($FILE_PATH, "/") + 1)

  )

);


// URL for a prediction

$url = "https://api.mindee.net/v1/products/$ACCOUNT/$ENDPOINT/v$VERSION/predict";


$options = array(

  CURLOPT_URL => $url,

  CURLOPT_HTTPHEADER => $headers,

  CURLOPT_POSTFIELDS => $data,

  CURLOPT_FOLLOWLOCATION => true,

  CURLOPT_RETURNTRANSFER => true

);


// Set all options for the cURL request

curl_setopt_array(

    $ch,

    $options

);


// Execute the request & extract the query content into a variable

$json = curl_exec($ch);


// Close the cURL session

curl_close($ch);


// Store the response as an array to allow for easier manipulations

$result = json_decode($json, true);


// Print the content of the document as raw json

echo json_encode($result, JSON_PRETTY_PRINT);
  • 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!

  1. 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/eu_driver_license/v1/predict"
  },
  "document": {
    "id": "854e67fd-238e-4b2d-8945-bdd2f8e90173",
    "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-12-13T09:49:57.576601",
    "is_rotation_applied": true,
    "pages": [
        {
            "extras": {},
            "id": 0,
            "orientation": {"value": 0},
            "prediction": {
                "address": {
                    "confidence": 0.42,
                    "polygon": [
                        [0.706, 0.412],
                        [0.728, 0.412],
                        [0.728, 0.421],
                        [0.706, 0.421]
                    ],
                    "value": "-"
                },
                "category": {
                    "confidence": 0.73,
                    "polygon": [
                        [0.069, 0.728],
                        [0.193, 0.728],
                        [0.193, 0.781],
                        [0.069, 0.781]
                    ],
                    "value": "AM B L"
                },
                "country_code": {
                    "confidence": 1,
                    "polygon": [
                        [0.033, 0.054],
                        [0.267, 0.054],
                        [0.267, 0.253],
                        [0.033, 0.253]
                    ],
                    "value": "DE"
                },
                "date_of_birth": {
                    "confidence": 0.99,
                    "polygon": [
                        [0.316, 0.29],
                        [0.503, 0.29],
                        [0.503, 0.341],
                        [0.316, 0.341]
                    ],
                    "value": "64-08-12"
                },
                "expiry_date": {
                    "confidence": 0.92,
                    "polygon": [
                        [0.316, 0.461],
                        [0.499, 0.461],
                        [0.499, 0.505],
                        [0.316, 0.505]
                    ],
                    "value": "30-01-21"
                },
                "first_name": {
                    "confidence": 0.99,
                    "polygon": [
                        [0.318, 0.238],
                        [0.432, 0.238],
                        [0.432, 0.28],
                        [0.318, 0.28]
                    ],
                    "value": "ERIKA"
                },
                "document_id": {
                    "confidence": 0.9,
                    "polygon": [
                        [0.314, 0.515],
                        [0.562, 0.515],
                        [0.562, 0.56],
                        [0.314, 0.56]
                    ],
                    "value": "B072RRE2I55"
                },
                "issue_date": {
                    "confidence": 0.93,
                    "polygon": [
                        [0.319, 0.35],
                        [0.503, 0.35],
                        [0.503, 0.391],
                        [0.319, 0.391]
                    ],
                    "value": "15-01-22"
                },
                "issue_authority": {
                    "confidence": 0.99,
                    "polygon": [
                        [0.313, 0.345],
                        [0.839, 0.345],
                        [0.839, 0.454],
                        [0.313, 0.454]
                    ],
                    "value": "Landratsamt Musterhausen See"
                },
                "last_name": {
                    "confidence": 0.95,
                    "polygon": [
                        [0.318, 0.128],
                        [0.548, 0.128],
                        [0.548, 0.169],
                        [0.318, 0.169]
                    ],
                    "value": "MUSTERMANN"
                },
                "mrz": {
                    "confidence": 0,
                    "polygon": [],
                    "value": null
                },
                "photo": {
                    "polygon": [
                        [0.028, 0.259],
                        [0.271, 0.259],
                        [0.271, 0.725],
                        [0.028, 0.725]
                    ]
                },
                "place_of_birth": {
                    "confidence": 0.99,
                    "polygon": [
                        [0.536, 0.29],
                        [0.683, 0.29],
                        [0.683, 0.343],
                        [0.536, 0.343]
                    ],
                    "value": "Berlin"
                },
                "signature": {
                    "polygon": [
                        [0.344, 0.562],
                        [0.672, 0.562],
                        [0.672, 0.725],
                        [0.344, 0.725]
                    ]
                }
            }
        }
    ],
    "prediction": {
        "address": {
            "confidence": 0.42,
            "page_id": 0,
            "polygon": [
                [0.706, 0.412],
                [0.728, 0.412],
                [0.728, 0.421],
                [0.706, 0.421]
            ],
            "value": "-"
        },
        "category": {
            "confidence": 0.73,
            "page_id": 0,
            "polygon": [
                [0.069, 0.728],
                [0.193, 0.728],
                [0.193, 0.781],
                [0.069, 0.781]
            ],
            "value": "AM B L"
        },
        "country_code": {
            "confidence": 1,
            "page_id": 0,
            "polygon": [
                [0.033, 0.054],
                [0.267, 0.054],
                [0.267, 0.253],
                [0.033, 0.253]
            ],
            "value": "DE"
        },
        "date_of_birth": {
            "confidence": 0.99,
            "page_id": 0,
            "polygon": [
                [0.316, 0.29],
                [0.503, 0.29],
                [0.503, 0.341],
                [0.316, 0.341]
            ],
            "value": "64-08-12"
        },
        "expiry_date": {
            "confidence": 0.92,
            "page_id": 0,
            "polygon": [
                [0.316, 0.461],
                [0.499, 0.461],
                [0.499, 0.505],
                [0.316, 0.505]
            ],
            "value": "30-01-21"
        },
        "first_name": {
            "confidence": 0.99,
            "page_id": 0,
            "polygon": [
                [0.318, 0.238],
                [0.432, 0.238],
                [0.432, 0.28],
                [0.318, 0.28]
            ],
            "value": "ERIKA"
        },
        "document_id": {
            "confidence": 0.9,
            "page_id": 0,
            "polygon": [
                [0.314, 0.515],
                [0.562, 0.515],
                [0.562, 0.56],
                [0.314, 0.56]
            ],
            "value": "B072RRE2I55"
        },
        "issue_date": {
            "confidence": 0.93,
            "page_id": 0,
            "polygon": [
                [0.319, 0.35],
                [0.503, 0.35],
                [0.503, 0.391],
                [0.319, 0.391]
            ],
            "value": "15-01-22"
        },
        "issue_authority": {
            "confidence": 0.99,
            "page_id": 0,
            "polygon": [
                [0.313, 0.345],
                [0.839, 0.345],
                [0.839, 0.454],
                [0.313, 0.454]
            ],
            "value": "Landratsamt Musterhausen See"
        },
        "last_name": {
            "confidence": 0.95,
            "page_id": 0,
            "polygon": [
                [0.318, 0.128],
                [0.548, 0.128],
                [0.548, 0.169],
                [0.318, 0.169]
            ],
            "value": "MUSTERMANN"
        },
        "mrz": {
            "confidence": 0,
            "page_id": null,
            "polygon": [],
            "value": null
        },
        "photo": {
            "page_id": 0,
            "polygon": [
                [0.028, 0.259],
                [0.271, 0.259],
                [0.271, 0.725],
                [0.028, 0.725]
            ]
        },
        "place_of_birth": {
            "confidence": 0.99,
            "page_id": 0,
            "polygon": [
                [0.536, 0.29],
                [0.683, 0.29],
                [0.683, 0.343],
                [0.536, 0.343]
            ],
            "value": "Berlin"
        },
        "signature": {
            "page_id": 0,
            "polygon": [
                [0.344, 0.562],
                [0.672, 0.562],
                [0.672, 0.725],
                [0.344, 0.725]
            ]
        }
    },
    "processing_time": 2.786,
    "product": {
        "features": [
            "country_code",
            "document_id",
            "category",
            "last_name",
            "first_name",
            "date_of_birth",
            "place_of_birth",
            "expiry_date",
            "issue_date",
            "issue_authority",
            "mrz",
            "address",
            "photo",
            "signature"
        ],
        "name": "mindee/eu_driver_license",
        "type": "standard",
        "version": "1.0"
    },
    "started_at": "2023-12-13T09:49:54.790517"
}

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.

Country Code

  • country_code: The country is classified, issued in a two-letter code (alpha code). All EU countries are supported, the following list shows which code belongs to which country:
    AT Austria
    BE Belgium
    BG Bulgaria
    CH Switzerland
    CY Cyprus
    CZ Czechia
    DE Germany
    DK Denmark
    EE Estonia
    ES Spain
    FI Finland
    FR France
    GR Greece
    HR Croatia
    HU Hungary
    IE Ireland
    IS Iceland
    IT Italy
    LI Liechtenstein
    LT Lithuania
    LU Luxembourg
    LV Latvia
    MT Malta
    NL Netherlands
    NO Norway
    PL Poland
    PT Portugal
    RO Romania
    SE Sweden
    SI Slovenia
    SK Slovakia
    UK United Kingdom
{
  "country_code": {
                    "confidence": 1,
                    "polygon": [
                        [0.033, 0.054],
                        [0.267, 0.054],
                        [0.267, 0.253],
                        [0.033, 0.253]
                    ],
                    "value": "DE"
                }
}

Document ID

  • document_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"
                }
}

Driver License Category

  • driver_license_category: The driving license category 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.
{
  "category": {
                    "confidence": 0.73,
                    "polygon": [
                        [0.069, 0.728],
                        [0.193, 0.728],
                        [0.193, 0.781],
                        [0.069, 0.781]
                    ],
                    "value": "AM B L"
                }
}

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.95,
                    "polygon": [
                        [0.318, 0.128],
                        [0.548, 0.128],
                        [0.548, 0.169],
                        [0.318, 0.169]
                    ],
                    "value": "MUSTERMANN"
                }
}

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.318, 0.238],
                        [0.432, 0.238],
                        [0.432, 0.28],
                        [0.318, 0.28]
                    ],
                    "value": "ERIKA"
                }
}

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.99,
                    "polygon": [
                        [0.316, 0.29],
                        [0.503, 0.29],
                        [0.503, 0.341],
                        [0.316, 0.341]
                    ],
                    "value": "64-08-12"
                }
}

Place Of Birth

  • place_of_birth: Place where the driver license holder was born, output in a string format.
{
  "place_of_birth": {
                    "confidence": 0.99,
                    "polygon": [
                        [0.536, 0.29],
                        [0.683, 0.29],
                        [0.683, 0.343],
                        [0.536, 0.343]
                    ],
                    "value": "Berlin"
                }
}

Expiry Date

  • expiry_date: The ISO formatted expiry date of the document in the ISO 8601 format.
{
  "expiry_date": {
                    "confidence": 0.92,
                    "polygon": [
                        [0.316, 0.461],
                        [0.499, 0.461],
                        [0.499, 0.505],
                        [0.316, 0.505]
                    ],
                    "value": "30-01-21"
                }
}

Issue Date

  • issue_date: The ISO formatted issue date of the document in the ISO 8601 format.
{
  "issue_date": {
                    "confidence": 0.93,
                    "polygon": [
                        [0.319, 0.35],
                        [0.503, 0.35],
                        [0.503, 0.391],
                        [0.319, 0.391]
                    ],
                    "value": "15-01-22"
                }
}

Issue Authority

  • issue_authority: The issuing office or issuing location responsible for issuing the document.
{
  "issue_authority": {
                    "confidence": 0.99,
                    "polygon": [
                        [0.313, 0.345],
                        [0.839, 0.345],
                        [0.839, 0.454],
                        [0.313, 0.454]
                    ],
                    "value": "Landratsamt Musterhausen See"
                }
}

MRZ

  • mrz: The machine-readable license number only appears on selected. It is issued in one string value.
{
  "mrz": {
                    "confidence": 0,
                    "polygon": [],
                    "value": null
                }
}

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.42,
                    "polygon": [
                        [0.706, 0.412],
                        [0.728, 0.412],
                        [0.728, 0.421],
                        [0.706, 0.421]
                    ],
                    "value": "-"
                }
}

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.028, 0.259],
                        [0.271, 0.259],
                        [0.271, 0.725],
                        [0.028, 0.725]
                    ]
                }
}

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.344, 0.562],
                        [0.672, 0.562],
                        [0.672, 0.725],
                        [0.344, 0.725]
                    ]
                }
}

Questions?
Slack Logo Icon  Join our Slack