STICBOX OCR API
STICBOX OCR API ให้บริการแปลงเอกสารและรูปภาพเป็นข้อความ (Optical Character Recognition) ผ่าน REST API โดยรองรับหลายรูปแบบไฟล์และส่งคืนตำแหน่ง bounding box ของข้อความทุก paragraph
https://api.sticbox.com — ทุก endpoint ใช้ HTTPS เท่านั้น
รูปแบบ Response
ทุก response เป็น JSON และมี field success: true/false เสมอ เมื่อเกิดข้อผิดพลาด จะมี field error.code และ error.message
Sync vs Async
- รูปภาพ (PNG, JPG, TIFF, WebP): ประมวลผล synchronous — ได้ผลลัพธ์ทันทีใน HTTP 200
- PDF: ประมวลผล asynchronous — ได้
task_idใน HTTP 202 แล้ว poll สถานะด้วย GET /v1/ocr/status/{task_id}
รูปแบบไฟล์ที่รองรับ
| รูปแบบ | Mode | ขนาดสูงสุด | หมายเหตุ |
|---|---|---|---|
PDF | Async | 20 MB | แปลงทุกหน้าเป็นรูปภาพแล้ว OCR |
PNG | Sync | 20 MB | |
JPG / JPEG | Sync | 20 MB | |
TIFF / TIF | Sync | 20 MB | |
WebP | Sync | 20 MB | |
GIF | Sync | 20 MB | เฉพาะ frame แรก |
Authentication
ทุก request ต้องส่ง API Key ใน HTTP header X-API-Key
X-API-Key: sb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
sb_live_ ตามด้วย 40 ตัวอักษร
Quick Start
ตัวอย่างการส่งไฟล์ภาพเข้า OCR ด้วย cURL:
# OCR รูปภาพ (sync) curl -X POST https://api.sticbox.com/v1/ocr \ -H "X-API-Key: sb_live_xxxx" \ -F "file=@invoice.jpg" # OCR PDF (async) — ขั้นตอนที่ 1: ส่งไฟล์ curl -X POST https://api.sticbox.com/v1/ocr \ -H "X-API-Key: sb_live_xxxx" \ -F "file=@document.pdf" # ขั้นตอนที่ 2: ตรวจสอบสถานะ curl https://api.sticbox.com/v1/ocr/status/{task_id} \ -H "X-API-Key: sb_live_xxxx"
/v1/ocr
อัปโหลดไฟล์และทำ OCR — คืนข้อความที่แยกได้พร้อม bounding box ของแต่ละ paragraph และข้อมูลการเรียกเก็บเงิน
Request Headers
| Header | ประเภท | คำอธิบาย |
|---|---|---|
| X-API-Keyrequired | string | API Key ที่ได้จาก Dashboard |
| Content-Typerequired | string | multipart/form-data |
Request Body (multipart/form-data)
| Field | ประเภท | คำอธิบาย |
|---|---|---|
| filerequired | file | ไฟล์ที่ต้องการ OCR — PDF, PNG, JPG, JPEG, TIFF, WebP ขนาดสูงสุด 20 MB |
Response — 200 OK (รูปภาพ, sync)
{
"success": true,
"request_id": "OCR-20240608-A3F9C1B2",
"pages": 1,
"cost": 0.2000,
"processing_time": 1.23,
"text": "ใบเสร็จรับเงิน\nเลขที่ 1234/2024\n...",
"blocks": [
{
"page": 1,
"text": "ใบเสร็จรับเงิน",
"confidence": 0.9981,
"bounding_box": { "x": 48, "y": 32, "width": 220, "height": 28 }
}
]
}
Response — 202 Accepted (PDF, async)
{
"success": true,
"message": "File accepted for processing",
"task_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status_url": "/v1/ocr/status/a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
status_url ทุก 2-5 วินาที จนกว่าสถานะจะเป็น SUCCESS หรือ FAILURE
/v1/ocr/status/{task_id}
ตรวจสอบสถานะของ OCR task ที่ส่งมาจาก PDF upload (async mode)
Path Parameters
| Parameter | ประเภท | คำอธิบาย |
|---|---|---|
| task_idrequired | string | task_id ที่ได้รับจาก POST /v1/ocr (202 response) |
Response States
result มีข้อมูล OCR เหมือนกับ 200 response
error ระบุสาเหตุ
{ "success": true, "status": "PENDING" }
{
"success": true,
"status": "SUCCESS",
"result": { /* เหมือนกับ 200 response ของ POST /v1/ocr */
"text": "...", "pages": 5, "cost": 0.7500, "blocks": [...]
}
}
/v1/balance
ดูยอด credit คงเหลือในบัญชี ต้องการ JWT authentication (login ผ่าน Dashboard หรือใช้ Bearer token)
{ "success": true, "balance": 48.3250 }
/v1/transactions
ดูประวัติธุรกรรมของบัญชี
Query Parameters
| Parameter | ประเภท | Default | คำอธิบาย |
|---|---|---|---|
| pageoptional | integer | 1 | หน้าที่ต้องการ |
| per_pageoptional | integer | 20 | จำนวนรายการต่อหน้า (สูงสุด 100) |
{
"success": true,
"transactions": [
{ "type": "DEBIT", "amount": "0.2000", "balance_after": "48.3250",
"description": "OCR - 1 page(s) - PNG", "reference_id": "OCR-20240608-A3F9C1B2",
"created_at": "2024-06-08T13:45:00" }
],
"pagination": { "page": 1, "per_page": 20, "total": 42 }
}
/v1/usage/monthly
ดูสถิติการใช้งานรายเดือน
Query Parameters
| Parameter | ประเภท | คำอธิบาย |
|---|---|---|
| yearrequired | integer | ปี เช่น 2024 |
| monthrequired | integer | เดือน 1–12 |
{
"success": true,
"usage": {
"total_requests": 128, "total_pages": 312,
"total_cost": 62.4000, "avg_response_time_ms": 1420,
"daily": [
{ "date": "2024-06-08", "requests": 12, "pages": 28, "cost": 5.6000 }
]
}
}
รูปแบบ OCR Response
เมื่อ OCR สำเร็จ (200 สำหรับรูปภาพ หรือ result ใน 200 ของ status endpoint) fields มีดังนี้:
true เสมอเมื่อสำเร็จ
OCR-20240608-A3F9C1B2
Bounding Boxes
field blocks ประกอบด้วย array ของ paragraph แต่ละอันมีตำแหน่งพิกเซลบนรูปภาพ ช่วยให้ระบุตำแหน่งของข้อความในเอกสารได้แม่นยำ
0.9981
ตัวอย่าง block
{
"page": 1,
"text": "ใบเสร็จรับเงิน",
"confidence": 0.9981,
"bounding_box": {
"x": 48,
"y": 32,
"width": 220,
"height": 28
}
}
Error Codes
เมื่อเกิดข้อผิดพลาด response จะมีรูปแบบ:
{ "success": false, "error": { "code": 401, "message": "Invalid or inactive API key" } }
| HTTP Status | สาเหตุ | วิธีแก้ไข |
|---|---|---|
400 Bad Request |
ไม่มีไฟล์, ชื่อไฟล์ว่าง, หรือรูปแบบไฟล์ไม่ถูกต้อง | ตรวจสอบ field file และนามสกุลไฟล์ |
401 Unauthorized |
ไม่มี API Key หรือ Key ไม่ถูกต้อง/ถูกยกเลิก | ตรวจสอบ header X-API-Key |
402 Payment Required |
ยอด credit ไม่พอสำหรับการประมวลผล | เติม credit ที่ Dashboard → Wallet |
413 Request Too Large |
ไฟล์ใหญ่เกิน 20 MB | ลดขนาดไฟล์ก่อนส่ง |
415 Unsupported Media Type |
รูปแบบไฟล์ไม่รองรับ หรือ magic bytes ไม่ตรงกับนามสกุล | ใช้ไฟล์ที่รองรับและไม่ถูกแก้ไข header |
429 Too Many Requests |
เกิน rate limit (60 req/min หรือ 1000 req/day) | ลด request rate หรือรอ 60 วินาที |
503 Service Unavailable |
ระบบอยู่ในโหมด Maintenance | ตรวจสอบสถานะที่ api.sticbox.com/status |
500 Internal Server Error |
ข้อผิดพลาดภายในระบบ | ลองอีกครั้ง — หากปัญหายังคงอยู่ แจ้ง support |
Rate Limits & Quota
| ประเภท | ขีดจำกัด | หมายเหตุ |
|---|---|---|
| Rate limit | 60 requests / นาที | ต่อ API Key |
| Daily quota | 1,000 requests / วัน | รีเซ็ตเที่ยงคืน UTC |
| Monthly quota | 10,000 requests / เดือน | |
| Max file size | 20 MB | ต่อไฟล์ |
เมื่อเกิน rate limit จะได้รับ 429 Too Many Requests พร้อม header Retry-After
ราคา
ตัวอย่างโค้ด
ตัวอย่างการส่ง OCR request พร้อม poll สถานะสำหรับ PDF:
import requests, time API_KEY = "sb_live_xxxx" BASE_URL = "https://api.sticbox.com" def ocr_file(file_path): headers = {"X-API-Key": API_KEY} with open(file_path, "rb") as f: res = requests.post( f"{BASE_URL}/v1/ocr", headers=headers, files={"file": f}, ) data = res.json() # รูปภาพ — ได้ผลทันที if res.status_code == 200: return data # PDF — poll สถานะ if res.status_code == 202: status_url = BASE_URL + data["status_url"] while True: r = requests.get(status_url, headers=headers) d = r.json() if d["status"] == "SUCCESS": return d["result"] if d["status"] == "FAILURE": raise RuntimeError(d.get("error")) time.sleep(2) raise RuntimeError(data.get("error", {}).get("message")) # ใช้งาน result = ocr_file("invoice.pdf") print(result["text"]) # แสดง bounding boxes for block in result["blocks"]: print(f"p{block['page']} {block['bounding_box']}: {block['text'][:30]}")
import fs from 'fs'; import FormData from 'form-data'; import fetch from 'node-fetch'; const API_KEY = 'sb_live_xxxx'; const BASE_URL = 'https://api.sticbox.com'; async function ocrFile(filePath) { const form = new FormData(); form.append('file', fs.createReadStream(filePath)); const headers = { ...form.getHeaders(), 'X-API-Key': API_KEY }; const res = await fetch(`${BASE_URL}/v1/ocr`, { method: 'POST', headers, body: form }); const data = await res.json(); // รูปภาพ — sync if (res.status === 200) return data; // PDF — async poll if (res.status === 202) { const statusUrl = BASE_URL + data.status_url; while (true) { const r = await fetch(statusUrl, { headers: { 'X-API-Key': API_KEY } }); const d = await r.json(); if (d.status === 'SUCCESS') return d.result; if (d.status === 'FAILURE') throw new Error(d.error); await new Promise(r => setTimeout(r, 2000)); } } throw new Error(data.error?.message); } // ใช้งาน const result = await ocrFile('invoice.pdf'); console.log(result.text);
<?php $apiKey = 'sb_live_xxxx'; $baseUrl = 'https://api.sticbox.com'; function ocrFile($filePath, $apiKey, $baseUrl) { $ch = curl_init($baseUrl . '/v1/ocr'); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["X-API-Key: $apiKey"], CURLOPT_POSTFIELDS => ['file' => new CURLFile($filePath)], ]); $body = json_decode(curl_exec($ch), true); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); // รูปภาพ if ($code === 200) return $body; // PDF — poll if ($code === 202) { $statusUrl = $baseUrl . $body['status_url']; while (true) { sleep(2); $r = json_decode(file_get_contents( $statusUrl, false, stream_context_create(['http' => ['header' => "X-API-Key: $apiKey"]]) ), true); if ($r['status'] === 'SUCCESS') return $r['result']; if ($r['status'] === 'FAILURE') throw new Exception($r['error']); } } throw new Exception($body['error']['message'] ?? 'Unknown error'); } $result = ocrFile('invoice.pdf', $apiKey, $baseUrl); echo $result['text'];
# OCR รูปภาพ (sync) curl -X POST https://api.sticbox.com/v1/ocr \ -H "X-API-Key: sb_live_xxxx" \ -F "file=@invoice.jpg" | python3 -m json.tool # OCR PDF (ขั้นตอนที่ 1: ส่งไฟล์) curl -X POST https://api.sticbox.com/v1/ocr \ -H "X-API-Key: sb_live_xxxx" \ -F "file=@document.pdf" # ได้รับ: {"task_id": "...", "status_url": "/v1/ocr/status/..."} # OCR PDF (ขั้นตอนที่ 2: ตรวจสอบสถานะ) curl https://api.sticbox.com/v1/ocr/status/TASK_ID \ -H "X-API-Key: sb_live_xxxx" # ดู credit คงเหลือ (ต้องใช้ JWT Bearer token) curl https://api.sticbox.com/v1/balance \ -H "Authorization: Bearer YOUR_JWT_TOKEN"