Paxa Labs

อ่านเอกสารด้วย OCR

ปลายทาง OCR อ่านไฟล์ PDF และรูปภาพ แล้วคืนข้อความเป็น Markdown หรือบล็อกโครงสร้าง คิดเครดิตเป็นรายหน้า ตัดเครดิตก่อนอ่านและคืนให้อัตโนมัติเมื่ออ่านไม่สำเร็จ

ดูเป็น Markdown

POST /v1/ocr อ่านไฟล์ PDF, PNG, JPEG หรือ WebP แล้วคืนข้อความในไฟล์ ส่งไฟล์เป็น base64 ในฟิลด์ document พร้อมรหัสโมเดล paxa-ocr-lite-v1 คำตอบมีหนึ่งรายการต่อหนึ่งหน้า เช่นเดียวกับทุกปลายทาง ระบบตัดเครดิตก่อนประมวลผลและคืนให้อัตโนมัติเมื่อประมวลผลไม่สำเร็จ (เครดิต)

# 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\"}"
Response
{
  "pages": [
    {
      "page": 1,
      "markdown": "# ใบเสร็จรับเงิน\n\nร้านข้าวแกงบ้านสวน สาขาสีลม\n\n| รายการ | จำนวน | ราคา |\n| --- | --- | --- |\n| ข้าวแกงเขียวหวานไก่ | 1 | 60 |\n| น้ำเปล่า | 1 | 10 |\n\nรวมทั้งสิ้น 70 บาท"
    }
  ],
  "usage": {
    "pages": 1,
    "credits": 6.5
  }
}

การคิดเครดิต#

แต่ละหน้าคิด 6.5 เครดิตเท่ากัน ไม่ว่าบนหน้านั้นจะมีอะไร หนึ่งหน้าคือหนึ่งหน้าของ PDF หรือรูปภาพหนึ่งไฟล์ ระบบอ่านจำนวนหน้าจากตัวเอกสารก่อนตัดเครดิต จึงรู้ค่าใช้จ่ายก่อนเริ่มอ่านเสมอ

ยอดที่ตัดรายงานอยู่ใน usage.credits ของเนื้อหาคำตอบเท่านั้น ปลายทางนี้ไม่ส่งเฮดเดอร์ x-credits-charged คำตอบที่เร็วและช้าจึงมีรูปแบบเดียวกัน เมื่ออ่านไม่สำเร็จหลังตัดเครดิต ระบบคืนเครดิตอัตโนมัติและตอบ 502 provider_error

เอกสารและรูปแบบไฟล์#

ฟิลด์ document คือไบต์ของไฟล์ในรูป base64 ระบบอ่านสี่รูปแบบ ได้แก่ PDF, PNG, JPEG และ WebP โดยตรวจรูปแบบจากไบต์ของไฟล์เอง และรูปภาพนับเป็นหนึ่งหน้าเสมอ ไฟล์ที่อ่านเป็นสี่รูปแบบนี้ไม่ได้จะตอบ 400 document_invalid ส่วน PDF ที่ต้องใช้รหัสผ่านในการเปิดจะตอบ 400 document_password_required ทั้งนี้ PDF ที่เข้ารหัสเพื่อจำกัดสิทธิ์อย่างเดียว ซึ่งเปิดได้โดยไม่ต้องกรอกรหัสผ่าน ระบบอ่านได้ตามปกติ และทุกกรณีข้างต้นไม่ตัดเครดิต

base64 ทำให้ขนาดข้อมูลโตขึ้นราวหนึ่งในสาม โปรดเผื่อขีดจำกัดขนาดคำขอของไคลเอนต์เมื่อส่งไฟล์สแกนขนาดใหญ่ และถอดรหัสผ่านของ PDF ก่อนเข้ารหัส base64

ขีดจำกัดจำนวนหน้าและขนาด#

หนึ่งคำขออ่านได้ไม่เกิน 50 หน้า เอกสารที่ยาวกว่านั้นตอบ 400 too_many_pages ไฟล์หลังถอดรหัส base64 ต้องไม่เกิน 10 MiB ไฟล์ที่ใหญ่กว่าตอบ 413 document_too_large การปฏิเสธทั้งสองแบบไม่ตัดเครดิต เอกสารที่ใหญ่กว่านี้ให้แบ่งส่งเป็นหลายคำขอ

เลือกรูปแบบผลลัพธ์#

