📄 General Thai Document OCR
🧾 ระบบอ่านจดหมายราชการ รายงาน เอกสารไทยทั่วไป
Welcome to Thai Document OCR API, version 2.0, an AI product developed by iApp Technology Co., Ltd. Our API automatically converts printed Thai documents into editable text formats with high accuracy. The API supports images (PNG, JPEG, JPG), PDF files, and Microsoft Office documents (Word, Excel, PowerPoint), processing them into three different output formats.
Try Demo!
Getting Started
-
Prerequisites
- An API key from iApp Technology
- Thai documents (images, PDFs, or Office files)
- Supported formats: PNG, JPEG, JPG, PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX
- Maximum file size: 30MB
-
Quick Start
- Fast processing time
- High accuracy text extraction
- Multiple output format options
-
Key Features
- Three output formats:
- Editable Text (.txt)
- Structured JSON (.json)
- Microsoft Word file (.docx)
- Automatic document component recognition
- Support for both Thai and English text
- Three output formats:
-
Security & Compliance
- GDPR and PDPA compliant
- URL file paths valid for 10 minutes only
API Endpoints
| Endpoint | Method | Description | Cost |
|---|---|---|---|
/v3/store/ocr/document/ocrLegacy : /document-ocr/ocr | POST | OCR for general Thai documents to Plain Text | 1 IC per page |
/v3/store/ocr/document/layoutLegacy : /document-ocr/layout | POST | OCR for general Thai documents to Layout JSON (with layout information analysis) | 1 IC per page |
/v3/store/ocr/document/docxLegacy : /document-ocr/docx | POST | OCR for general Thai documents and convert it to Microsoft Word (DOCX) | 1 IC per page |
Features & Capabilities
Core Features
- Text extraction from documents
- Document structure analysis
- Multiple output formats
- Support for Thai and English text
- PDF file support
Supported Fields
- Page boundary detection
- Title recognition
- Paragraph detection
- Image detection
- Table recognition
- Thai character recognition
- English character recognition
- Special character support
Example
Perform OCR and Return Raw Text
- Sample Request
curl --location 'https://api.iapp.co.th/v3/store/ocr/document/ocr' \
--header 'apikey: {YOUR API KEY}' \
--form 'file=@"{YOUR UPLOADED FILE}"'
- Sample Response
{
"text": ["ด่วนที่สุด\nที่ มท ๐๔๐๒.๖ มั่นคงและชุมชนพึ่งตนเองได้\nภายในป ี ๒๕๖๕ ..."],
"time": 1.1443967819213867,
"iapp": { "page": 0, "char": 1376 }
}
Perform Document Structure Analysis, OCR and return JSON formatted bounding box and raw text
- Sample Request
curl --location 'https://api.iapp.co.th/v3/store/ocr/document/layout' \
--header 'apikey: {YOUR API KEY}' \
--form 'file=@"{YOUR UPLOADED FILE}"'
- Sample Response
{
"pages": [
{
"page": 1,
"components": [
{
"text": "ให้ไว้ ณ วันที่ 10 กุมภาพันธ์ 2554\n(นาย น ง ปานทอง\nอัยการผู้เชี่ยวชาญ สํานักงานอัยการภาค 5\nรักษาการในตาแหน่งอัยการจังหวัดเชียงใหม่",
"bb_left": 228.6162872314453,
"bb_top": 433.568115234375,
"bb_right": 436.36279296875,
"bb_bottom": 554.9218139648438,
"type": "Signature"
},
{
"text": "หนังสือรับรองฉบับนี้ออกให้เพื่อรับรองว่า ห้างหุ้นส่วนจำกัด เชียงใหม่แฮร์แคร์เอ็นจิเนียริ่ง ซึ่ง\nจดทะเบียนเป็นนิติบุคคล ณ สำนักงานทะเบียนหุ้นส่วนบริษัทจังหวัดเชียงใหม่ กรมพัฒนาธุรกิจการค้า\nกระทรวงพาณิชย์ มีสำนักงานใหญ่ ตั้งอยู่ เลขที่ 58/19 หมู่ที่ 4 ตำบลหนองหอย อำาเภอเมืองเชียงใหม่ จังหวัด\nเชียงใหม่ 50000 จ้างเหมาครุภัณฑ์สำนักงานเครื่องปรับอากาศพร้อมติดตั้ง ทั้งนี้",
"bb_left": 120.08554077148438,
"bb_top": 194.70896911621094,
"bb_right": 560.1184692382812,
"bb_bottom": 271.0887756347656,
"type": "Para1"
},
{
"text": "FUSION รุ่น FUC24Ff124 (ฉลากเบอร์ 5) แบบฟอกอากาศ จํานวน 3 เครื่อง พร้อมติดตั้ง\nรายละเอียดตาม สัญญาเลขที่ 1/2554 ลงวันที่ 13 มกราคม พ.ศ. 2554 จํานวนเงินตามสัญญารวมทั้ง\nสามรายการ เป็นเงินทั้งสิ้น 512,255 บาท (ห้าแสนหนึ่งหมื่นสองพันสองร้อยห้าสิบห้าบาทถ้วน) ซึ่งผู้จ้างได้",
"bb_left": 109.7691650390625,
"bb_top": 353.8553161621094,
"bb_right": 551.1951293945312,
"bb_bottom": 418.5770568847656,
"type": "Para1"
},
{ "text": "", "bb_left": 281.7373046875, "bb_top": 47.54597854614258, "bb_right": 348.1979675292969, "bb_bottom": 117.07936096191406, "type": "Logo" },
{
"text": "FISION รุ่น FIC MARUDT1 (ฉลากเบอร์ 5) แบบฟอกอากาศ จํานวน 11 เครื่อง พร้อมติดตั้ง\n3. เครื่องปรับอากาศแบบแยกส่วน ชนิดตั้งพื้นหรือชนิดแขวน ขนาด 25,182.95 ยู ยี่ห้อ",
"bb_left": 107.63800048828125,
"bb_top": 313.69549560546875,
"bb_right": 527.8297119140625,
"bb_bottom": 355.0850524902344,
"type": "Para1"
},
{
"text": "FUSION รุ่น FUCK1201128 (ฉลากเบอร์ 5) แบบฟอกอากาศ จํานวน 11 เครื่อง พร้อมติดตั้ง\n2. เครื่องปรับอากาศแบบแยกส่วน ชนิดตั้งพื้นหรือชนิดแขวน ขนาด 18,087.01 บีทียู ยี่ห้อ",
"bb_left": 108.46659088134766,
"bb_top": 279.6349182128906,
"bb_right": 536.12890625,
"bb_bottom": 322.54345703125,
"type": "Para1"
},
{
"text": "สํานักงานอัยการจังหวัดเชียงใหม่\nคน ราชการจังหวัดเชียงใหม่\nถ.โชตนา ชม 50300",
"bb_left": 374.2991638183594,
"bb_top": 95.19263458251953,
"bb_right": 509.24542236328125,
"bb_bottom": 156.33181762695312,
"type": "UpperRight"
},
{ "text": "หนังสือรับรองผลงาน", "bb_left": 282.33282470703125, "bb_top": 165.2444610595703, "bb_right": 374.5608215332031, "bb_bottom": 184.74752807617188, "type": "Date" },
{
"text": "1. เครื่องปรับอากาศแบบแยกส่วน ชนิดตั้งพื้นหรือชนิดแขวน ขนาด 13,942.80 บีทียู ยี่หัอ\nFUSION 1UCk120112 (ฉลากเบอร์ 5) แบบฟอกอากาศ จํานวน 11 เครื่อง พร้อมติดตั้ง",
"bb_left": 114.9815902709961,
"bb_top": 269.22735595703125,
"bb_right": 521.8577270507812,
"bb_bottom": 306.366943359375,
"type": "Para1"
},
{ "text": "ที่ ทส (ชม) 0037/435", "bb_left": 122.62628936767578, "bb_top": 98.11686706542969, "bb_right": 224.76698303222656, "bb_bottom": 116.89942932128906, "type": "NextPage" },
{
"text": "FLE\n2. เครื่องปรับอากาศแบบแยกส่วน ชนิดตั้งพื้นหรือชนิดแขวน ขนาด 18,087.01 บีทียู ยี่ห้อ\nFIISION รุ่น FIC MARUIDT1 (ฉลากเบอร์ 5) แบบฟอกอากาศ จํานวน 11 เอง พร้อมติดตั้ง",
"bb_left": 108.22515106201172,
"bb_top": 293.6889953613281,
"bb_right": 529.6473388671875,
"bb_bottom": 338.7919616699219,
"type": "Para1"
},
{
"text": "เชียงใหม่ 50000 จ้างเหมาครุ ณ สานักงานเครื่องปรับอากาศพร้อมสด ง.\n1. เครื่องปรับอากาศแบบแยกส่วน ชนิดตั้งพื้นหรือชนิดแขวน ขนาด 13,942.80 บีทียู ยี่ห้อ",
"bb_left": 112.15975189208984,
"bb_top": 255.9883575439453,
"bb_right": 546.0884399414062,
"bb_bottom": 290.6558532714844,
"type": "Para1"
}
]
}
],
"time": 4.234404563903809,
"iapp": { "page": 1, "char": 1673 }
}
Perform Document Structure Analysis, OCR and return a URL file path of a converted Microsoft Words (as .docx) file.
- Sample Request
curl --location 'https://api.iapp.co.th/v3/store/ocr/document/docx' \
--header 'apikey: {YOUR API KEY}' \
--form 'file=@"{YOUR UPLOADED FILE}"'
- Sample Response
{
"path": "https://storage.googleapis.com/iapp-ocr-docx/document_trial2-250114-074403.docx?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=ai-ocr%40iapp-ai-357013.iam.gserviceaccount.com%2F20250114%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20250114T074407Z&X-Goog-Expires=600&X-Goog-SignedHeaders=host&X-Goog-Signature=425b62bc36eec0cc5c0ca7442f863ae960f7a41302f8da5c312b7392011cbfe6119b4814bade146fac81da427a231142cce5d67a56c35e242437cf5a7990bc48290c403052af23eb2293da55e5249cdb803bb4c18a5b15d6262caa4b773487417dd3ed62fe47a75e42d7aa5e631e08efa1320c589042b0e244c7ba0c10ec236303f6b92d1546d49f3f1b1f4aca7ceb9715036470b6bd6caf6aecb862eef180d213f8787e65dc5f97decf0b05add6ce28499a5b76ef31112884442affc3b79dde8531a014e90352a9e73ffdc1f118e2d082294509fb41c26e3f4d55c2854c73e3142298ef75d40ee95dbe63c4c2ec4de4a170c9c746986f7d248f99f0ef9a12f9",
"time": 1.728440761566162,
"iapp": { "pages": 1, "char": 1229 }
}
API Reference
Endpoints
| Endpoint | Method | URL | Description | Content-Type |
|---|---|---|---|---|
| Text Extraction | POST | https://api.iapp.co.th/v3/store/ocr/document/ocr | Returns raw text output | multipart/form-data |
| Layout Analysis | POST | https://api.iapp.co.th/v3/store/ocr/document/layout | Returns JSON with bounding boxes and text | multipart/form-data |
| DOCX Conversion | POST | https://api.iapp.co.th/v3/store/ocr/document/docx | Returns URL to download .docx file | multipart/form-data |
Required Parameter
| Parameter | Required | Description |
|---|---|---|
apikey | Yes | Your API key |
file | Yes | Document image/PDF file |
Code Example
Python
import requests
url = "https://api.iapp.co.th/v3/store/ocr/document/ocr"
payload = {}
files=[
('file',('{YOUR UPLOADED FILE}',open('{YOUR UPLOADED FILE}','rb'),'application/pdf'))
]
headers = {
'apikey': '{YOUR API KEY}'
}
response = requests.request("POST", url, headers=headers, data=payload, files=files)
print(response.text)
JavaScript
const axios = require("axios")
const FormData = require("form-data")
const fs = require("fs")
let data = new FormData()
data.append("file", fs.createReadStream("{YOUR UPLOADED FILE}"))
let config = {
method: "post",
maxBodyLength: Infinity,
url: "https://api.iapp.co.th/v3/store/ocr/document/ocr",
headers: {
apikey: "{YOUR API KEY}",
...data.getHeaders(),
},
data: data,
}
axios
.request(config)
.then((response) => {
console.log(JSON.stringify(response.data))
})
.catch((error) => {
console.log(error)
})
PHP
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.iapp.co.th/v3/store/ocr/document/ocr',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => array('file'=> new CURLFILE('{YOUR UPLOADED FILE}')),
CURLOPT_HTTPHEADER => array(
'apikey: {YOUR API KEY}'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
Swift
let parameters = [
[
"key": "file",
"src": "{YOUR UPLOADED FILE}",
"type": "file"
]] as [[String: Any]]
let boundary = "Boundary-\(UUID().uuidString)"
var body = Data()
var error: Error? = nil
for param in parameters {
if param["disabled"] != nil { continue }
let paramName = param["key"]!
body += Data("--\(boundary)\r\n".utf8)
body += Data("Content-Disposition:form-data; name=\"\(paramName)\"".utf8)
if param["contentType"] != nil {
body += Data("\r\nContent-Type: \(param["contentType"] as! String)".utf8)
}
let paramType = param["type"] as! String
if paramType == "text" {
let paramValue = param["value"] as! String
body += Data("\r\n\r\n\(paramValue)\r\n".utf8)
} else {
let paramSrc = param["src"] as! String
let fileURL = URL(fileURLWithPath: paramSrc)
if let fileContent = try? Data(contentsOf: fileURL) {
body += Data("; filename=\"\(paramSrc)\"\r\n".utf8)
body += Data("Content-Type: \"content-type header\"\r\n".utf8)
body += Data("\r\n".utf8)
body += fileContent
body += Data("\r\n".utf8)
}
}
}
body += Data("--\(boundary)--\r\n".utf8);
let postData = body
var request = URLRequest(url: URL(string: "https://api.iapp.co.th/v3/store/ocr/document/ocr")!,timeoutInterval: Double.infinity)
request.addValue("{YOUR API KEY}", forHTTPHeaderField: "apikey")
request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
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
val client = OkHttpClient()
val mediaType = "text/plain".toMediaType()
val body = MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("file","{YOUR UPLOADED FILE}",
File("{YOUR UPLOADED FILE}").asRequestBody("application/octet-stream".toMediaType()))
.build()
val request = Request.Builder()
.url("https://api.iapp.co.th/v3/store/ocr/document/ocr")
.post(body)
.addHeader("apikey", "{YOUR API KEY}")
.build()
val response = client.newCall(request).execute()
Java
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("text/plain");
RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("file","{YOUR UPLOADED FILE}",
RequestBody.create(MediaType.parse("application/octet-stream"),
new File("{YOUR UPLOADED FILE}")))
.build();
Request request = new Request.Builder()
.url("https://api.iapp.co.th/v3/store/ocr/document/ocr")
.method("POST", body)
.addHeader("apikey", "{YOUR API KEY}")
.build();
Response response = client.newCall(request).execute();
Dart
var headers = {
'apikey': '{YOUR API KEY}'
};
var request = http.MultipartRequest('POST', Uri.parse('https://api.iapp.co.th/v3/store/ocr/document/ocr'));
request.files.add(await http.MultipartFile.fromPath('file', '{YOUR UPLOADED FILE}'));
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
print(await response.stream.bytesToString());
}
else {
print(response.reasonPhrase);
}
Accuracy and Performance
- Document Component Analysis Accuracy: 96.97% AP Score
- OCR Accuracy (Word Level)
- English Accuracy ~98%
- Thai Accuracy ~96%
Code Examples
Curl
curl -X POST https://api.iapp.co.th/v3/store/ocr/document \
-H "apikey: YOUR_API_KEY" \
-F "file=@/path/to/document.pdf"
Python
import requests
url = "https://api.iapp.co.th/v3/store/ocr/document/ocr"
files = {"file": ("("/path/to/document.pdf", "rb"))}
headers = {"apikey": "YOUR_API_KEY"}
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("/path/to/document.pdf"));
let config = {
method: "post",
url: "https://api.iapp.co.th/v3/store/ocr/document/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/v3/store/ocr/document/ocr',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => array(
'file'=> new CURLFILE('/path/to/document.pdf')
),
CURLOPT_HTTPHEADER => array(
'apikey: YOUR_API_KEY'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
?>
Swift
import Foundation
let url = URL(string: "https://api.iapp.co.th/v3/store/ocr/document/ocr")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("YOUR_API_KEY", forHTTPHeaderField: "apikey")
let boundary = "Boundary-\(UUID().uuidString)"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
var body = Data()
body.append("--\(boundary)\r\n".data(using: .utf8)!)
body.append("Content-Disposition: form-data; name=\"file\"; filename=\"file.jpg\"\r\n".data(using: .utf8)!)
body.append("Content-Type: image/jpeg\r\n\r\n".data(using: .utf8)!)
if let fileData = try? Data(contentsOf: URL(fileURLWithPath: "/path/to/document.pdf")) {
body.append(fileData)
}
body.append("\r\n--\(boundary)--\r\n".data(using: .utf8)!)
request.httpBody = body
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
print(String(data: data, encoding: .utf8)!)
}
}
task.resume()
Kotlin
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody.Companion.asRequestBody
import java.io.File
val client = OkHttpClient()
val file = File("/path/to/document.pdf")
val requestBody = MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", file.name, file.asRequestBody("image/jpeg".toMediaTypeOrNull()))
.build()
val request = Request.Builder()
.url("https://api.iapp.co.th/v3/store/ocr/document/ocr")
.addHeader("apikey", "YOUR_API_KEY")
.post(requestBody)
.build()
client.newCall(request).execute().use { response ->
println(response.body?.string())
}
Java
import okhttp3.*;
import java.io.File;
OkHttpClient client = new OkHttpClient();
File file = new File("/path/to/document.pdf");
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", file.getName(),
RequestBody.create(MediaType.parse("image/jpeg"), file))
.build();
Request request = new Request.Builder()
.url("https://api.iapp.co.th/v3/store/ocr/document/ocr")
.addHeader("apikey", "YOUR_API_KEY")
.post(requestBody)
.build();
try (Response response = client.newCall(request).execute()) {
System.out.println(response.body().string());
}
Dart
import 'package:http/http.dart' as http;
var request = http.MultipartRequest(
'POST',
Uri.parse('https://api.iapp.co.th/v3/store/ocr/document/ocr')
);
request.files.add(await http.MultipartFile.fromPath(
'file',
'/path/to/document.pdf'
));
request.headers.addAll({
'apikey': 'YOUR_API_KEY'
});
var response = await request.send();
var responseBody = await response.stream.bytesToString();
print(responseBody);
Pricing
| AI API Service Name | Endpoint | Pricing | On-Premise |
|---|---|---|---|
| Document OCR | /v3/store/ocr/document/ocr | 1 IC/Page | Contact |
| Document OCR with Layout Structure JSON | /v3/store/ocr/document/layout | 1 IC/Page | Contact |
| Document OCR convert to Microsoft Word (DOCX) | /v3/store/ocr/document/docx | 1 IC/Page | Contact |

