All use cases

Thai OCR for knowledge bases and document ingestion

Read Thai PDFs and scans into structured Markdown, so an index holds the document's headings and tables instead of a wall of text.

What comes back

An internal handbookoutput: markdown
# คู่มือพนักงาน

## ๓. การลาพักร้อน

พนักงานที่ทำงานครบหนึ่งปีมีสิทธิลาพักร้อนได้
ปีละหกวันทำการ

### ๓.๑ การยื่นคำขอ
ยื่นล่วงหน้าไม่น้อยกว่าเจ็ดวัน
Heading levels come back as heading levels, which is what lets a chunker split on sections instead of on character counts.
A specification tableoutput: structured
heading   ข้อกำหนดทางเทคนิค
table     14 rows x 4 columns
paragraph ค่าที่ระบุเป็นค่าที่วัดที่อุณหภูมิห้อง
A table stays one block with its rows and columns, so a retrieved answer can cite a row rather than a fragment of one.
A scanned circularoutput: markdown · 50 pages
## หน้า 1
# ประกาศ เรื่อง แนวปฏิบัติการเบิกจ่าย

## หน้า 2
๑. ให้ถือปฏิบัติตั้งแต่วันที่ ๑ ตุลาคม ๒๕๖๙
๒. ยกเลิกประกาศฉบับลงวันที่ ๑๕ มีนาคม ๒๕๖๗
Pages stay separate in the response, so a citation can name the page an answer came from.

The reads above are illustrations of shape, not captured responses. The OCR page carries the model's own witnessed read of a real specimen, with its capture date.

How ingestion works

Retrieval is only as good as what went into the index, and in Thailand a large share of what an assistant needs to know is a PDF that was scanned rather than typed. Extracting a flat string from those pages produces something an index will happily store and an assistant will quote badly, because every heading, every table, and every page boundary has been dissolved into it. The read that helps is the one that comes back with its structure intact.

  1. Read once, index the textSend each document in batches of up to 50 pages. Ingestion is a one-time cost per document, and the text is yours to store, chunk, and embed however your stack prefers.
  2. Chunk on structure, not on lengthSplit on the headings the read returned. A section-sized chunk keeps a rule and its exception together, which a fixed character window will separate sooner or later.
  3. Cite the pageKeep the page number the read came back with. An assistant that can name the page it answered from is one a reader can check.

What structure gives a chunker

the same page, two ways
flat text
  ...ครบหนึ่งปีมีสิทธิลาพักร้อนได้ปีละหกวันทำการ๓.๑
  การยื่นคำขอยื่นล่วงหน้าไม่น้อยกว่าเจ็ดวัน...
  → split on 500 characters, mid-sentence, mid-clause

markdown
  ## ๓. การลาพักร้อน
  ### ๓.๑ การยื่นคำขอ
  → split on headings, one section per chunk

Thai writes without spaces between words, so a flat extraction gives a splitter nothing to cut on except a character count. Headings and tables give it real boundaries.

An ingestion run, priced

WorkloadPagesCredits
One handbook (180 pages)1801,170
One request, at the 50-page ceiling50325
A 500-document corpus39,000 credits

At 12 pages a document and 6.5 credits a page, an ingestion budget is arithmetic you can do before writing any code.

What a citation looks like afterwards

one retrieved answer
question   ลาพักร้อนได้ปีละกี่วัน

chunk      คู่มือพนักงาน · ๓. การลาพักร้อน · หน้า 12
answer     หกวันทำการต่อปี สำหรับพนักงาน
           ที่ทำงานครบหนึ่งปี

the page number came from the read,
so a reader can open page 12 and check

The response keeps its pages separate, so the page number survives into the index and out again into the answer. An assistant that can name its page is one a reader can verify.

For developers

Markdown for a chunker that splits on headings; structured output when your pipeline would rather walk typed blocks than parse them back out.

# Encode without line wrapping: wrapped base64 breaks the JSON string.
DOC=$(base64 < invoice.pdf | tr -d '\n')
# --max-time covers a multi-page document; curl defaults to no limit.
curl -X POST https://api.paxalabs.com/v1/ocr \
  --max-time 300 \
  -H "Authorization: Bearer $PAXA_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"document\": \"$DOC\", \"model\": \"paxa-ocr-lite-v1\"}"

Full API reference

A language with no word spaces punishes naive chunking

Chunkers usually fall back on character counts, and in a language written with spaces that mostly lands between words. Thai has no spaces between words, so a fixed window cuts wherever it happens to land, including inside a word and inside a numeral. Structure is the way out: a read that returns headings, lists, and tables gives a splitter boundaries the document itself put there.

Common questions

Do you do the chunking and embedding too?
No. This is the read. What you index, how you chunk it, and which embedding model you use stay in your stack, where they belong.
Which output should a retrieval pipeline use?
Markdown, if your chunker splits on headings, which most do. Structured output if your pipeline would rather walk typed blocks (heading, paragraph, list, table, figure) than parse Markdown back apart.
What about documents that are already digital text?
If a PDF already carries a reliable text layer, extract it directly and save the credits. The read is for pages where that text does not exist or cannot be trusted.
Can the same pipeline handle documents in other languages?
The read handles the page it is given. If the corpus is multilingual and the readers are Thai, the translation API is the next call: 14 source languages into Thai, with the document's own context carried along.

Start with free credits

Sign in with Google, GitHub, or Hugging Face and spend 100 one-time free credits on your own text.