🪪 Thai National ID Card OCR
🪪 บัตรประชาชนไทย
Welcome to Thai National ID Card OCR API, version 3.5, an AI product developed by iApp Technology Co., Ltd. Our API is designed to extract text information from both the front and back face of Thai National ID card images with high accuracy and speed. Our API supports JPEG, JPG, PNG, HEIC, HEIF, and PDF file formats and can process an ID card image in 1-2 seconds.
Visit our API Portal to test the Thai National ID Card OCR API with your own images.
Getting Started
-
Prerequisites
- An API key from iApp Technology
- Thai national ID card images (front/back)
- Supported file formats: JPEG, JPG, PNG, HEIC, HEIF, PDF
- Maximum file size: 10MB
-
Quick Start
- Fast processing (1-2 seconds per card)
- High accuracy text extraction (98.13% at character level)
- Support for multiple file formats
-
Key Features
- Detailed field extraction including:
- ID number
- Full name (Thai and English)
- Date of birth
- Religion
- Address
- Issue and expiry dates
- Support for both front and back of ID cards
- Option to return original OCR text and processed images
- Flexible JSON response format
- Detailed field extraction including:
-
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
Front side
Request:
curl -X POST https://api.iapp.co.th/thai-national-id-card/v3.5/front
-H "apikey: YOUR_API_KEY"
-F "file=@/path/to/idcard.jpg"
Response:
{
"address": "XXXXXX XXXX X ต.หนองปรือ อ.บางละมุง จ.ชลบุรี",
"alley": "",
"detection_score": 0.981011797984441,
"district": "บางละมุง",
"en_dob": "XX Mar 1957",
"en_expire": "XX Mar 2025",
"en_fname": "XXXXXX",
"en_init": "Mrs.",
"en_issue": "26 Jul 2016",
"en_lname": "Lopez",
"en_name": "Mrs. XXXXXX Lopez",
"error_message": "",
"face": "/9j/4AAQ...UAFFFFAH/9k=", # Base64 of photo's image
"gender": "Female",
"home_address": "XXXXX XXX",
"house_no": "XXXXXX",
"id_number": "34117XXXXXX334",
"id_number_status": 1,
"lane": "",
"postal_code": "20150", # Automatic Retrieve from Database
"process_time": 1.3018648624420166, # Seconds
"province": "ชลบุรี",
"religion": "",
"request_id": null,
"road": "",
"sub_district": "หนองปรือ",
"th_dob": "XX มี.ค. 2500",
"th_expire": "XX มี.ค. 2568",
"th_fname": "XXXXX",
"th_init": "นาง",
"th_issue": "XX ก.ค. 2559",
"th_lname": "โ ลเปซ",
"th_name": "นาง XXXXX โลเปซ",
"village": "",
"village_no": "7"
}
Backside
Request:
curl --location --request POST 'https://api.iapp.co.th/thai-national-id-card/v3.5/back' \
--header 'apikey: {Your API Key}' \
--form 'file=@"path/to/id-card-back.jpg"'
Response:
{
"back_number": "JT0-XXXXXXX-05",
"detection_score": 0.99846746524175,
"process_time": 1.370201416015625
}
Features & Capabilities
Core Features
- High accuracy text extraction (98.13% character-level accuracy)
- Fast processing time (1-3 seconds per card)
- Support for multiple file formats (JPEG, JPG, PNG, HEIC, HEIF, PDF)
- Automatic card cropping and rotation
- Return bounding boxes and scores for fields
- Return base64 images of card and fields
- Return raw OCR text
- Support for back card side without chip
Supported Fields
Front Side
Field | Type | Description |
---|---|---|
address | String | Address on the ID card |
detection_score | float | Detection score of a related field |
district | String | District name on the ID card |
en_dob | String | Date of birth, in English |
en_expire | String | Date of expiry, in English |
en_fname | String | English given name |
en_init | String | Name title, in English |
en_issue | String | Date of issue, in Thai |
en_lname | String | English surname |
en_name | String | English given name and surname |
error_message | String | Error message |
face | String | Base64 character string converted from the image |
gender | String | Gender |
home_address | String | Home address on the ID card |
id_number | String | National ID number |
postal_code | String | Postal Code |
process_time | String | Processing time (Sec.) |
province | String | Province name on the ID card |
religion | String | Religion on the ID card |
sub_district | String | Sub district name on the ID card |
th_dob | String | Date of birth, in Thai |
th_expire | String | Date of expiry, in Thai |
th_fname | String | Thai given name |
th_init | String | Name title, in English |
th_issue | String | Date of issue |
th_lname | String | Thai surname |
th_name | String | Thai given name and surname |
Back side
Field | Type | Description |
---|---|---|
back_number | String | Laser number on back of ID card |
Common Response Fields
Field | Type | Description |
---|---|---|
detection_score | Float | Confidence score (0-1) |
error_message | String | Error message if request fails |
process_time | Float | Processing time in seconds |
API Reference
Recognizing Thai National ID Card
This endpoint processes Thai national ID card images and returns the extracted data in a structured format.
Front Side
POST https://api.iapp.co.th/thai-national-id-card/v3.5/front
Request Headers
Name | Type | Required | Description |
---|---|---|---|
apikey | string | Yes | Your API key |
Request Body (multipart/form-data)
Parameter | Type | Required | Description |
---|---|---|---|
file | File | Yes | The binary data of the image (front side) |
fields | String | No | Option to choose fields in output |
options | String | No | Option to choose processing tools and settings |
Back Side
POST https://api.iapp.co.th/thai-national-id-card/v3.5/back
Request Headers
Name | Type | Required | Description |
---|---|---|---|
apikey | string | Yes | Your API key |
Request Body (multipart/form-data)
Parameter | Type | Required | Description |
---|---|---|---|
file | File | Yes | The binary data of the image (back side) |
options | String | No | Option to choose processing tools and settings |
Available Options
not_crop_card
- Skip card croppingnot_rotate_card
- Skip auto-rotationget_bbox
- Return bounding box coordinatesget_image
- Return processed imageget_original
- Return original image
Response Format for Available Options
When using the available options, the response JSON will include additional fields based on the options selected:
Response with get_bbox Option
Returns bounding box coordinates for each detected field in the format [x1, y1, x2, y2]
with confidence score:
{
"bbox": {
"address": [
[[119, 292, 376, 334], 0.991],
[[75, 330, 255, 362], 0.999]
],
"card": [[[0, 0, 713, 462], 0.99]],
"en_dob": [[[370, 235, 526, 266], 0.999]],
"face": [[[544, 218, 708, 407], 0.999]]
// Other field coordinates...
}
}
Response with get_image Option
Returns base64 encoded cropped images for each detected field:
{
"image": {
"address": ["/9j/4AAQSk...", "/9j/4AAQSk..."],
"card": ["/9j/4AAQSk..."],
"face": ["/9j/4AAQSk..."],
"id_number": ["/9j/4AAQSk..."]
// Other field images...
}
}
Response with get_original Option
Returns the original values before the autocorrect step (which occured in the post processing step) detected from the card:
{
"original": {
"address": "XXXXX XXXXX X ต.หนองปรือ อ.บางละมุง จ.ชลบุรี",
"en_dob": "XX Mar. 1957",
"en_expire": "XX Mar. 2025",
"th_name": "นาง XXXXXX โลเปซ"
// Other original field values...
}
}
The response will always include the standard fields like detection_score, error_message, and process_time regardless of options used.
Error Code
Specific Error Messages
Thai National ID Card Front Side
Status Code | Status Message | Description |
---|---|---|
420 | NO_ID_CARD_FOUND | The image file is not the ID card |
421 | IMAGE_ERROR_UNSUPPORTED_FORMAT | The image cannot be resolved. The file format may not be supported or the file is damaged |
422 | INVALID_IMAGE_SIZE | The size of the uploaded image does not meet the requirement |
424 | PLEASE_VERIFY_ID_CARD_NUMBER | The National ID Number has 13 digits but is incorrect. Response code 424 will show when using id_check option |
425 | CANNOT_READ_ID_CARD_NUMBER_CLEARLY | The National ID Number has less than 13 digits. Response code 425 will show when using id_check option |
426 | IMAGE_ERROR_UNSUPPORTED_BLACK_WHITE_IMAGE | Used gray_check option to check black-white and gray images |
Thai National ID Card Back Side
Status Code | Status Message | Description |
---|---|---|
430 | NO_ID_CARD_FOUND | The image file is not the ID Card |
431 | IMAGE_ERROR_UNSUPPORTED_FORMAT | The image cannot be resolved. The file format may not be supported or the file is damaged |
432 | INVALID_IMAGE_SIZE | The size of the uploaded image does not meet the requirement |
434 | LASER_NUMBER_NOT_FOUND | Cannot detect the laser number on back ID Card |
435 | CANNOT_READ_LASER_NUMBER_CLEARLY | The laser number has less than 12 digits. Response code 435 will show when using id_check option |
436 | IMAGE_ERROR_UNSUPPORTED_BLACK_WHITE_IMAGE | Used gray_check option to check black-white and gray images |
Common Error Messages
Status Code | Status Message | Description |
---|---|---|
404 | REQUESTED_URL_NOT_FOUND | API Route not found in request |
405 | METHOD_NOT_ALLOWED | Method name (GET, POST) in the URL is incorrect |
413 | FILE_IS_TOO_LARGE: (more than 2 MB) | The file size is too large |
427 | LONG_TIME_TO_PROCESS | The server is processed for a long time |
428 | LONG_TIME_TO_REQUEST | The client is waiting in the queue for a long time |
461 | NO_FILE_ATTACHED | No file attached |
560 | SERVER_IS_BUSY: (Please try again in a few seconds.) | Server is working on many requests |
563 | ID_CARD_API_NOT_SUPPORT_THIS_IMAGE | The API has an error in the process |
Code Examples
Python
import requests
url = "https://api.iapp.co.th/thai-national-id-card/v3.5/front"
payload = {
'options': 'get_bbox,get_image'
}
files = [
('file',('id-card.jpg',open('path/to/id-card.jpg','rb'),'image/jpeg'))
]
headers = {
'apikey': 'YOUR_API_KEY'
}
response = requests.request("POST", url, headers=headers, data=payload, files=files)
print(response.json())
JavaScript
const axios = require("axios")
const FormData = require("form-data")
const fs = require("fs")
const form = new FormData()
form.append("file", fs.createReadStream("path/to/id-card.jpg"))
form.append("options", "get_bbox,get_image")
const config = {
method: "post",
url: "https://api.iapp.co.th/thai-national-id-card/v3.5/front",
headers: {
apikey: "YOUR_API_KEY",
...form.getHeaders(),
},
data: form,
}
axios(config)
.then((response) => console.log(JSON.stringify(response.data)))
.catch((error) => console.log(error))
PHP
<?php
$curl = curl_init();
$post_data = array(
'file'=> new CURLFile('path/to/id-card.jpg'),
'options' => 'get_bbox,get_image'
);
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.iapp.co.th/thai-national-id-card/v3.5/front',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $post_data,
CURLOPT_HTTPHEADER => array(
'apikey: YOUR_API_KEY'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
?>
Swift
import Foundation
let headers = [
"apikey": "YOUR_API_KEY"
]
let parameters = [
[
"name": "file",
"fileName": "path/to/id-card.jpg"
],
[
"name": "options",
"value": "get_bbox,get_image"
]
]
let boundary = "Boundary-\(UUID().uuidString)"
var body = ""
var error: Error? = nil
for param in parameters {
if let fileName = param["fileName"] {
let fileContent = try? String(contentsOfFile: fileName, encoding: .utf8)
body += "--\(boundary)\r\n"
body += "Content-Disposition:form-data; name=\"\(param["name"] ?? "")\""
body += "; filename=\"\(fileName)\"\r\n"
body += "Content-Type: image/jpeg\r\n\r\n"
body += fileContent ?? ""
} else {
body += "--\(boundary)\r\n"
body += "Content-Disposition:form-data; name=\"\(param["name"] ?? "")\"\r\n\r\n"
body += param["value"] ?? ""
}
}
let postData = body.data(using: .utf8)
var request = URLRequest(url: URL(string: "https://api.iapp.co.th/thai-national-id-card/v3.5/front")!,timeoutInterval: Double.infinity)
request.addValue("YOUR_API_KEY", forHTTPHeaderField: "apikey")
request.httpMethod = "POST"
request.httpBody = postData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else {
print(String(describing: error))
return
}
print(String(data: data, encoding: .utf8)!)
}
task.resume()
Kotlin
import okhttp3.*
import java.io.File
val client = OkHttpClient()
val mediaType = MediaType.parse("image/jpeg")
val file = File("path/to/id-card.jpg")
val body = MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("file", file.name, RequestBody.create(mediaType, file))
.addFormDataPart("options", "get_bbox,get_image")
.build()
val request = Request.Builder()
.url("https://api.iapp.co.th/thai-national-id-card/v3.5/front")
.addHeader("apikey", "YOUR_API_KEY")
.post(body)
.build()
client.newCall(request).execute().use { response ->
println(response.body()?.string())
}
Java
import java.io.File;
import okhttp3.*;
public class Main {
public static void main(String[] args) {
OkHttpClient client = new OkHttpClient().newBuilder().build();
MediaType mediaType = MediaType.parse("image/jpeg");
RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("file", "id-card.jpg",
RequestBody.create(mediaType, new File("path/to/id-card.jpg")))
.addFormDataPart("options", "get_bbox,get_image")
.build();
Request request = new Request.Builder()
.url("https://api.iapp.co.th/thai-national-id-card/v3.5/front")
.method("POST", body)
.addHeader("apikey", "YOUR_API_KEY")
.build();
try {
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
} catch(Exception e) {
e.printStackTrace();
}
}
}
Dart
import 'package:http/http.dart' as http;
void main() async {
var request = http.MultipartRequest('POST',
Uri.parse('https://api.iapp.co.th/thai-national-id-card/v3.5/front'));
request.files.add(await http.MultipartFile.fromPath(
'file', 'path/to/id-card.jpg'));
request.fields['options'] = 'get_bbox,get_image';
request.headers.addAll({
'apikey': 'YOUR_API_KEY'
});
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
print(await response.stream.bytesToString());
} else {
print(response.reasonPhrase);
}
}
Limitations and Best Practices
Limitations
- Maximum file size: 10MB
- Supported formats: JPEG, JPG, PNG, HEIC, HEIF, PDF
Best Practices
- Ensure good image quality
- Check detection_score in response
- Handle error messages appropriately
- Validate ID card number format
- Consider using options parameter for specific needs
Accuracy & Performance
Overall Accuracy
- Detection score typically above 96%
- Field-specific accuracy varies
Processing Speed
- Average: 1-2 seconds
- May vary based on image size and quality
Factors Affecting Accuracy
- Image Quality
- Resolution (Minimum 300 DPS)
- Lighting
- Focus
- Card Condition
- Physical damage
- Reflections
- Text clarity
History
Version | Release Date | Accuracy | Key Improvements |
---|---|---|---|
3.5 | Nov 2022 | 98.13% | New OCR Engine, Faster Processing |
3.4 | Jul 2022 | 93.25% | Added Thai Military Ranks |
3.1-3.3 | May-Jul 2021 | 92.75% | Internal Beta Release |
3.0 | Feb 2021 | 91.75% | Major Accuracy Improvements |
2.0 | Feb 2020 | 85% | Added Back Card Support |
1.0 | Nov 2019 | 76% | Initial Release |
Pricing
AI API Service Name | Endpoint | IC Per Request | On-Premise |
---|---|---|---|
Thai National ID Card OCR (v3.5) | iapp_thai_national_id_card_ocr_v3.5_back | 0.75 IC/Request | Contact |
iapp_thai_national_id_card_ocr_v3.5_front | 1.25 IC/Request |