Passport OCR

Automatically extracts data from passports

Many on-boarding processes in mobile or web apps require to extract some data from ID documents. Using Mindee's Passport API, you can automatically extract data from passports to offer to your users the best on-boarding experience.

The API extracts:

country: Passport's country of issuance
id_number: Passport's number
given_names: Holder's given names
surname: Holder's surname
birth_date: Holder's date of birth
birth_place: Holder's birth place
gender: Holder's gender
issuance_date: ISO formatted passport's date of issuance
expiry_date: ISO formatted passport's expiry date
mrz1: Passport's machine readable zone line 1
mrz2: Passport's machine readable zone line 2

API Prerequisites

  1. You’ll need a free Mindee account. Sign up and confirm your email to log in.
  2. A picture of a passport. You can use yours safely as data protection is one of our priority and we won't send your images to any third party application. You can also download the following fake one:

Set up the API

Log into your Mindee account and access your International Passport API environment by clicking the Passport API card:

When clicking this card, you land on the dashboard page - where you can quickly see API usage (you have none right now, but that will change).

On the left navigation, there are links to “Documentation”, “API Keys” and “Live Interface”. The docs tab has all of the technical details you’ll need to build for the invoice API.

Click on the Create a new API key button and name your API key:

Now, we are ready to make an API call. You can find sample codes for the most popular languages in the "Documentation" tab:

curl -X POST \
  https://api.mindee.net/v1/products/mindee/passport/v1/predict \
  -H 'Authorization: Token my-api-key-here' \
  -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \
  -F [email protected]/path/to/your/file.png
import requests

url = "https://api.mindee.net/v1/products/mindee/passport/v1/predict"

with open("/path/to/my/file", "rb") as myfile:
    files = {"document": myfile}
    headers = {"Authorization": "Token my-api-key-here"}
    response = requests.post(url, files=files, headers=headers)
    print(response.text)
// works for NODE > v10
const axios = require('axios');
const fs = require("fs");
const FormData = require('form-data')

async function makeRequest() {
    let data = new FormData()
    data.append('document', fs.createReadStream('./file.jpg'))
    const config = {
        method: 'POST',
        url: 'https://api.mindee.net/v1/products/mindee/passport/v1/predict',
        headers: { 
          'Authorization':'Token my-api-key-here',
          ...data.getHeaders()
           },
        data
    }

    try {
      let response = await axios(config)
      console.log(response.data);
    } catch (error) {
      console.log(error)
    }

}

makeRequest()
<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/passport/v1/predict");
  xhr.setRequestHeader("Authorization", "Token my-api-key-here");
  xhr.send(data);
}
</script>
# tested with Ruby 2.5
require 'uri'
require 'net/http'
require 'net/https'
require 'mime/types'

url = URI("https://api.mindee.net/v1/products/mindee/passport/v1/predict")
file = "/path/to/your/file.png"

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

Replace {my-api-key-here} with your new API key, and /path/to/your/file/png with the path to your passport image or pdf.

