General Thai Document OCR
The General Thai Document OCR API converts printed Thai and English documents into machine-readable text. It accepts images (PNG, JPEG), PDF files, and Microsoft Office documents, and returns plain text, layout-structured JSON, or generated Microsoft Word, PowerPoint, Excel, or searchable PDF files. The production service processes a page of plain text in 0.53 seconds (median) and sustains 4.28 pages per second — more than 15,000 pages per hour. Measured character accuracy is 94.8 percent on an independent public benchmark of scanned Thai government documents; see Accuracy.
Live Demo
Upload a document, or select one of the examples below.
Try Our AI Demo
Login or create a free account to use this AI service demo and explore our powerful APIs.
Get 100 Free Credits (IC) when you sign up!
Offer ends December 31, 2025
Example Images (Click to try)












Quick Start
You need an API key from the iApp AI Portal. Send the document as multipart/form-data:
curl -X POST https://api.iapp.co.th/v3/store/ocr/document/ocr \
-H "apikey: YOUR_API_KEY" \
-F "file=@document.pdf"
{
"text": ["ด่วน ที่สุด\nที่ มท ๐๔๐๒.๖ ..."],
"time": 0.53,
"iapp": { "page": 1, "char": 1376 }
}
Code examples for Python, JavaScript, PHP, Swift, Kotlin, Java, and Dart are in the Technical Reference.
Endpoints and Pricing
All endpoints accept the same input and charge 1 IC per input page. Choose the endpoint by the output you need.
| Endpoint | Output | Price |
|---|---|---|
POST /v3/store/ocr/document/ocr | Plain text | 1 IC per page |
POST /v3/store/ocr/document/layout | JSON with text, bounding boxes, and component types | 1 IC per page |
POST /v3/store/ocr/document/docx | Download link to a generated Microsoft Word (.docx) file | 1 IC per page |
POST /v3/store/ocr/document/pptx | Download link to a generated Microsoft PowerPoint (.pptx) file | 1 IC per page |
POST /v3/store/ocr/document/xlsx | Download link to a generated Microsoft Excel (.xlsx) file | 1 IC per page |
POST /v3/store/ocr/document/searchablePDF | Download link to a searchable PDF — the original pages with a selectable text layer | 1 IC per page |
Every endpoint is also available under the legacy /document-ocr prefix, for example /document-ocr/pptx. For on-premise deployment, see Data Security.
Performance
Measured on the production service, August 2026.
| Metric | Value |
|---|---|
| Median processing time (plain text) | 0.53 s per page |
| Sustained throughput | 4.28 pages per second (15,400 pages per hour) |
| Maximum file size | 30 MB |
| Supported input formats | PNG, JPEG, PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX |
Accuracy
Accuracy is measured on an independent, publicly available benchmark: 242 scanned pages from 20 Thai Administrative Court judgments, scored against their original source documents.
| Metric | Result |
|---|---|
| Character error rate (CER) | 5.2% (94.8% character accuracy) |
| Word error rate (WER) | 7.0% (93.0% word accuracy) |
| Document layout analysis | 96.97% AP |
The benchmark counts every difference between the OCR output and the source document as an error, including headers and typesetting differences, so the figures above are conservative. Clean, well-scanned prints score higher. The full methodology, per-document results, and comparison against a leading global cloud OCR service are published in the benchmark whitepaper:
Download the benchmark whitepaper (PDF)
Data Security and Compliance
- The service is GDPR and PDPA compliant.
- Uploaded documents are used only to produce the requested output.
- Generated download links expire after 10 minutes, and generated files are deleted from the server within one hour.
- A fully self-contained on-premise deployment is available, in which no document data leaves your infrastructure. Contact us for details.
Technical Reference
Request
All endpoints accept multipart/form-data with the apikey header.
| Field | Required | Description |
|---|---|---|
file | Yes, unless base64 is used | The document: image, PDF, or Microsoft Office file |
base64 | No | A single image as a Base64 string, as an alternative to file |
email | No | If set, the result is emailed to this address instead of returned in the response |
Every response carries the header iapp-input-pages with the number of input pages, which equals the number of IC charged.
Responses
/ocr returns one text string per page:
{
"text": ["ด่วนที่สุด\nที่ มท ๐๔๐๒.๖ มั่นคงและชุมชนพึ่งตนเองได้\nภายในปี ๒๕๖๕ ..."],
"time": 0.53,
"iapp": { "page": 1, "char": 1376 }
}
/layout returns, for every page, the detected components with their text, bounding box (in page coordinates), and component type:
{
"pages": [
{
"page": 1,
"components": [
{
"text": "หนังสือรับรองผลงาน",
"bb_left": 282.3, "bb_top": 165.2, "bb_right": 374.6, "bb_bottom": 184.7,
"type": "CenTitle"
},
{
"text": "หนังสือรับรองฉบับนี้ออกให้เพื่อรับรองว่า ...",
"bb_left": 120.1, "bb_top": 194.7, "bb_right": 560.1, "bb_bottom": 271.1,
"type": "Para1"
}
]
}
],
"time": 1.84,
"iapp": { "page": 1, "char": 1673 }
}
/docx, /pptx, /xlsx, and /searchablePDF return a signed download link. The link is valid for 10 minutes:
{
"path": "https://api.iapp.co.th/document-ocr/files/pZWNyZXQtZXhhbXBsZS10b2tlbg...",
"time": 1.72,
"iapp": { "pages": 1, "char": 1229 }
}
Layout Component Types
The type field of each component in the /layout response is one of the following.
| Group | Types |
|---|---|
| Titles and body text | CenTitle, Para1 – Para5, BodyText3, Text, TextBox |
| Lists | List, ListNum1 – ListNum4, ListCon1 – ListCon4 |
| Indented blocks | Indent1 – Indent5 |
| Tables | Table, TableLike |
| Page furniture | Header, Footer, Date, NextPage, UpperLeft, UpperRight, TopRight, BottomLeft, BottomRight |
| Graphics | Figure, Logo, LeftLogo |
| Signatures | Signature |
Code Examples
- cURL
- Python
- JavaScript
- PHP
- Swift
- Kotlin
- Java
- Dart
curl -X POST https://api.iapp.co.th/v3/store/ocr/document/ocr \
-H "apikey: YOUR_API_KEY" \
-F "file=@document.pdf"
import requests
url = "https://api.iapp.co.th/v3/store/ocr/document/ocr"
headers = {"apikey": "YOUR_API_KEY"}
files = {"file": open("document.pdf", "rb")}
response = requests.post(url, headers=headers, files=files)
print(response.json())
const axios = require("axios");
const FormData = require("form-data");
const fs = require("fs");
const data = new FormData();
data.append("file", fs.createReadStream("document.pdf"));
axios.post("https://api.iapp.co.th/v3/store/ocr/document/ocr", data, {
headers: { apikey: "YOUR_API_KEY", ...data.getHeaders() },
})
.then((response) => console.log(response.data))
.catch((error) => console.log(error));
<?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('document.pdf')
),
CURLOPT_HTTPHEADER => array(
'apikey: YOUR_API_KEY'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
?>
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=\"document.pdf\"\r\n".data(using: .utf8)!)
body.append("Content-Type: application/pdf\r\n\r\n".data(using: .utf8)!)
if let fileData = try? Data(contentsOf: URL(fileURLWithPath: "document.pdf")) {
body.append(fileData)
}
body.append("\r\n--\(boundary)--\r\n".data(using: .utf8)!)
request.httpBody = body
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
print(String(data: data, encoding: .utf8)!)
}
}.resume()
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody.Companion.asRequestBody
import java.io.File
val client = OkHttpClient()
val file = File("document.pdf")
val requestBody = MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", file.name, file.asRequestBody("application/pdf".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())
}
import okhttp3.*;
import java.io.File;
OkHttpClient client = new OkHttpClient();
File file = new File("document.pdf");
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", file.getName(),
RequestBody.create(MediaType.parse("application/pdf"), 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());
}
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', 'document.pdf'));
request.headers.addAll({'apikey': 'YOUR_API_KEY'});
var response = await request.send();
print(await response.stream.bytesToString());
Limitations
- Printed text only; handwriting is not supported.
- Scans at 200 dpi or higher give the best results.
- Files larger than 30 MB are rejected.
Changelog
| Version | Date | Changes |
|---|---|---|
| v2.1.13-20260822 | 22 Aug 2026 | Upgraded recognition engine: 15% relative reduction in character error rate on the public benchmark; median per-page processing time reduced from 3.33 s to 0.53 s. Generated files are now served directly by the API with signed, expiring links. Fully self-contained on-premise deployment available. PowerPoint (.pptx), Excel (.xlsx), and searchable-PDF outputs are now generally available. |
| v2.1.12-20251116 | 16 Nov 2025 | Added the iapp-input-pages response header. |
| v2.0 | Aug 2022 | Document layout analysis and Microsoft Word output. |