一個端點。格式版本 4。Base URL https://api.consensis.app。
每個請求都帶 API 金鑰 —— Authorization: Bearer pk_live_… 或 X-API-Key 標頭。登入(Google 或 email,登入即建立帳戶)後在帳戶頁簽發金鑰。明文金鑰只顯示一次;我們只保存摘要。比對不到的金鑰回 401 —— 打錯的金鑰絕不會靜默降級成匿名試用,所以你永遠知道一件工作是記在哪個帳戶上。
mode=batch 為 0.036 美元),最低儲值 3.50 美元。失敗的頁面一律不計費。免費試用直接從 API 就能用:每個位址每天 10 頁免費,完全不帶 Authorization 標頭(網頁上傳器另有獨立的 10 頁;超過額度時回應會帶 Retry-After)。
# 完全匿名 —— 不必金鑰、不必註冊
curl -X POST https://api.consensis.app/v1/parse -F "[email protected]"
# → 202 {"id": "…", "status": "queued", ...} — 輪詢方式同下
curl -X POST https://api.consensis.app/v1/parse \
-H "Authorization: Bearer pk_live_…" \
-F "[email protected]" -F "pages=10"
# → 202 {"id": "b7f395cf7fbc", "status": "queued", ...}
curl -H "Authorization: Bearer pk_live_…" \
https://api.consensis.app/v1/parse/b7f395cf7fbc
# → 輪詢到 "status": "done" 為止,之後 usage 與 result 就會一併附上
curl -OJ -H "Authorization: Bearer pk_live_…" \
"https://api.consensis.app/v1/parse/b7f395cf7fbc/export?format=xlsx"
json 與 zip 帶全部內容(信心等級、來源、讀取結果、bbox);xlsx 保留看得見的信心標記 —— 有異議的格子塗紅、未驗證塗黃 —— 另附一張攤平的 cells 工作表供稽核;csv 只有值:它表達不了哪些格子有異議,所以在意可信度時請搭配 JSON。非同步 —— POST 立刻回 202;之後用 id 追蹤。10 頁冷啟動約需 600 秒;命中快取快得多。不要用 stage 推斷是否完成 —— 那個字串是給人看的;請看 status。
-F "mode=batch"。同樣的擷取、同樣的保證、同樣的結果格式;差別在於時間 —— 其中一條讀取分支跑在 batch 端點上。九次實測為 4–55 分鐘,但那是觀察值,不是承諾:上游的 batch 服務以 24 小時為目標,也是這樣說的。我們承諾的是一條底線 —— 若 batch 分支在 4 小時內未回傳,我們就改用即時管線重跑,你照樣拿到結果、照樣是 batch 價格。差額由我們吸收。輪詢方式相同;工作會回報 "mode": "batch"。適合夜間執行與大量回填這類價格優先於延遲的場合。這就是這個 API 賣的東西。不是「擷取更準」—— 而是每一格都能交代自己的來歷。
{"value": "1432",
"confidence": "verified",
"sources": ["vision-1", "vision-2"],
"bbox": [436.5, 577.7, 459.8, 591.9]}
兩個獨立讀取結果一致,所以這一格是 verified,不帶 readings —— 值就是值。
readings 是關鍵差異:讀取結果不一致時你會拿到每個版本 —— 我們不會靜默挑一個。挑錯了,你根本不知道該看哪裡。只在有不一致時出現:
{"value": "1432",
"confidence": "disputed",
"provisional": true,
"sources": ["vision-1", "vision-2"],
"readings": {"vision-1": "1432", "vision-2": "1482"}}
只在 confidence 為 disputed 時出現,而且永遠是 true。
readings 檢查,並且不要直接匯入正式系統。| confidence | 意義 |
|---|---|
exact | 直接從結構化檔案讀出 —— 不涉及任何解讀 |
verified | 多次獨立讀取一致 |
confirmed | 由人對照原頁定案 |
reviewed | 由 AI 複核器對照原頁影像裁定 —— 快速且審慎,但未經獨立驗證 |
resolved | 多數讀取一致 |
unverified | 只有一次讀取 —— 沒有東西可以交叉比對 |
disputed | 獨立讀取之間不一致 —— 這些儲存格需要人工確認 |
這些不是廠商名稱。稽核問的是「有幾個獨立讀取結果」,不是「哪一家廠商」。
| sources | 是什麼 |
|---|---|
ocr-1 | 某一個模型家族的 OCR 引擎 |
ocr-2 | 另一個家族的 OCR 引擎 —— 只有不同家族才抓得到同源偏差 |
ocr-3 | 第三個 OCR 家族。目前的服務未啟用 —— 名稱留在詞彙表裡,因為契約不該隨我們的組態而改變。 |
pdf-layout | PDF 自帶的版面幾何(有框線與文字層時最準 —— 而且免費) |
pdf-grid | 從填色矩形推得的格線 |
pdf-model | 以訓練過的版面模型讀取 PDF 的內部結構 —— 不用 OCR、不依賴框線 |
pdf-text | PDF 的文字層 |
source-data | 直接讀自結構化檔案(XLSX/CSV —— 不做解讀) |
vision-review | 對照原始頁面影像裁決 |
layout | 版面讀取在這個位置找到一張圖 |
ocr | 第二個讀取獨立在同一個框內找到重疊的圖 —— 就是它讓一張圖成為 verified |
pdf-image | PDF 本身在這裡有一個內嵌的影像物件。單靠它不算第二意見 —— 它只說檔案裡有一張圖,不代表我們框對了那一張 |
vision-1 | 兩個獨立視覺讀取器之一,各自看頁面影像並重建表格網格 |
vision-2 | 第二個視覺讀取器 —— 與 vision-1 是不同的模型家族,所以兩者能各自獨立地不一致 |
vision-single | 由視覺讀出,但這一格只有一個讀取結果 —— 沒有第二意見佐證 |
vision-audit | confirmed by the audit pass — a separate reading of the original page image that reviewed the whole table and raised no objection to this cell. |
vision-arbiter | 為了裁定兩個視覺讀取器之間的分歧而多做的一次讀取 —— 不是那兩個之一 |
vision-grid | 第一輪留下空洞或整列錯位時,重讀頁面影像重建網格而補回的 |
human-review | 由人在並排複核頁上確認過 —— 其他每個來源都是在解讀頁面;這一個是一個人在確認或修正它 |
[x0, y0, x1, y1],單位是 PDF 點(1/72 英吋),原點在左上;頁碼在表格的 page 上。
usage.cells_with_bbox 會精確回報你的文件有幾格帶座標 —— 這個數字不藏。上一節說的是一格帶什麼。這一節說一張表是怎麼圍著這些格子成形的。
{
"page": 7,
"index": 0,
"order": null,
"kind": null,
"layout_disputed": true,
"column_major": false,
"header": [
"model",
"d"
],
"row_groups": [],
"header_cells": [
{
"value": "model",
"confidence": "unverified",
"sources": []
},
{
"value": "d",
"confidence": "unverified",
"sources": []
}
],
"rows": [
[
{
"value": "LB 08",
"confidence": "unverified",
"sources": []
},
{
"value": "1432",
"confidence": "verified",
"sources": [
"vision-1",
"vision-2"
]
}
]
]
}
header 是純粹的欄名 —— 從 header_cells 導出,絕不另外計算,所以兩者不會漂開。header_cells 是同一組名字加上 confidence 與 sources:欄名錯一個,整欄的意思就變了,而且你光看看不出來。
rows 是列的清單,每列是格子的清單。column_major 告訴你原表是橫著走還是直著走;我們永遠交付列,這個欄位記錄的是頁面上原本的樣子。
row_groups 是規格表上那種旋轉的側邊分類(Dimensions (mm)、Load capacity)—— 每列一個標籤。它不是一欄,因為欄數是交叉比對的根基;但少了它你分不出 C₀ 是負載還是長度。表格沒有分組時為空。
這些和 unreadable 遵守同一條規則:每張表都帶一個 false 是雜訊,你要掃的是例外。
| 欄位 | 何時出現 |
|---|---|
caption | 屬於整張表的限定詞(例如 HG - 15, 20),繼承自它交付時所屬的群組。 |
kind | 我們認為這是哪一種表。每張表都有;值是簡短的標籤,不是承諾。 |
layout_disputed | 版面讀取對「這裡有一張表」意見不一。我們照樣交付擷取到的內容 —— 但採信前請對照原頁檢查這一張。這和格子層級的 confidence 是不同的軸:它質疑的是表存不存在,不是值有沒有讀對。 |
ocr_unsupported | 沒有獨立的 OCR 讀取結果與這張表的內容重疊。精神同上:標記,不丟掉。 |
span_grid | 跨列或跨欄的表格背後的合併格網格。你拿到的攤平 rows 就是這個網格攤開的樣子;這裡是原本的形狀。 |
colbands | 欄帶 —— 把幾欄歸在同一個標籤下的表頭。 |
unfolded | 這張表是跨摺頁重新拼回來的。 |
sheet | 工作表名稱。只有試算表輸入才有,而試算表目前關閉 —— 欄位仍保留說明,好讓重新開放時契約不必改。 |
segments(代碼的每一段:叫什麼、允許哪些值)和一個 example_code。表本身原樣交付 —— 你已經在讀的東西照常運作。每張表也帶 bbox —— 整張表在頁面上的外框,座標和格子、散文、影像同樣用 PDF 點(取該表各格子框的聯集;一個格子框都沒有時就不給這個欄位)—— 以及 order,它在該頁閱讀順序中的位置。當版面讀取對一頁有幾張表意見不一時,order 改由 bbox 量出:等於表上方最後一個散文或影像區塊的 order。配合 pages[].width/height,就足以把頁面重建成結構化的版面。
結果不只有 tables。每份文件也帶 prose(連續文字 —— 標題與段落)和 images(裁下的圖)。兩者都用和格子一樣的方式交叉比對,也都會說是誰佐證了它們。
{"page": 7,
"index": 2,
"text": "Preload classes are selected according to the rail size.",
"confidence": "verified",
"sources": ["ocr-1", "ocr-2"],
"bbox": [56.2, 98.6, 213.6, 236.9],
"role": "paragraph",
"level": 0,
"order": 4}
每個文字區塊一筆,逐頁編號。role 是 heading 或 paragraph;level 是標題層級(段落為 0);order 是該頁閱讀順序中的位置,與 images 共用,方便你穿插排列。
負責呈現文字的那個讀取,不算作它自己的證人。一個段落是 verified,是因為對這一頁的另一個讀取含有相同內容 —— 所以你看到的來源是同意的那些,絕不是被檢查的那一個。段落邊界不必吻合:各個讀取切分文字的方式不同,那是排版差異,不是不一致。
verified,跨 7 份文件(2,812 個段落)。這個範圍是真的,取決於文件 —— 和 bbox 同樣的但書。掃描件落在低的那一端。{"page": 7,
"index": 1,
"path": "images/p007_00.png",
"confidence": "verified",
"bbox": [56.2, 98.6, 213.6, 236.9],
"order": 3,
"also_on": [9],
"sources": ["layout", "ocr", "pdf-image"]}
path 相對於結果包(zip 匯出);also_on 列出帶有位元組完全相同副本的其他頁 —— 重複的會回報,不會移除,因為同一張尺寸圖本來就會合理地出現在兩個料號底下。
影像用自己的一套來源詞彙,因為問題是「這裡有沒有一張圖」,不是「這個值有沒有讀對」。注意什麼不會讓一張圖成為 verified:只有 pdf-image。PDF 在那個位置含有內嵌影像,只說明檔案裡有一張圖,不代表我們框對了 —— 早先的版本把它當成充分條件,結果三份文件回來 100% verified,而「整張圖漏掉」的機率在結構上是零。
[{"page": 6, "width": 612.0, "height": 792.0},
{"page": 7, "width": 612.0, "height": 792.0, "unreadable": true}]
當你要求的是頁面範圍時,旁邊會有 source_pages:它把交付內容中的位置對應回你原始檔案的頁碼,所以任何結果都能指回它來自的那一頁。
你要求的每一頁一筆。width 與 height 是畫布大小,單位 PDF 點 —— 少了它們,bbox 就沒有可依附的框。
unreadable: true 不代表「這一頁沒有表格」。它代表我們讀了這一頁,而且兩個獨立讀取都失敗了 —— 這份交付裡沒有任何來自那一頁的東西,你應該去看原稿。真的什麼都沒有的頁面,不帶任何旗標。
這個旗標只出現在失敗的頁面上,所以掃它很便宜。一頁壞掉不再拖垮整份文件:其他頁面照常交付。若每一頁都失敗,我們會拒絕這件工作,而不是給你一份空結果。
| 項目 | 值 | 為什麼是這個數字 |
|---|---|---|
| 檔案大小 | 600 MB | 從真實的掃描型錄量出來的(121、266、443、456 MB)—— 不是猜的。 |
| 頁數 | 500 頁 | 我們量過最厚的型錄是 235 頁,而一份 500 頁的文件已經會佔住佇列大約兩小時 —— 再多,一件工作就會卡住後面所有人。免費試用涵蓋 10 頁;自架的安裝可調 PDFPAGES_MAX_PAGES。 |
| 格式 | 副檔名不算數 —— 我們看內容。影像與試算表目前關閉 —— 管線處理得了,但會帶著自己的定價回來。 | |
| 並行 | 一次一份文件 | 管線會吃滿 CPU;佇列只有一個 worker。多送的會排隊 —— 不會失敗。 |
| 重啟 | 最多重新排隊 2 次 | 被服務重啟打斷的工作會重新排隊(有快取,重跑幾乎不花成本);超過次數就誠實地失敗,而不是無限迴圈。 |
| 保留期 | 完成後 24 小時 | 我們不保留你的資料。結果同步可取;請在期限內抓取裁圖 —— 之後整件工作連同 OCR 快取一併刪除。DELETE /v1/parse/{id} 可以提前刪除。代價是:之後再送同一份文件會當作新工作處理 —— 也重新計費;沒有任何副本留下來抄捷徑。 |
Python-urllib/3.x)的請求,會在到達我們之前就被 CDN 的機器人規則擋下 —— 你拿到的是 CDN 錯誤頁,不是下面任何一種錯誤,看起來就像服務掛了。requests、httpx 與 curl 原樣就能用;用 urllib 的話,自己設任何一個 User-Agent 都行。一律是 {"detail": "…"},寫給人看 —— 絕不含伺服器路徑、絕不含金鑰名稱。
| 狀態碼 | 何時 | 說明 |
|---|---|---|
400 | 無法辨識的格式 | 副檔名不算數 —— 我們看內容。支援:PDF。 |
401 | 不認識的 API 金鑰 | Authorization / X-API-Key 裡的金鑰對不上任何帳戶。打錯的金鑰絕不會降級成匿名試用;要用試用就刻意不帶金鑰。 |
400 | 我們暫時關閉的格式 | 目前暫時只收 PDF。影像與試算表管線支援但已關閉 —— 會帶著自己的定價回來。這和上面那個是不同的錯誤:檔案沒問題,只是我們現在不收。 |
400 | 檔案太大,或是空的 | 上限是 600 MB。 |
400 | pages 小於 1 | 需要幾頁就要幾頁;上限由伺服器把關。 |
400 | 不支援的匯出格式 | GET 接受 xlsx、csv、json 與 zip(結果包:dataset.json 加上每張裁圖);POST /v1/export 接受 xlsx 與 csv。 |
413 | 無狀態匯出請求主體太大 | POST /v1/export 接受最大 600 MB 的資料集。 |
402 | 餘額不足 | 預付方案:這份文件的費用(頁數 × 每頁單價)超過你的餘額 —— 餘額夠付才會執行。回應會說明你剩多少餘額、這份文件需要多少 —— 儲值後重送即可;沒有東西排隊,也沒有扣款。 |
429 | 匿名試用的速率限制 | 免註冊試用有每小時/每天的頁數上限(防濫用,不是定價)。回應帶 Retry-After;已登入的預付帳戶不受此限。 |
404 | 找不到擷取工作 | job_id 錯了,或是服務重啟後這件工作沒有被恢復。 |
404 | 沒有裁到任何圖卻要 format=zip | 結果包是裁下的影像加上 dataset.json;一份我們沒裁出任何圖的文件(試算表,或整頁純文字)沒有結果包。其他三種格式仍可用 —— json 帶同樣的資料。我們寧可回 404,也不給你一個看起來像結果其實不是的壓縮檔。 |
409 | 尚未完成就要求匯出 | 請先輪詢到 status 為 done。 |
500 | 已完成但結果檔不見了 | 那是我們這邊的 bug。我們不會假裝它還在跑,讓你永遠輪詢下去。 |
| 不提供 | 原因 |
|---|---|
POST /v1/webhooks | 完成回呼。目前請輪詢 GET /v1/parse/{id};在 10 頁(冷啟動約 600 秒)的規模下,輪詢完全撐得住。 |
page_range | 只能要前 N 頁,不能要第 100–110 頁。對厚型錄這是真實的限制:一份 235 頁的型錄把規格表放在後半,而 pages 是從第 1 頁數起。 |
GET /v1/jobs, POST /v1/cancel/{id} | 列表與取消。還不需要,所以沒做。(刪除有:DELETE /v1/parse/{id}。) |
掃描檔辨識效果會明顯下降。我們把 PDF 的文字層當成額外的獨立讀取依據;少了它,我們實測的交叉比對覆蓋率降到 1/3–1/18。text_layer 在 202 回應裡就會回報 —— 不必等跑完才知道。
正確率每份文件差很多。怎麼量、樣本多大、哪裡會失敗都有文件記載,並附人工查核的下限。我們不會在這裡籠統寫「99%+」。