Paste the cURL sample into your terminal, hit enter, and about a second later, you will receive a JSON response with the passport details. Since the response is quite verbose, we will walk through the fields section by section.

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/passport/v1/predict"
  },
  "document": {
    "annotations": {
      "labels": []
    },
    "id": "c2651887-85f0-4890-88a1-55d1acbe1263",
    "inference": {
      "finished_at": "2021-06-01T10:27:52+00:00",
      "pages": [
        {
          "id": 0,
          "prediction": {
            "birth_date": {
              "confidence": 0.99,
              "polygon": [
                [
                  0.5172,
                  0.081
                ],
                [
                  0.9155,
                  0.7614
                ],
                [
                  0.5103,
                  0.3545
                ],
                [
                  0.0073,
                  0.6564
                ]
              ],
              "value": "2001-08-25"
            },
            "birth_place": {
              "confidence": 0.99,
              "polygon": [
                [
                  0.7475,
                  0.7026
                ],
                [
                  0.0837,
                  0.6433
                ],
                [
                  0.772,
                  0.8915
                ],
                [
                  0.2545,
                  0.1172
                ]
              ],
              "value": "string"
            },
            "country": {
              "confidence": 0.99,
              "polygon": [
                [
                  0.3263,
                  0.6623
                ],
                [
                  0.4642,
                  0.4185
                ],
                [
                  0.3179,
                  0.8991
                ],
                [
                  0.4653,
                  0.9794
                ]
              ],
              "value": "string"
            },
            "expiry_date": {
              "confidence": 0.99,
              "polygon": [
                [
                  0.0719,
                  0.7544
                ],
                [
                  0.0987,
                  0.3772
                ],
                [
                  0.8204,
                  0.3824
                ],
                [
                  0.6437,
                  0.7535
                ]
              ],
              "value": "2023-04-12"
            },
            "gender": {
              "confidence": 0.99,
              "polygon": [
                [
                  0.4187,
                  0.6225
                ],
                [
                  0.7608,
                  0.3195
                ],
                [
                  0.2222,
                  0.8163
                ],
                [
                  0.5484,
                  0.586
                ]
              ],
              "value": "string"
            },
            "given_names": [
              {
                "confidence": 0.99,
                "polygon": [
                  [
                    0.892,
                    0.1198
                  ],
                  [
                    0.8429,
                    0.3504
                  ],
                  [
                    0.4408,
                    0.4322
                  ],
                  [
                    0.2926,
                    0.2348
                  ]
                ],
                "value": "string"
              }
            ],
            "id_number": {
              "confidence": 0.99,
              "polygon": [
                [
                  0.8481,
                  0.0496
                ],
                [
                  0.5729,
                  0.4031
                ],
                [
                  0.4119,
                  0.0891
                ],
                [
                  0.0492,
                  0.3859
                ]
              ],
              "value": "string"
            },
            "issuance_date": {
              "confidence": 0.99,
              "polygon": [
                [
                  0.708,
                  0.5445
                ],
                [
                  0.8973,
                  0.375
                ],
                [
                  0.9134,
                  0.8104
                ],
                [
                  0.827,
                  0.3991
                ]
              ],
              "value": "2019-08-03"
            },
            "mrz1": {
              "confidence": 0.99,
              "polygon": [
                [
                  0.5703,
                  0.3335
                ],
                [
                  0.4427,
                  0.1992
                ],
                [
                  0.0419,
                  0.3303
                ],
                [
                  0.0059,
                  0.65
                ]
              ],
              "value": "string"
            },
            "mrz2": {
              "confidence": 0.99,
              "polygon": [
                [
                  0.3573,
                  0.7532
                ],
                [
                  0.9437,
                  0.9827
                ],
                [
                  0.5973,
                  0.1705
                ],
                [
                  0.538,
                  0.8355
                ]
              ],
              "value": "string"
            },
            "orientation": {
              "confidence": 0.99,
              "degrees": 270
            },
            "surname": {
              "confidence": 0.99,
              "polygon": [
                [
                  0.5189,
                  0.9896
                ],
                [
                  0.3264,
                  0.3849
                ],
                [
                  0.9078,
                  0.1242
                ],
                [
                  0.8757,
                  0.085
                ]
              ],
              "value": "string"
            }
          }
        }
      ],
      "prediction": {
        "birth_date": {
          "confidence": 0.99,
          "page_id": 0,
          "polygon": [
            [
              0.246,
              0.2646
            ],
            [
              0.9535,
              0.65
            ],
            [
              0.1072,
              0.5242
            ],
            [
              0.201,
              0.7183
            ]
          ],
          "value": "2001-08-25"
        },
        "birth_place": {
          "confidence": 0.99,
          "page_id": 0,
          "polygon": [
            [
              0.263,
              0.6665
            ],
            [
              0.1728,
              0.9879
            ],
            [
              0.7359,
              0.16
            ],
            [
              0.6487,
              0.9166
            ]
          ],
          "value": "string"
        },
        "country": {
          "confidence": 0.99,
          "page_id": 0,
          "polygon": [
            [
              0.5038,
              0.3721
            ],
            [
              0.8746,
              0.9776
            ],
            [
              0.3966,
              0.9076
            ],
            [
              0.2861,
              0.1554
            ]
          ],
          "value": "string"
        },
        "expiry_date": {
          "confidence": 0.99,
          "page_id": 0,
          "polygon": [
            [
              0.3412,
              0.7005
            ],
            [
              0.4965,
              0.6171
            ],
            [
              0.1555,
              0.7132
            ],
            [
              0.7421,
              0.6633
            ]
          ],
          "value": "2023-04-12"
        },
        "gender": {
          "confidence": 0.99,
          "page_id": 0,
          "polygon": [
            [
              0.5592,
              0.5758
            ],
            [
              0.2672,
              0.0716
            ],
            [
              0.9684,
              0.6278
            ],
            [
              0.2855,
              0.1543
            ]
          ],
          "value": "string"
        },
        "given_names": [
          {
            "confidence": 0.99,
            "page_id": 0,
            "polygon": [
              [
                0.5765,
                0.6945
              ],
              [
                0.1599,
                0.7222
              ],
              [
                0.3402,
                0.1705
              ],
              [
                0.755,
                0.371
              ]
            ],
            "value": "string"
          }
        ],
        "id_number": {
          "confidence": 0.99,
          "page_id": 0,
          "polygon": [
            [
              0.4431,
              0.1359
            ],
            [
              0.339,
              0.6333
            ],
            [
              0.9366,
              0.5534
            ],
            [
              0.3192,
              0.9519
            ]
          ],
          "value": "string"
        },
        "issuance_date": {
          "confidence": 0.99,
          "page_id": 0,
          "polygon": [
            [
              0.6635,
              0.6699
            ],
            [
              0.0262,
              0.938
            ],
            [
              0.6887,
              0.7021
            ],
            [
              0.2226,
              0.7361
            ]
          ],
          "value": "2019-08-03"
        },
        "mrz1": {
          "confidence": 0.99,
          "page_id": 0,
          "polygon": [
            [
              0.2724,
              0.1524
            ],
            [
              0.6602,
              0.949
            ],
            [
              0.6035,
              0.8488
            ],
            [
              0.8763,
              0.5025
            ]
          ],
          "value": "string"
        },
        "mrz2": {
          "confidence": 0.99,
          "page_id": 0,
          "polygon": [
            [
              0.7596,
              0.8019
            ],
            [
              0.4068,
              0.5756
            ],
            [
              0.0751,
              0.086
            ],
            [
              0.5724,
              0.5922
            ]
          ],
          "value": "string"
        },
        "surname": {
          "confidence": 0.99,
          "page_id": 0,
          "polygon": [
            [
              0.0798,
              0.3528
            ],
            [
              0.4076,
              0.5601
            ],
            [
              0.9134,
              0.0295
            ],
            [
              0.9604,
              0.5395
            ]
          ],
          "value": "string"
        }
      },
      "processing_time": 0.52,
      "product": {
        "features": [
          "country",
          "id_number",
          "given_names",
          "surname",
          "birth_date",
          "birth_place",
          "gender",
          "issuance_date",
          "expiry_date",
          "orientation",
          "mrz1",
          "mrz2"
        ],
        "name": "mindee/International Passports",
        "version": "1.0"
      },
      "started_at": "2021-06-01T10:27:52+00:00"
    },
    "n_pages": 1,
    "name": "myfile.jpg",
    "ocr": {}
  }
}

