๐ Passport OCR
๐ เธเธฒเธชเธเธญเธฃเนเธ
Welcome to iApp Passport OCR API, an AI product developed by iApp Technology Co., Ltd. Our API is designed to automatically recognize and extract information from scanned passport images with high accuracy and speed. The system specifically focuses on reading the Machine Readable Zone (MRZ) at the bottom of passport pages, extracting crucial information like the holder's name, nationality, date of birth, and more.
Visit our API Portal to test the Passport OCR API with your own images.
Getting Startedโ
-
Prerequisites
- An API key from iApp Technology
- Scanned passport images (profile page)
- Supported file formats: JPEG, JPG, PNG, PDF
- Maximum file size: 10MB
-
Quick Start
- Fast processing (1-2 seconds per image)
- High accuracy text extraction (95.51%)
- Support for multiple file formats
-
Key Features
- Extracts information from TD3 type MRZ
- OCR accuracy scoring and validation
- Face image extraction in base64 format
- Support for multiple page PDF documents
- Handles rotated and skewed images
- Image segmentation pre-processing for skewed images
- Supports Thai and English language
-
Security & Compliance
- GDPR and PDPA compliant
- No data retention after processing
Please visit API Portal to view your existing API key or request a new one.
Exampleโ
Profile Pageโ
Request:โ
curl -X POST https://api.iapp.co.th/passport-ocr/v2/ocr \
-H "apikey: YOUR_API_KEY" \
-F "file=@/path/to/passport.jpg"
Response:โ
{
"check_composite": "4",
"check_date_of_birth": "4",
"check_expiration_date": "4",
"check_number": "6",
"check_personal_number": "3",
"country": "THA",
"date_of_birth": "930710",
"expiration_date": "250304",
"method": "direct",
"mrz_type": "TD3",
"names": "MATHANIDA",
"nationality": "THA",
"number": "AC1062346",
"personal_number": "0012345678913",
"raw_text": "P<THAPOSHNASWADIWONG<<MATHANIDA<<<<<<<<<<<<<\nAC10623466THA9307104F25030440012345678913<34",
"sex": "F",
"surname": "POSHNASWADIWONG",
"type": "P",
"valid_composite": true,
"valid_date_of_birth": true,
"valid_expiration_date": true,
"valid_number": true,
"valid_personal_number": true,
"valid_score": 100,
"face": "/9j/4AAQSkZJRgABAQAAAQABAAD/..."
}
Response Fields Explanationโ
Field | Description | Format | Example |
---|---|---|---|
check_composite | Overall check digit for upper and middle machine readable lines | Single digit | "4" |
check_date_of_birth | Check digit for date of birth field | Single digit | "4" |
check_expiration_date | Check digit for expiration date field | Single digit | "4" |
check_number | Check digit for document number | Single digit | "6" |
check_personal_number | Check digit for personal number | Single digit | "3" |
country | Country code of passport issuance | 3 letters | "THA" |
date_of_birth | Date of birth | YYMMDD | "930710" |
expiration_date | Document expiry date | YYMMDD | "250304" |
method | Reading method used | String | "direct" |
mrz_type | Type of machine readable zone | String | "TD3" |
names | First/given name(s) | String | "MATHANIDA" |
nationality | Nationality of holder | 3 letters | "THA" |
number | Passport number | String | "AC1062346" |
personal_number | National ID number | String | "0012345678913" |
raw_text | Raw MRZ text from passport | String | "P<THAPOSHNASWADIWONG..." |
sex | Gender | Single letter | "F" |
surname | Last/family name | String | "POSHNASWADIWONG" |
type | Document type | String | "P" |
valid_composite | Overall MRZ validity check | Boolean | true |
valid_date_of_birth | Date of birth check digit validity | Boolean | true |
valid_expiration_date | Expiry date check digit validity | Boolean | true |
valid_number | Document number check digit validity | Boolean | true |
valid_personal_number | Personal number check digit validity | Boolean | true |
valid_score | Overall validity score | Integer 0-100 | 100 |
face | Extracted face image | Base64 string | "/9j/4AAQSkZJRgABA..." |
PDF File Processingโ
When processing PDF files, the response format differs slightly:
- The response will be a JSON array containing results for each page
- Each page result includes:
- page: Page number
- info: Contains all the standard fields as shown above
- A process_time field shows total processing duration
Example PDF response structure:
[
{
"page": 1,
"info": {
"sex": "F",
"number": "AC1062346",
"expiration_date": "04/03/25",
"raw_text": "P<THAPOSHNASWADIWONG<<MATHANIDA<<<<<<<<<<<<<\nAC10623466THA9307104F25030440012345678913<34",
"personal_number": "0012345678913",
"surname": "POSHNASWADIWONG",
"nationality": "THA",
"date_of_birth": "10/07/93",
"names": "MATHANIDA",
"country": "THA",
"face": "iVBORw0...CYII=",
"inference": "3.888",
"file_name": "1676365480.3823211_thai_passport_page_1.png",
"message": "Success",
"status_code": 200
}
},
{
"process_time": "4.918s"
}
]
Features & Capabilitiesโ
Core Featuresโ
- MRZ (Machine Readable Zone) text extraction
- Face image extraction
- Multiple page PDF support
- Automatic image orientation correction
- Image segmentation for skewed images
- High accuracy validation checks
Supported Fieldsโ
- Document type
- Issuing country
- Document number
- Holder's name
- Nationality
- Date of birth
- Gender
- Expiration date
- Personal number
- Face image (base64)
- Raw MRZ text
- Validation scores
API Referenceโ
Recognizing Passportโ
POST https://api.iapp.co.th/passport-ocr/v2
Performs OCR on passport profile page and extracts MRZ data
Parameters:
- file (required): Image file (JPG, PNG, PDF)
- apikey (required): Your API key
- options: Enable "segmentation" for skewed image processing
Code Examplesโ
Pythonโ
import requests
url = "https://api.iapp.co.th/passport-ocr/v2/ocr"
headers = {
"apikey": "YOUR_API_KEY"
}
files = {
"file": open("passport.jpg", "rb")
}
response = requests.post(url, headers=headers, files=files)
print(response.json())
JavaScriptโ
const axios = require("axios")
const FormData = require("form-data")
const fs = require("fs")
let data = new FormData()
data.append("file", fs.createReadStream("passport.jpg"))
let config = {
method: "post",
url: "https://api.iapp.co.th/passport-ocr/v2/ocr",
headers: {
apikey: "YOUR_API_KEY",
...data.getHeaders(),
},
data: data,
}
axios(config)
.then((response) => console.log(response.data))
.catch((error) => console.log(error))
PHPโ
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.iapp.co.th/passport-ocr/v2/ocr',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => array(
'apikey: YOUR_API_KEY'
),
CURLOPT_POSTFIELDS => array(
'file'=> new CURLFILE('passport.jpg')
)
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
Swiftโ
import Foundation
let url = URL(string: "https://api.iapp.co.th/passport-ocr/v2/ocr")!
let boundary = "Boundary-\(UUID().uuidString)"
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("YOUR_API_KEY", forHTTPHeaderField: "apikey")
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let imageData = try! Data(contentsOf: URL(fileURLWithPath: "passport.jpg"))
var body = Data()
body.append("--\(boundary)\r\n")
body.append("Content-Disposition: form-data; name=\"file\"; filename=\"passport.jpg\"\r\n")
body.append("Content-Type: image/jpeg\r\n\r\n")
body.append(imageData)
body.append("\r\n--\(boundary)--\r\n")
let task = URLSession.shared.uploadTask(with: request, from: body) { data, response, error in
if let data = data {
let json = try? JSONSerialization.jsonObject(with: data)
print(json ?? "")
}
}
task.resume()
Kotlinโ
import okhttp3.*
import java.io.File
val client = OkHttpClient()
val file = File("passport.jpg")
val requestBody = MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart(
"file",
file.name,
RequestBody.create(MediaType.parse("image/jpeg"), file)
)
.build()
val request = Request.Builder()
.url("https://api.iapp.co.th/passport-ocr/v2/ocr")
.addHeader("apikey", "YOUR_API_KEY")
.post(requestBody)
.build()
client.newCall(request).execute().use { response ->
println(response.body()?.string())
}
Javaโ
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.*;
public class PassportOCR {
public static void main(String[] args) throws IOException {
String boundary = "Boundary-" + System.currentTimeMillis();
URL url = new URL("https://api.iapp.co.th/passport-ocr/v2/ocr");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("apikey", "YOUR_API_KEY");
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
try (OutputStream os = conn.getOutputStream()) {
byte[] fileBytes = Files.readAllBytes(Paths.get("passport.jpg"));
os.write(("--" + boundary + "\r\n").getBytes());
os.write(("Content-Disposition: form-data; name=\"file\"; filename=\"passport.jpg\"\r\n").getBytes());
os.write(("Content-Type: image/jpeg\r\n\r\n").getBytes());
os.write(fileBytes);
os.write(("\r\n--" + boundary + "--\r\n").getBytes());
}
try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
}
}
Dartโ
import 'package:http/http.dart' as http;
import 'dart:io';
Future<void> scanPassport() async {
var url = Uri.parse('https://api.iapp.co.th/passport-ocr/v2/ocr');
var request = http.MultipartRequest('POST', url);
request.headers['apikey'] = 'YOUR_API_KEY';
request.files.add(
await http.MultipartFile.fromPath(
'file',
'passport.jpg',
),
);
var response = await request.send();
var responseBody = await response.stream.bytesToString();
print(responseBody);
}
Limitations and Best Practicesโ
Limitationsโ
- Maximum file size: 10MB
- Supported formats: JPG, PNG, PDF
- One passport per image
- Clear, focused images required
Best Practicesโ
- Ensure good lighting conditions
- Avoid glare and reflections
- Center the passport in frame
- Keep the passport flat
- Use high resolution images
- Enable segmentation option for skewed images
Accuracy & Performanceโ
Overall Accuracyโ
- Current Version (2.0): 95.51%
- Previous Version (1.1): 88.86%
Field-Level Accuracy (Version 1.1)โ
- Name: 81.93%
- Surname: 90.26%
- Document Number: 84.03%
- Nationality: 88.09%
- Face Detection: 100%
Processing Speedโ
- Single image: 1-2 seconds
- PDF documents: 2-3 seconds per page
- Additional time when using segmentation
Factors Affecting Accuracyโ
- Image quality
- Lighting conditions
- Document positioning
- Image resolution
- Document condition
- Image skew angle
Historyโ
Version 2.0 (February 2023)โ
- Increased overall accuracy from 88.86% to 95.51%
- Upgraded entire OCR engine
- Added image segmentation pre-processing for skewed images
Version 1.1 (January 2023)โ
- Added face extraction to base64
- Added support for slightly tilted images
- Added PDF file support
- Added multiple page PDF support
Version 1.0 (February 2022)โ
- Initial release
- Support for all country passports using MRZ
- Basic image format support (PNG, JPG, JPEG)
Pricingโ
AI API Service Name | Endpoint | IC Per Request | On-Premise |
---|---|---|---|
Passport OCR [v2.0] | passport_ocr_v1 | 0.75 IC/Request | Contact |
passport_ocr_v2 | 0.75 IC/Request |