ฟิลด์ output เลือกรูปแบบผลลัพธ์ ค่าเริ่มต้นคือ "markdown" ทั้งสองรูปแบบให้เนื้อหาการอ่านเดียวกัน ต่างกันที่ปริมาณโครงสร้างที่ติดมาด้วย

Markdown#

ค่าเริ่มต้นคืนแต่ละหน้าเป็น Markdown แบบ GitHub ตามลำดับการอ่าน หัวเรื่อง รายการ และตารางมาเป็นโครงสร้าง Markdown จึงนำไปวางในวิกิ พรอมป์ต หรือดัชนีค้นหาได้ทันที ต่อแต่ละหน้าด้วยบรรทัดว่างเพื่อประกอบเป็นเอกสารเต็ม

บล็อกโครงสร้าง#

ตั้ง output เป็น "structured" แล้วแต่ละหน้าจะมาเป็นบล็อกแยกตามชนิด เรียงตามลำดับการอ่าน แต่ละบล็อกบอกชนิดและเนื้อหาในฟิลด์ที่ระบุชนิดไว้ชัดเจน ไปป์ไลน์จึงแยกหัวเรื่อง ตาราง และย่อหน้าได้โดยไม่ต้องแกะ Markdown เอง

บล็อกฟิลด์ความหมาย
headingtext, levelหัวเรื่องของส่วน level เริ่มที่ 1 สำหรับหัวเรื่องเด่นที่สุด
paragraphtextย่อหน้าข้อความ
listitemsรายการเรียงตามลำดับ
tablerowsเซลล์ของตารางเป็นแถวของค่าคอลัมน์ แถวแรกมาก่อน
figuretextรูปภาพหรือแผนภูมิ text คือคำบรรยายหรือป้ายกำกับใกล้เคียง
curl
DOC=$(base64 < invoice.pdf | tr -d '\n')
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\", \"output\": \"structured\"}"
Response
{
  "pages": [
    {
      "page": 1,
      "blocks": [
        {
          "type": "heading",
          "level": 1,
          "text": "ใบเสร็จรับเงิน"
        },
        {
          "type": "paragraph",
          "text": "ร้านข้าวแกงบ้านสวน สาขาสีลม"
        },
        {
          "type": "table",
          "rows": [
            [
              "รายการ",
              "จำนวน",
              "ราคา"
            ],
            [
              "ข้าวแกงเขียวหวานไก่",
              "1",
              "60"
            ],
            [
              "น้ำเปล่า",
              "1",
              "10"
            ]
          ]
        },
        {
          "type": "paragraph",
          "text": "รวมทั้งสิ้น 70 บาท"
        }
      ]
    }
  ],
  "usage": {
    "pages": 1,
    "credits": 6.5
  }
}

ความเสถียรและการส่งซ้ำ#

คำตอบเป็น JSON ก้อนเดียว เอกสารหลายหน้าอาจใช้เวลาหลายนาที จึงควรตั้งไทม์เอาต์ของไคลเอนต์ให้เผื่อไว้ ตัวอย่างด้านบนเผื่อ 300 วินาที

คำขอที่ใช้เวลานานพอจะเขียนส่วนหัวของคำตอบออกไปก่อนที่จะรู้ผลลัพธ์ เพื่อไม่ให้พร็อกซีระหว่างทางตัดการเชื่อมต่อที่ยังทำงานอยู่ คำตอบลักษณะนี้มีสถานะ 200 เสมอ และรายงานความล้มเหลวไว้ในเนื้อคำตอบด้วยเอกสารปัญหาชุดเดียวกับที่คำขอล้มเหลวได้รับ คือมี title และ status แทนที่ตำแหน่งของ pages เอกสารยาวคือกรณีที่ไปถึงจุดนี้ ให้ถือว่าเนื้อคำตอบที่มี title คือข้อผิดพลาดตามที่ระบุ ส่วนเอกสารที่สั้นกว่านั้นแจ้งสถานะไว้ที่บรรทัดสถานะเสมอ

ส่งซ้ำได้อย่างปลอดภัยด้วย Idempotency-Key การส่งซ้ำของคำขอที่ส่งมอบแล้วจะได้ผลการอ่านเดิมโดยไม่ตัดเครดิตซ้ำ เมื่ออ่านไม่สำเร็จ ระบบคืนเครดิตให้ และคำขอใหม่ต้องใช้คีย์ใหม่