To access the page-level prediction: document > inference > pages[] > prediction is an array, containing the extracted data from each page. For images, there is only one element on this array, but for pdfs, you can find the extracted data for each pdf page.

Each predicted field contains a confidence_score as well as a polygon when the information is located in the image.

country

Passport's country ISO 3166-1 alpha-3 code (3 letters format)

{
  "country": {
    "confidence": 1,
    "polygon": [
      [
        0.508,
        0.547
      ],
      [
        0.559,
        0.547
      ],
      [
        0.559,
        0.568
      ],
      [
        0.508,
        0.568
      ]
    ],
    "value": "GBR"
  }
}

id_number

Passport's number

{
  "id_number": {
    "confidence": 1,
    "polygon": [
      [
        0.723,
        0.547
      ],
      [
        0.899,
        0.547
      ],
      [
        0.899,
        0.569
      ],
      [
        0.723,
        0.569
      ]
    ],
    "value": "707797979"
  }
}

given_names

List of holder's given names

{
  "given_names": [
    {
      "confidence": 0.99,
      "polygon": [
        [
          0.341,
          0.617
        ],
        [
          0.435,
          0.617
        ],
        [
          0.435,
          0.638
        ],
        [
          0.341,
          0.638
        ]
      ],
      "value": "HENERT"
    }
  ]
}

