Modern Passport Structure & Bulk Scan APIs

A Passport is a document that almost everyone has at some point in their lives. It is issued by the country’s government to its citizens and mainly being used for traveling purposes. It also serves as proof of nationality, name, and more importantly an Universally Unique ID for its owner.

Modern Passport Structure

Passport Specimen

Many services have been long-time accepting passports as identification documents from their customers to complete their KYC (Know Your Customer) form as required by the legislation in force. This is especially true and enforced for the Finance, HR or Travel sectors. In most cases, a human operator will verify the authenticity of the submitted document and grant validation or reject it.

Things can get really complicated if you have hundreds of KYC forms to checks, but also if your clients differ in nationality. Quickly, you will find yourself drowning in physical copies of passports in different languages that you can not even understand. Let alone the potential legal problems you can face with passport copies laying around the office. This is why, an automated & safe solution for Passports processing is required!

Modern Passport Structure

From the 1980s on wards, most countries started issuing passports containing an MRZ. MRZ stands for the Machine Readable Zone and is usually located at the bottom of the Passport as shown below:

Modern Passport Specimen

Passports MRZ Sample

Passports that contain an MRZ are referred to as MRPs, machine-readable passports (Almost all modern issued Passports have one). The structure of the MRZ is standardized by the ICAO Document 9303 and the International Electro-technical Commission as ISO/IEC 7501-1.

The MRZ is an area on the document that can easily be read by a machine using an OCR Reader Application or API. It’s not important for you to understand how it works, but if you look at it carefully, you will see that it contains most of the relevant information on the document, combined with additional characters and a checksum that can be extracted programmatically and automatically via API as we will see in the next section.

Once parsed, the following information are automatically extracted from the target MRZ and made immediately available to your app, thanks to the /docscan API endpoint:

  • issuingCountry: The issuing country or organization, encoded in three characters.
  • fullName: Passport holder full name. The name is entirely upper case.
  • documentNumber: This is the passport number, as assigned by the issuing country. Each country is free to assign numbers using any system it likes.
  • checkDigit: Check digits are calculated based on the previous field. Thus, the first check digit is based on the passport number, the next is based on the date of birth, the next on the expiration date, and the next on the personal number. The check digit is calculated using this algorithm.
  • nationality: The issuing country or organization, encoded in three characters.
  • dateOfBirth: The date of the passport holder's birth in YYMMDD form. Year is truncated to the least significant two digits. Single digit months or days are perpended with 0.
  • sex: Sex of the passport holder, M for males, F for females, and < for non-specified.
  • dateOfExpiry: The date the passport expires in YYMMDD form. Year is truncated to the least significant two digits. Single digit months or days are perpended with 0.
  • personalNumber: This field is optional and can be used for any purpose that the issuing country desires.
  • finalcheckDigit: This is a check digit for positions 1 to 10, 14 to 20, and 22 to 43 on the second line of the MRZ. Thus, the nationality and sex are not included in the check. The check digit is calculated using this algorithm.

Automatic Passport Processing

PixLab Logo

Fortunately for the developer wishing to automate Passports scanning, PixLab can automatically scan & extract passport MRZ but also help to detect possible fraudulent documents. This is made possible thanks to the /docscan API endpoint which let you in a single call scan government issued documents such as Passports, Visas or ID Cards from various countries.

Besides extracting MRZ, the /docscan API endpoint shall automatically crop any detected face and transform binary Machine Readable Zone into stream of text content (i.e. full name, issuing country, document number, date of expiry, etc.) ready to be consumed by your app in the JSON format.

Below, a typical output result of the /docscan endpoint for a passport input image:

Input Passport Specimen (JPEG/PNG/BMP Image)

Input Image URL

Extracted MRZ Fields

MRZ Fields

What follow is the gist used to achieve such result:

Other document scanning code samples are available to consult via the following Github links:

Face extraction is automatically performed using the /facedetect API endpoint. For a general purpose Optical Character Recognition engine, you should rely on the /OCR API endpoint instead. If you are dealing with PDF documents, you can convert them at first to raw images via the /pdftoimg endpoint.


The era we are in is more digitized than ever. Tasks that are repetitive are slowly being replaced by computers and robots. In many cases, they can perform these tasks faster, with a smaller amount of mistakes and in a more cost-effective manner. At PixLab we focus on building software to replace manual repetitive labor in administrative business processes. The processing and checking of passports can be very time-consuming. Using /docscan to automate your passport processing will enable you to save cost, on-board customers faster and reduce errors in administrative processes.

Generate MEMEs Programmtically

MEMEs are de facto internet standard nowadays. At least, dozen if not hundred of daily top posts on Imgur or Reddit are probably MEMEs. That is, a pop culture image with sarcastic text (always) displayed on Top, Bottom or Center of that image. A lot of web tools out there let you create memes graphically but a few ones actually propose an API for generating memes from your favorite programming language.

In this blog post, we'll try to generate a few MEMEs programmatically using Python, PHP or whatever language that support HTTP requests with the help of the PixLab API but before that, lets dive a little bit into the tools needed to build a MEME generator.

Crafting a MEME API

Building a RESTful API capable of generating memes at request is not that difficult. The most important part is to find a good image processing library that support the annotate operation (i.e. Text drawing). The most capable & open source libraries are the ImageMagick suite and its popular fork GraphicsMagick. Both provides advanced annotate & draw capability such as selecting the target font, its size, text position, the stroke width & height and beyond. Both should be a good fit and up to the task. Here is some good tutorials to follow if you wanna build your own RESTful API:

