文字识别 API
POST /v1/ocr/base64 · /v1/ocr/url · /v1/ocr/file 单图识别 · PDF 异步任务
01单图识别
图片文字识别,返回逐行文本(含位置信息)。单张图片(png / jpg / webp / bmp,≤20MB),按输入形态三选一接口:base64 直传 / 公网 URL 引用 / multipart 文件直传,同步返回。
Endpoint · base64
POST/v1/ocr/base64 application/x-www-form-urlencoded
Endpoint · url
POST/v1/ocr/url application/x-www-form-urlencoded
Endpoint · file
POST/v1/ocr/file multipart/form-data
请求参数(按接口归属,三种输入形态对应三个接口)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| image | string | base64 接口必填 | base64 编码的图片内容(须 urlencode,解码后 ≤ 20MB,png/jpg/webp/bmp),一次请求直传,格式由文件头自动探测 |
| url | string | url 接口必填 | 图片的公网可下载地址(url ≤2048 字符,图片 ≤ 20MB),服务端拉取识别;内网/保留地址会被安全策略拒绝 |
| file(multipart) | file | file 接口必填 | 图片文件二进制(≤ 20MB),一次请求直传 |
| tier | string | 三接口均必填 | 识别档位:standard 标准档(快速,适合清晰打印件、截图)/ accurate 精准档(表格、多栏、倾斜拍摄等复杂版面);档位内具体模型由平台按在线状态自动选择 |
shell
# 接口 1 · base64 直传(image 字段自动 urlencode,一次请求闭环) curl https://www.suanlinfang.cn/v1/ocr/base64 \ -H "Authorization: Bearer nk-your-api-key" \ -d "tier=standard" \ --data-urlencode image@document.png # 接口 2 · 公网 URL(服务端从该地址拉取图片) curl https://www.suanlinfang.cn/v1/ocr/url \ -H "Authorization: Bearer nk-your-api-key" \ -d "tier=standard" \ -d "url=https://your-cdn.com/document.png" # 接口 3 · multipart 文件直传 curl https://www.suanlinfang.cn/v1/ocr/file \ -H "Authorization: Bearer nk-your-api-key" \ -F file=@document.png \ -F tier=standard
python
import base64, requests BASE, HEADERS = "https://www.suanlinfang.cn/v1", {"Authorization": "Bearer nk-your-api-key"} image = base64.b64encode(open("document.png", "rb").read()).decode() # base64 直传,一次请求闭环(data= 自动 urlencode,与 cURL 接口 1 等价) resp = requests.post(f"{BASE}/ocr/base64", headers=HEADERS, data={"tier": "standard", "image": image}) for line in resp.json()["wordsResult"]: print(line["words"])
响应示例
json · response
{
"logId": "550e8400-e29b-41d4-a716-446655440000",
"wordsResultNum": 2,
"wordsResult": [
{
"words": "算邻坊 GPU 算力共享平台"
},
{
"words": "闲置算力 · 共享收益"
}
]
}
| 响应字段 | 类型 | 必有 | 说明 |
|---|---|---|---|
| logId | string | 是 | 请求标识,排查问题时提供给平台(即该笔调用的流水号,与调用记录一一对应) |
| wordsResultNum | integer | 是 | 识别文本行数 |
| wordsResult | array | 是 | 逐行识别结果:words 为行文本;location 位置框取决于档位能力(当前档位不返回) |
计费按页计算(单图=1 页),详见计费说明。
02异步识别(PDF 文档)
PDF 文档(≤200MB、500 页以内)走 OSS 直传三步流 + 异步任务接口逐页识别;任务状态机与轮询约定见通用说明 · 异步任务。
申请上传签名
Endpoint
POST/v1/ocr/upload-tickets
Content-Type
application/json
异步 PDF 专用入口(单图走单笔三接口直连)
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| fileName | string | 是 | 文件名(含扩展名),扩展名须为 .pdf(异步任务仅支持 PDF;单张图片请直接调用单笔三接口) |
| sizeBytes | integer | 是 | 文件大小(字节),PDF ≤ 200MB,超出拒绝签发 |
响应示例
json · response
{
"fileKey": "inference-media/upload/1024/3a7d92c1-5b8e-4f0a-9c2d-7e1f6b4a8d30.pdf",
"uploadUrl": "https://slf-media-ocr.oss-cn-beijing.aliyuncs.com/inference-media/upload/...?Expires=...&Signature=...",
"method": "PUT",
"headers": { "Content-Type": "application/pdf" },
"expireAt": "2026-09-27T12:10:00Z",
"maxSizeBytes": 209715200
}
签名入口为异步 PDF 专用;单张图片识别无需签名上传,按输入形态直接调用 /v1/ocr/base64、/v1/ocr/url 或 /v1/ocr/file。
shell
# sizeBytes = 文件实际字节数(≤ 200MB、≤ 500 页) curl https://www.suanlinfang.cn/v1/ocr/upload-tickets \ -H "Authorization: Bearer nk-your-api-key" \ -H "Content-Type: application/json" \ -d '{"fileName":"contract-scan.pdf","sizeBytes":15728640}'
python
import os size_bytes = os.path.getsize("contract-scan.pdf") # ≤ 200MB、≤ 500 页 ticket = requests.post(f"{BASE}/ocr/upload-tickets", headers=HEADERS, json={"fileName": "contract-scan.pdf", "sizeBytes": size_bytes}).json() # ticket["uploadUrl"] / ticket["headers"] → 下一步 PUT 直传;ticket["fileKey"] → 提交任务用
上传文件到 OSS
Endpoint
PUT{uploadUrl}
Host
slf-media-ocr.oss-cn-beijing.aliyuncs.com
uploadUrl 域名为阿里云 OSS(非平台域名);签名已含在 URL 参数中,无需 Authorization 头
请求要素
| 要素 | 值 | 说明 |
|---|---|---|
| URL | 签名响应 uploadUrl | 签名 10 分钟内有效;过期重新申请签名(返回新的 fileKey 与 uploadUrl,以新值重传) |
| Headers | 照抄签名响应 headers | Content-Type: application/pdf 参与签名,值不一致时 OSS 返回 403(SignatureDoesNotMatch) |
| Body | PDF 原始二进制 | 文件字节流本身,不是 multipart/form-data |
| 成功 | HTTP 200 | 无响应体(响应头含 ETag);上传完成后 fileKey 即上传凭证,供下一步提交任务引用 |
shell
# URL 换成上一步签名响应的 uploadUrl(域名即 OSS,非平台) curl -X PUT "https://slf-media-ocr.oss-cn-beijing.aliyuncs.com/inference-media/upload/1024/3f2a9c71-....pdf?Expires=1761552000&Signature=..." \ -H "Content-Type: application/pdf" \ --data-binary @contract-scan.pdf # 成功:HTTP 200,无响应体
python
# ticket = 上一步「申请上传签名」的响应;headers 直接用 ticket["headers"],勿自行改写 with open("contract-scan.pdf", "rb") as pdf_file: upload = requests.put(ticket["uploadUrl"], data=pdf_file, headers=ticket["headers"]) upload.raise_for_status() # HTTP 200 即成功,无响应体
浏览器网页内也可直传:存储桶已开放 CORS(PUT / GET),前端拿到签名后用
fetch / XMLHttpRequest 发起同样的 PUT 即可。提交任务与轮询结果
Endpoint
POST/v1/ocr/tasks
Content-Type
application/json
平台自动将 PDF 逐页渲染为图片识别,页数即计费单元数
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| fileKey | string | 是 | 上传凭证,须为 PDF 文档(≤ 200MB、≤ 500 页),由申请上传签名接口返回 |
| tier | string | 是 | 识别档位:standard 标准档 / accurate 精准档,档位内模型由平台自动选择 |
查询接口
Endpoint
GET/v1/ocr/tasks/{taskNo}
查询响应示例(success 时)
json · response
{
"status": "success",
"totalUnits": 5,
"doneUnits": 5,
"resultUrl": "https://oss.../result.json?Expires=...&Signature=...",
"expireAt": "2026-09-27T12:00:00Z"
}
json · resultUrl 下载内容(result.json)
{
"pages": [
{ "page": 1, "words_result": [ { "words": "第一页第一行…" } ] },
{ "page": 2, "words_result": [ { "words": "第二页第一行…" } ] }
]
}
shell
# ① 提交任务(fileKey = 签名响应 fileKey;平台逐页渲染识别,页数即计费单元数) curl https://www.suanlinfang.cn/v1/ocr/tasks \ -H "Authorization: Bearer nk-your-api-key" \ -H "Content-Type: application/json" \ -d '{"fileKey":"inference-media/upload/1024/3f2a9c71-....pdf","tier":"accurate"}' # ② 轮询任务(GET 至终态 success / failed / expired) curl https://www.suanlinfang.cn/v1/ocr/tasks/f47ac10b-58cc-4372-a567-0e02b2c3d479 \ -H "Authorization: Bearer nk-your-api-key"
python
import time task = requests.post(f"{BASE}/ocr/tasks", headers=HEADERS, json={"fileKey": ticket["fileKey"], "tier": "accurate"}).json() while True: # 指数退避版见 通用说明 · 异步任务 query = requests.get(f"{BASE}/ocr/tasks/{task['taskId']}", headers=HEADERS).json() if query["status"] in ("success", "failed", "expired"): break time.sleep(5) print(query["resultUrl"] if query["status"] == "success" else query)
03历史记录查询
查询本 API Key 所属账户的文字识别调用历史;鉴权同产品端点(Bearer API Key),响应为分页 JSON(无信封)。
单笔历史
Endpoint
GET/v1/ocr/records
分页查询文字识别单笔形态的历史。
Query 参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| page | integer | 否 | 页码,默认 1 |
| pageSize | integer | 否 | 每页条数,默认 10 |
任务历史
Endpoint
GET/v1/ocr/tasks
分页查询文字识别异步任务形态的历史。
Query 参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| page | integer | 否 | 页码,默认 1 |
| pageSize | integer | 否 | 每页条数,默认 10 |
响应字段(items[] 内,null 字段不下发)
| 字段 | 类型 | 说明 |
|---|---|---|
| form | string | single / task(单笔 / 异步任务) |
| status | string | processing / success / failed |
| taskNo | string | 任务形态的任务号(单笔为 null 不下发) |
| inputCount | integer | 计费输入计数(OCR=页数,单图=1 页) |
| consumerCost | number | 本笔消费金额(元) |
| elapsedMs | integer | 推理耗时(毫秒) |
| errorMsg | string | 失败原因(成功为 null 不下发) |
| createdAt / completedAt | string | 受理 / 完成时间;两者之差即处理耗时 |
| resultUrl | string | success 且有产物时现签的下载链接(1 小时有效,重查换新链) |
| resultText | string | 单笔 success 行的识别全文(与当场响应同源;任务行无此字段,任务结果走 resultUrl) |
| tier | string | 识别档位(standard / accurate) |
| inputName | string | 输入文件名(任务形态) |
响应示例
json · response
{
"total": 42, "page": 1, "pageSize": 10,
"items": [{
"form": "single", "status": "success",
"inputCount": 52, "consumerCost": 0.0104,
"createdAt": "2026-10-29T10:00:00", "completedAt": "2026-10-29T10:00:08"
}]
}
04计费说明
按笔后付费:每次成功调用按实际用量从账户余额扣费,失败调用不扣费。费用明细与账户余额可在「文字识别工具」页的「历史记录」与「账户信息」页查看。
按页计费,元 / 页:单图 = 1 页,PDF = 实际页数。牌价以平台实时牌价为准。异步任务按单元逐笔计费(每页图片各计一笔)。
网络中断可能发生在计费完成之后,重试同一请求会产生新的计费,请结合「调用记录」核对后再重试。