surname

Holder's surname

{
  "surname": {
    "confidence": 0.99,
    "polygon": [
      [
        0.34,
        0.581
      ],
      [
        0.473,
        0.581
      ],
      [
        0.473,
        0.604
      ],
      [
        0.34,
        0.604
      ]
    ],
    "value": "PUDARSAN"
  }
}

birth_date

ISO formatted holder's date of birth

{
  "birth_date": {
    "confidence": 1,
    "polygon": [
      [
        0.341,
        0.689
      ],
      [
        0.571,
        0.689
      ],
      [
        0.571,
        0.714
      ],
      [
        0.341,
        0.714
      ]
    ],
    "value": "1995-05-20"
  }
}

birth_place

Holder's birth place

{
  "birth_place": {
    "confidence": 0.9,
    "polygon": [
      [
        0.441,
        0.724
      ],
      [
        0.556,
        0.724
      ],
      [
        0.556,
        0.744
      ],
      [
        0.441,
        0.744
      ]
    ],
    "value": "CAMTETH"
  }
}

gender

Holder's sex

{
  "gender": {
    "confidence": 1,
    "polygon": [
      [
        0.054,
        0.919
      ],
      [
        0.928,
        0.919
      ],
      [
        0.928,
        0.945
      ],
      [
        0.054,
        0.945
      ]
    ],
    "value": "M"
  }
}

issuance_date

ISO formatted passport's date of issuance

{
  "issuance_date": {
    "confidence": 1,
    "polygon": [
      [
        0.34,
        0.763
      ],
      [
        0.565,
        0.763
      ],
      [
        0.565,
        0.788
      ],
      [
        0.34,
        0.788
      ]
    ],
    "value": "2012-04-23"
  }
}

expiry_date

ISO formatted passport's expiry date

{
  "expiry_date": {
    "confidence": 1,
    "polygon": [
      [
        0.34,
        0.796
      ],
      [
        0.576,
        0.796
      ],
      [
        0.576,
        0.82
      ],
      [
        0.34,
        0.82
      ]
    ],
    "value": "2017-04-22"
  }
}

mrz1

Passport's machine readable zone line 1

{
  "mrz1": {
    "confidence": 0.99,
    "polygon": [
      [
        0.055,
        0.882
      ],
      [
        0.926,
        0.882
      ],
      [
        0.926,
        0.911
      ],
      [
        0.055,
        0.911
      ]
    ],
    "value": "P<GBRPUDARSAN<<HENERT<<<<<<<<<<<<<<<<<<<<<<<"
  }
}

mrz2

Passport's machine readable zone line 2

{
  "mrz2": {
    "confidence": 1,
    "polygon": [
      [
        0.054,
        0.919
      ],
      [
        0.928,
        0.919
      ],
      [
        0.928,
        0.945
      ],
      [
        0.054,
        0.945
      ]
    ],
    "value": "7077979792GBR9505209M1704224<<<<<<<<<<<<<<00"
  }
}

Updated about a month ago


Passport OCR


Automatically extracts data from passports

Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.