In our case, we'll stick with the PixLab API due to the fact that is shipped with robust API endpoints such as Image compositing, facial landmarks extraction, dynamic image creation that proves of great help when working with complex stuff such as cloning Snapchat filters or playing with GIFs. So, without further ado, let's start programming some memes..

First MEME

Given an input image of the famous Michael Jordan crying face:

JDR face

Draw some funny text on top & bottom of that image to obtain something like this:

JDR Draw

Using the following code:

import requests
import json
# Draw some funny text on top & button of the famous Michael Jordan crying face.
# is the target command
req = requests.get('',params={
    'img': '',
    'top': 'someone bumps the table',
    'bottom':'right before you win',
    'cap':True, # Capitalize text,
    'strokecolor': 'black',
reply = req.json()
if reply['status'] != 200:
    print (reply['error'])
    print ("Meme: "+ reply['link']) snippet available on the PixLab Github Repository.

If this is the first time you've seen the PixLab API in action, your are invited to take a look at the excellent introduction to the API in 5 minutes or less. Only one command (API endpoint) is actually needed in order to generate such a meme:

drawtext is the command used for text annotation. It expect the text to be displayed on Top, Center or Bottom of the target image and support a bunch of other options such as selecting the text font, its size & colors, whether to capitalize the text or not, stroke width & opacity and so on. You can find out all the options the drawtext command takes here.

There is a more flexible command named drawtextat that let you draw text on any desired region of the input image by specifying the target coordinates (X,Y) of where the text should be displayed. Here is an usage example.

Dynamic MEME

This example is similar to the previous one except that the image we'll draw something on top is generated dynamically. That is, we will request from the PixLab API server to create a new image for us with a specified height, width, background color and output format and finally we'll draw our text at the center of the generated image to obtain something like this:

dynamic image

Using this code:

import requests
import json

# Dynamically create a 300x300 PNG image with a yellow background and draw some text on the center of it later.
# Refer to && for additional information.

req = requests.get('',params={
reply = req.json()
if reply['status'] != 200:
    print (reply['error'])
# Link to the new image
img = reply['link'];

# Draw some text now on the new image
req = requests.get('',params={
    'img':img, #The newly created image
    "cap":True, #Uppercase
    "color":"black", #Text color
reply = req.json()
if reply['status'] != 200:
    print (reply['error'])
    print ("Pic location: "+ reply['link']) snippet available on the PixLab Github Repository.

Here, we request a new image using the newimage API endpoint which export to PNG by default but you can change the output format at request. We set the image height, width and the background color respectively to 300x300 with a yellow background color.

Note that if one of the height or width parameter is missing (but not both), then the available length is applied to the missing side and if you want a transparent image, set the color parameter to none.

We finally draw our text at the center of the newly created image using the wolf font, black color and 35 px font size. Of course, one could draw lines, a rectangle for example to surround faces, merge with other images and so forth...

Image Composite

Let's generate the following by compositing two smiley on top of Jordan's face:

jdr smiley

Using this code:

import requests
import json

# Composite two smiley on top of the famous Michael jordan crying face.
# A more sophisticated approach would be to extract the face landmarks using facelandmarks and composite something on the different regions.
# for more info.

req ='',
           'img': '',
           'x': 30,
           'y': 320
           'img': '',
           'x': 630,
           'y': 95
reply = req.json()
if reply['status'] != 200:
    print (reply['error'])
    print ("Pic Link: "+ reply['link']) snippet available on the PixLab Github Repository.

This operation is named compositing and is done via a single PixLab command named merge. this command expects a list of coordinates (X, Y) and a list of images to be composited (i.e. The two smiley in our case) on top of the target region. The coordinates here were set randomly and passed verbatim to merge but a more sophisticated approach would gather the facial coordinates and composite something on top of them such as a flower crown to mimic the Snapchat filters for example. Refer to the PixLab documentation for additional information on the merge command.

Mimic Snapchat Filters

This last example, although relatively unrelated to our subject here is about to show how to mimic the famous Snapchat filters programmatically. So, given an input image: plain woman face and this eye mask: eye_mask

located at.

plus this mustache: mustache located at.

output something like this: snapchat filter Well, in order to achieve that effect except for the MEME we draw on the bottom of that image, lots of computer vision algorithms are involved here such as face detection, facial landmarks extraction, pose estimation and so on. You are invited to take a look at our previous blog post on how such filter is produced, what techniques are involved and so on: Mimic Snapchat Filters Programmatically.


Generating MEMEs is quite easy providing a good image manipulation library. We saw that ImageMagick and GraphicsMagick with their PHP/Node.js binding can be used to create your own MEME Restful API. Our simple yet elegant solution is to rely on the PixLab API. Not only generating MEMEs is straightforward but also, you'll be able to perform advanced analysis & processing operations on your input media such as face analysis, nsfw content detection and so forth. Your are invited to take a look at the Github sample page for dozen of the others interesting samples in action such as censoring images based on their nsfw score, blurring human faces, making gifs, etc. All of them are documented on the PixLab API endpoints reference doc and the 5 minutes intro the the API. Finally, if you have any suggestion or critics, please leave a comment below.