สกัดฟิลด์จากเอกสาร
Document Extraction อ่านไฟล์ PDF หรือรูปภาพ แล้วเติมค่าลงสคีมาของฟิลด์ที่คุณกำหนดชนิดไว้ แต่ละค่าคือข้อความที่พิมพ์อยู่ในเอกสาร หรือ null พร้อมเหตุผล คิดเครดิตรายหน้าตามขนาดของสคีมา ตัดก่อนอ่านและคืนให้อัตโนมัติเมื่อล้มเหลว
POST /v1/extract อ่านไฟล์ PDF, PNG, JPEG หรือ WebP แล้วเติมค่าลงสคีมาที่คุณส่งมา ส่งไฟล์เป็น base64 ในฟิลด์ document พร้อมรหัสโมเดล paxa-doc-extract-v1 และ schema ของฟิลด์ที่ระบุชนิด ทุกค่าที่ส่งกลับคือข้อความที่พิมพ์อยู่ในเอกสาร อ่านตามชนิดของฟิลด์ หรือเป็น null พร้อมเหตุผล ระบบไม่อนุมานและไม่ค้นหาข้อมูลจากที่อื่น เช่นเดียวกับทุกปลายทาง ระบบตัดเครดิตก่อนประมวลผลและคืนให้อัตโนมัติเมื่อประมวลผลไม่สำเร็จ (เครดิต)
# 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/extract \
--max-time 300 \
-H "Authorization: Bearer $PAXA_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<EOF
{
"document": "$DOC",
"model": "paxa-doc-extract-v1",
"schema": {
"fields": {
"seller": {
"type": "string",
"required": true,
"description": "The shop name as printed at the top"
},
"total": {
"type": "number",
"required": true
},
"issued_on": {
"type": "date"
},
"items": {
"type": "array",
"max_items": 5,
"items": {
"type": "object",
"fields": {
"name": {
"type": "string"
},
"amount": {
"type": "number"
}
}
}
}
}
}
}
EOFimport { readFile } from "node:fs/promises";
const document = (await readFile("invoice.pdf")).toString("base64");
const schema = {
"fields": {
"seller": {
"type": "string",
"required": true,
"description": "The shop name as printed at the top"
},
"total": {
"type": "number",
"required": true
},
"issued_on": {
"type": "date"
},
"items": {
"type": "array",
"max_items": 5,
"items": {
"type": "object",
"fields": {
"name": {
"type": "string"
},
"amount": {
"type": "number"
}
}
}
}
}
};
const response = await fetch("https://api.paxalabs.com/v1/extract", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PAXA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ document, model: "paxa-doc-extract-v1", schema }),
// A multi-page document can run for minutes; give it room.
signal: AbortSignal.timeout(300_000),
});
if (!response.ok) throw new Error(`Extraction failed: ${response.status}`);
const { status, fields, missing, usage } = await response.json();
console.log(status, fields.seller, fields.total, missing);
console.log(`${usage.leaves} leaves, ${usage.credits} credits`);import base64
import os
import requests
with open("invoice.pdf", "rb") as file:
document = base64.b64encode(file.read()).decode()
schema = {
"fields": {
"seller": {
"type": "string",
"required": True,
"description": "The shop name as printed at the top",
},
"total": {
"type": "number",
"required": True,
},
"issued_on": {
"type": "date",
},
"items": {
"type": "array",
"max_items": 5,
"items": {
"type": "object",
"fields": {
"name": {
"type": "string",
},
"amount": {
"type": "number",
},
},
},
},
},
}
response = requests.post(
"https://api.paxalabs.com/v1/extract",
headers={"Authorization": f"Bearer {os.environ['PAXA_API_KEY']}"},
json={"document": document, "model": "paxa-doc-extract-v1", "schema": schema},
# A multi-page document can run for minutes; give it room.
timeout=300,
)
response.raise_for_status()
body = response.json()
print(body["status"], body["fields"]["seller"], body["fields"]["total"])
print(body["usage"]["leaves"], "leaves,", body["usage"]["credits"], "credits"){
"status": "complete",
"fields": {
"seller": "ร้านข้าวแกงบ้านสวน สาขาสีลม",
"total": 70,
"issued_on": null,
"items": [
{
"name": "ข้าวแกงเขียวหวานไก่",
"amount": 60
},
{
"name": "น้ำเปล่า",
"amount": 10
}
]
},
"missing": [],
"unverified": [],
"truncated": [],
"assumed": [],
"usage": {
"pages": 1,
"leaves": 13,
"credits": 13
}
}การคิดเครดิต#
หนึ่งหน้าคิด 13 เครดิตเมื่อสคีมานับได้ไม่เกิน 50 ฟิลด์ย่อย และ 19.5 เครดิตเมื่อนับได้ 51 ถึง 100 ฟิลด์ย่อย คิดเป็นสองเท่าและสามเท่าของอัตรา OCR ที่ 6.5 เครดิต เพราะรวมการอ่านเอกสารไว้แล้ว หนึ่งหน้าคือหนึ่งหน้าของ PDF หรือรูปภาพหนึ่งไฟล์ ระบบอ่านจำนวนหน้าจากเอกสารและนับฟิลด์ย่อยจากสคีมาก่อนตัดเครดิตทั้งคู่ จึงรู้ค่าใช้จ่ายก่อนเริ่มอ่านเสมอ หลักฐานและข้อความที่อ่านได้ไม่เปลี่ยนค่าใช้จ่าย
จำนวนฟิลด์ย่อยคือฟิลด์ย่อยทุกตัวนับหนึ่งครั้ง บวกฟิลด์ย่อยในอาร์เรย์นับหนึ่งครั้งต่อหนึ่งสมาชิกที่อาร์เรย์กำหนดขนาดไว้ สคีมาที่มีฟิลด์ส่วนหัว 15 ฟิลด์ กับสามฟิลด์ต่อรายการสินค้าสูงสุดสิบรายการ นับได้ 45 ฟิลด์ย่อย สคีมาเดียวกันที่ยี่สิบรายการนับได้ 75 คำตอบรายงานจำนวนนี้ใน usage.leaves คู่กับ usage.pages และ usage.credits
ยอดที่ตัดรายงานอยู่ใน usage.credits ของเนื้อหาคำตอบเท่านั้น ปลายทางนี้ไม่ส่งเฮดเดอร์ x-credits-charged เมื่อการสกัดล้มเหลวหลังตัดเครดิต ระบบคืนเครดิตอัตโนมัติและตอบ 502 provider_error เอกสารที่ไม่มีฟิลด์ใดเลยถือเป็นการส่งมอบผลลัพธ์ที่ทุกฟิลด์เป็น null และคิดเครดิตตามปกติ
เขียนสคีมา#
schema เป็นออบเจกต์ที่มีคีย์เดียวคือ fields ซึ่งจับคู่ชื่อฟิลด์กับนิยามของมัน นิยามหนึ่งมี type แฟล็ก required (ไม่บังคับ) description ยาวไม่เกิน 200 ตัวอักษร (ไม่บังคับ) และคีย์ที่ชนิดนั้นรองรับ description คือข้อความเดียวของคุณที่โมเดลอ่าน จึงเป็นที่อธิบายความหมายของฟิลด์ เช่น "ชื่อผู้ขายตามที่พิมพ์ด้านบน" ชื่อฟิลด์ยาว 1 ถึง 64 ตัวอักษร ใช้ได้เฉพาะตัวอักษรละติน ตัวเลข และขีดล่าง
คอนเทนเนอร์สองแบบใช้ซ้อนฟิลด์ object มี fields ของตัวเอง array มี items ที่เป็นฟิลด์ย่อยหรือออบเจกต์ และต้องมี max_items ตั้งแต่ 1 ถึง 200 ซ้อนคอนเทนเนอร์ใต้รากได้ไม่เกิน 3 ชั้น ดังนั้น items[].tax.rate ใช้ได้ แต่ชั้นที่สี่จะถูกปฏิเสธ อาร์เรย์เก็บฟิลด์ย่อยหรือออบเจกต์ อาร์เรย์ซ้อนอาร์เรย์จะถูกปฏิเสธ
| ชนิด | คีย์ | ค่าที่ส่งกลับ |
|---|---|---|
| string | pattern, min_length, max_length | ข้อความตามที่พิมพ์ คัดลอกมาตรง ๆ ใช้กับรหัสที่อาจเริ่มด้วยเลขศูนย์ |
| integer | min, max | จำนวนเต็มที่พิมพ์อยู่ในช่วงข้อความ |
| number | min, max, decimals | จำนวนเงินหรือตัวเลขที่พิมพ์อยู่ในช่วงข้อความ |
| date | min, max, not_future, year | วันที่แบบ ISO YYYY-MM-DD อ่านจากช่วงข้อความตามธรรมเนียมเอกสารไทย วันมาก่อน ปีเป็น พ.ศ. หรือ ค.ศ. ก็ได้ |
| time | เวลาแบบ 24 ชั่วโมง HH:MM รวมวินาทีเมื่อพิมพ์ไว้ | |
| enum | values (1 ถึง 50), aliases, strict | ค่าหนึ่งใน values แปลงจากช่วงข้อความที่พิมพ์ หรือเลือกเมื่อไม่มีสิ่งใดพิมพ์ไว้ |
| id | digits, check | ตัวเลข ตรวจจำนวนหลักและเลขตรวจสอบแล้ว |
| thai_id | format | เลข 13 หลักของเลขประจำตัวประชาชน นิติบุคคล หรือผู้เสียภาษี ตรวจเลขตรวจสอบแล้ว |
| ที่อยู่อีเมล ส่วนโดเมนเป็นตัวพิมพ์เล็ก | ||
| phone | format | เบอร์โทรไทยแบบ E.164 หรือแบบในประเทศ |
| postal_code | รหัสไปรษณีย์ห้าหลักที่ใช้อยู่ในประเทศไทย | |
| province | format | หนึ่งใน 77 จังหวัดของไทย |
| bank | format | ธนาคารในประเทศไทย |
| insurer | format | บริษัทประกันที่ได้รับใบอนุญาตในประเทศไทย |
| card_scheme | format | เครือข่ายบัตร เช่น Visa, Mastercard, JCB หรือ UnionPay |
| payment_method | format | เงินสด บัตร โอน พร้อมเพย์ หรือกระเป๋าเงิน |
| legal_form | format | รูปแบบนิติบุคคลไทย เช่น บจก., บมจ., หจก. หรือ ร้าน |
| currency | format | รหัส ISO 4217 จากสัญลักษณ์หรือชื่อสกุลเงิน |
| unit | format | หน่วยนับจากรายการสินค้า |
| amount_words | จำนวนเงินที่เขียนเป็นตัวหนังสือ ไทยหรือภาษาอื่น ส่งกลับเป็นตัวเลข | |
| object | fields | ออบเจกต์ของฟิลด์ภายใน |
| array | items, max_items | สมาชิก max_items ตัวแรกที่พิมพ์ไว้ ตามลำดับการอ่าน |
เงื่อนไขของฟิลด์#
เงื่อนไขบอกว่าฟิลด์นั้นคืออะไร ค่าที่พิมพ์ไว้แต่ผิดเงื่อนไขจะส่งกลับเป็น null พร้อมเหตุผล และช่วงข้อความยังอยู่ใน evidence เมื่อคุณขอไว้ จำกัด number ด้วย min max และ decimals กำหนดรูป string ด้วย pattern ซึ่งเป็น regular expression ยาวไม่เกิน 200 ตัวอักษรที่ต้องตรงกับค่าทั้งค่า และด้วย min_length กับ max_length จำกัด date ด้วย min และ max เป็นวันที่แบบ ISO และด้วย not_future ซึ่งเทียบกับวันนี้ตามเวลาประเทศไทย id รับ digits เป็นจำนวนหลักหรือคู่ [min, max] ตั้งแต่ 1 ถึง 64 และ check เป็น none, thai_mod11 หรือ luhn การตรวจสอบจับตัวเลขที่ผิดได้แต่จะไม่แก้ให้
year กำหนดว่า date อ่านปีสองหลักอย่างไร ค่าเริ่มต้นคือ recent ซึ่งเลือกศักราชที่ทำให้วันที่ตกในอดีตไม่นานนี้ เลข 69 บนใบเสร็จจึงเป็น พ.ศ. 2569 ส่วน strict จะส่งปีกลับเมื่อมีศักราชเดียวที่เข้ากันได้ be และ ce ระบุศักราชที่คุณทราบอยู่แล้ว ไม่ว่าใช้กฎใด ปีสองหลักทุกตัวที่อ่านจะถูกระบุใน assumed ของคำตอบพร้อมตัวเลขตามที่พิมพ์
enum และชุดค่าในตัว#
enum ระบุ values ของตัวเอง และอาจมี aliases ซึ่งจับคู่ค่าหนึ่งกับการสะกดแบบอื่นได้ไม่เกิน 20 แบบ เช่น "bangkok" กับ กรุงเทพมหานคร กทม. และ BKK ระบบเทียบช่วงข้อความที่พิมพ์กับชุดค่า ค่าที่ตรงทั้งหมดโดยไม่แยกตัวพิมพ์เล็กใหญ่ชนะก่อน ถัดมาคือช่วงข้อความที่มีการสะกดยาวตั้งแต่สี่ตัวอักษรของค่าเพียงค่าเดียว ถัดมาคือช่วงข้อความที่ต่างจากค่าเดียวเพียงหนึ่งตัวอักษร โดยไม่มีค่าอื่นอยู่ในระยะสองตัวอักษร กรณีเสมอกันจะไม่เลือกค่าใด และฟิลด์เป็น null พร้อม ambiguous_match ตั้ง strict เป็น true เพื่อรับเฉพาะค่าที่ตรงทั้งหมด enum ยังเป็นฟิลด์เดียวที่อาจเป็นการตัดสิน เช่น ประเภทของเอกสารซึ่งไม่ได้พิมพ์ไว้ที่ใด จะถูกเลือกจากค่าที่ระบุ
ชนิดชุดค่าปิด ได้แก่ province, bank, insurer, postal_code, card_scheme, payment_method, legal_form, currency และ unit คือ enum ที่บริการมีตารางค่าให้เอง รวมถึงตัวย่อที่เอกสารพิมพ์ ชื่อเดิมของธนาคารที่รวมกิจการแล้วแปลงเป็นธนาคารปัจจุบัน สัญลักษณ์สกุลเงินที่กำกวมอย่าง $ ใช้กับหลายสกุลเงิน จึงส่งกลับเป็นสัญลักษณ์นั้นเอง format เลือกรูปแบบที่ส่งกลับ และเป็นรูปแบบที่ไม่สูญเสียข้อมูลเสมอ
| ชนิด | รูปแบบ ค่าเริ่มต้นมาก่อน |
|---|---|
| province | name_th, name_en, code (10), iso (TH-10) |
| bank | short (KBANK), code (004), name_th, name_en |
| insurer | short, code (2037), name_th, name_en |
| thai_id | digits (1234567890121), grouped (1-2345-67890-12-1) |
| phone | e164 (+66812345678), national (0812345678) |
| card_scheme | code (MASTERCARD), name |
| payment_method, legal_form, currency, unit | code, name_th, name_en |
การปฏิเสธสคีมา#
สคีมาที่อยู่นอกภาษาสคีมาตอบ 400 schema_invalid ก่อนอ่านเอกสาร โดยไม่คิดเครดิต เนื้อหาปัญหามีสองฟิลด์เพิ่มจากรูปแบบขั้นต่ำ path ระบุฟิลด์ที่มีปัญหาแบบจุด (ว่างสำหรับราก) และ reason เป็นค่าหนึ่งจากตารางด้านล่าง สคีมาที่ใหญ่กว่า 128 KB ในรูป JSON ตอบโค้ดเดียวกันพร้อมเหตุผล too_large เหตุผลคงเป็นภาษาอังกฤษ เพราะเป็นค่าบนสาย
| reason | Meaning |
|---|---|
| not_an_object | The schema, or the field definition at this path, is not a JSON object. |
| unknown_key | A key at this path is not part of the dialect. A field takes type, required, description, and the keys its type lists. |
| missing_fields | The object at this path has no fields key. |
| invalid_fields | The fields key at this path is not an object with at least one field. |
| invalid_name | The field name at this path is not 1 to 64 characters of letters, digits, and underscores. |
| missing_type | The field at this path has no type. |
| unknown_type | The type at this path is not one of the dialect's types. |
| too_deep | The field at this path sits under more than 3 containers. |
| missing_items | The array at this path has no items definition. |
| nested_array | The array at this path holds arrays. An array holds leaves or objects. |
| invalid_max_items | The array at this path has no max_items, or one outside 1 to 200. |
| too_many_leaves | The schema counts more leaf fields than the model's ceiling, arrays counted once per element they are sized for. |
| invalid_flag | The required, strict, or not_future key at this path is not a boolean. |
| invalid_format | The format at this path is not one the type offers. |
| invalid_bound | A min or max at this path is not a number, or not an ISO date on a date field. |
| min_exceeds_max | The min at this path is greater than its max. |
| invalid_count | A decimals, min_length, or max_length at this path is not a whole number in range. |
| invalid_pattern | The pattern at this path is not a valid regular expression of up to 200 characters. |
| invalid_digits | The digits at this path is not a count from 1 to 64, or a [min, max] pair in that range. |
| invalid_check | The check at this path is not none, thai_mod11, or luhn. |
| invalid_year | The year at this path is not recent, strict, be, or ce. |
| invalid_description | The description at this path is not a string of up to 200 characters. |
| invalid_enum_values | The values at this path is not a list of 1 to 50 strings. |
| duplicate_enum_value | Two values at this path are the same once case is folded. |
| invalid_aliases | The aliases at this path is not a map from a listed value to up to 20 spellings. |
| conflicting_alias | An alias at this path spells a listed value, or could name two of them. |
| too_large | The schema is larger than 131,072 bytes as JSON. |
อ่านคำตอบ#
fields คือต้นไม้ของสคีมาที่เติมค่าธรรมดา และเป็น null ตรงที่อ่านค่าไม่ได้ status เป็น "complete" เมื่อฟิลด์ที่ required ทุกตัวมีค่า และเป็น "incomplete" ในกรณีอื่น ค่านี้คำนวณจากฟิลด์เท่านั้น ไฟล์ที่ไม่ใช่เอกสารตามที่สคีมาบรรยายจะกลับมาเป็น incomplete โดยฟิลด์ required ส่วนใหญ่อยู่ใน missing ซึ่งเป็นวิธีตรวจจับเอกสารผิดประเภท คำตอบไม่มีคะแนนความมั่นใจ เพราะการคัดลอกตัวเลขที่อ่านผิดมาอย่างซื่อตรงเป็นสิ่งที่คะแนนใดมองไม่เห็น ชนิดที่มีเลขตรวจสอบคือวิธีจับกรณีนั้น
missingระบุฟิลด์ required ทุกตัวที่เป็น null ไม่ว่าด้วยเหตุผลใดunverifiedระบุทุกฟิลด์ที่ช่วงข้อความอ่านเป็นชนิดของฟิลด์ไม่ได้ หรือที่ข้อความที่อ่านได้ไม่มีค่านั้น พร้อมreasonจากตารางด้านล่าง ฟิลด์เหล่านี้เป็น nulltruncatedระบุอาร์เรย์ทุกตัวที่เอกสารมีสมาชิกมากกว่าขนาดที่กำหนด สมาชิกmax_itemsตัวแรกอยู่ในfieldsตามลำดับการอ่าน เพิ่มmax_itemsเพื่ออ่านส่วนที่เหลือassumedระบุวันที่ทุกตัวที่พิมพ์ปีเป็นสองหลัก พร้อมprintedและread_asคีย์นี้มีเสมอ และว่างเมื่อไม่มีการตีความevidenceเมื่อinclude_evidenceเป็น true จับคู่พาธของแต่ละฟิลด์กับช่วงข้อความที่พิมพ์ซึ่งใช้อ่านค่า ไม่ว่าจะอ่านค่าได้หรือไม่pagesเมื่อinclude_pagesเป็น true คือข้อความที่อ่านได้จากแต่ละหน้าในรูป Markdown เป็นการอ่านเดียวกับที่ POST /v1/ocr คืนให้ ฟิลด์ทั้งหมดสกัดมาจากข้อความนี้
พาธเขียนแบบจุด และสมาชิกอาร์เรย์ระบุดัชนี เช่น "items[2].amount" เหตุผลใน unverified มีดังนี้
| reason | Meaning |
|---|---|
| not_in_readout | The value does not appear in the text read from the document. |
| not_as_printed | The value differs from the printed span it was read from. |
| no_number | The span carries no number. |
| ambiguous_number | The span carries more than one number. |
| not_an_integer | The number in the span is not whole. |
| no_date | The span carries no date. |
| ambiguous_date | The span's date reads two ways, or its two-digit year fits no era under the strict rule. |
| no_time | The span carries no time of day. |
| ambiguous_time | The span carries more than one time. |
| not_an_enum_value | The span resolves to none of the listed values. |
| ambiguous_match | The span resolves to two listed values equally well. |
| not_13_digits | The identifier does not carry exactly thirteen digits. |
| bad_checksum | The identifier's check digit does not hold. |
| wrong_digit_count | The identifier's digit count is outside the field's digits. |
| not_an_email | The span is not an email address. |
| not_a_phone | The span is not a Thai telephone number. |
| not_a_postal_code | The span is not a postal code in use in Thailand. |
| no_amount_words | The span is not an amount written in words. |
| below_min | The number is below the field's min. |
| above_max | The number is above the field's max. |
| too_many_decimals | The number carries more decimals than the field allows. |
| too_short | The text is shorter than the field's min_length. |
| too_long | The text is longer than the field's max_length. |
| pattern_mismatch | The text does not match the field's pattern. |
| before_min | The date is before the field's min. |
| after_max | The date is after the field's max. |
| in_the_future | The date is after today in Thailand, and the field set not_future. |
หมายเหตุ
ภาษาสคีมาไม่มีชนิด boolean ป้ายของช่องติ๊กพิมพ์อยู่บนหน้ากระดาษ แต่รอยติ๊กไม่ได้พิมพ์ ช่องติ๊กจึงจำลองเป็น enum ของป้ายที่พิมพ์ไว้
ขีดจำกัดจำนวนหน้า ขนาด และสคีมา#
หนึ่งคำขออ่านได้ไม่เกิน 20 หน้า เอกสารที่ยาวกว่านั้นตอบ 400 too_many_pages ไฟล์หลังถอดรหัส base64 ต้องไม่เกิน 10 MiB ไฟล์ที่ใหญ่กว่าตอบ 413 document_too_large สคีมานับได้ไม่เกิน 100 ฟิลด์ย่อย และมีขนาดไม่เกิน 128 KB ในรูป JSON กฎเรื่องเอกสารในคู่มือ OCR ใช้เหมือนเดิมทุกข้อ ระบบตรวจรูปแบบจากไบต์ของไฟล์ รูปภาพนับเป็นหนึ่งหน้า และไฟล์ที่อ่านไม่ได้หรือมีรหัสผ่านถูกปฏิเสธก่อนตัดเครดิต หนึ่งคำขอรับหนึ่งเอกสาร ไฟล์ที่มีหลายเอกสารได้ฟิลด์ชุดเดียว
ความเสถียรและการส่งซ้ำ#
คำตอบเป็น JSON ก้อนเดียว เอกสารหลายหน้าอาจใช้เวลาหลายนาที จึงควรตั้งไทม์เอาต์ของไคลเอนต์ให้เผื่อไว้ ตัวอย่างด้านบนเผื่อ 300 วินาที
คำขอที่ใช้เวลานานพอจะเขียนส่วนหัวของคำตอบออกไปก่อนที่จะรู้ผลลัพธ์ เพื่อไม่ให้พร็อกซีระหว่างทางตัดการเชื่อมต่อ คำตอบลักษณะนี้มีสถานะ 200 เสมอ และรายงานความล้มเหลวไว้ในเนื้อคำตอบด้วยเอกสารปัญหาชุดเดียวกับที่คำขอล้มเหลวได้รับ คือมี title และ status แทนที่ตำแหน่งของ fields ให้ถือว่าเนื้อคำตอบที่มี title คือข้อผิดพลาดตามที่ระบุ
ส่งซ้ำได้อย่างปลอดภัยด้วย Idempotency-Key การส่งซ้ำของคำขอที่ส่งมอบแล้วจะได้ฟิลด์ชุดเดิมโดยไม่ตัดเครดิตซ้ำ เมื่อการสกัดล้มเหลว ระบบคืนเครดิตให้ และคำขอใหม่ต้องใช้คีย์ใหม่ รหัสโมเดลคือเวอร์ชันของสัญญา ภาษาสคีมา รูปแบบคำตอบ และกฎการนับฟิลด์ย่อยคงที่ภายใต้ paxa-doc-extract-v1 การเปลี่ยนแปลงจะออกเป็นรหัสใหม่ที่ให้บริการควบคู่กัน