Stirling-PDF 3.2.0 API 使用详解
Stirling-PDF 3.2.0 REST API 实战详解:免认证/JWT/API Key 三种认证链路实测、319 端点 28 分组全景、general/convert/security/misc 核心端点请求-响应逐字回显、结构化错误码(E004/企业版 403)与排障实录、文件响应与分页通用约定。
Stirling-PDF 3.2.0 API 使用详解
目标:讲清 Stirling-PDF 3.2.0 的 REST API 体系——三种认证方式(免认证探测/会话 JWT/API Key)的完整实测链路、319 个端点的 28 个功能分组、文件类与信息类端点的请求-响应实测对照、结构化错误响应与错误码,以及企业版端点的行为边界。全部请求与响应均在部署环境(Ubuntu 22.04、Stirling-PDF 3.2.0,服务地址 http://192.168.146.128:8129)用 curl 实测取得,逐字照抄。部署与配置背景见 《Stirling-PDF 3.2.0 Docker Compose 部署指南》、《Stirling-PDF 3.2.0 配置参数详解》。
一、环境信息
本篇 API 实测环境与版本基线如下:
- 服务端:Stirling-PDF 3.2.0(Java/Spring Boot,REST API 与 Web 界面同端口同服务)
- 操作系统:Ubuntu 22.04.4 LTS
- 服务地址:http://192.168.146.128:8129(API 基路径
http://192.168.146.128:8129/api/v1) - 客户端工具:curl 7.81.0(文件上传用
-Fmultipart/form-data,JSON 接口用-d) - 测试文件:
test1.pdf(ReportLab 生成、2 页、有文本层)、scanned.pdf(扫描样式件) - 管理账号:admin(角色 ROLE_ADMIN,界面生成 API Key)
- 接口清单来源:服务端 OpenAPI 描述("Stirling PDF API",openapi 3.0.3,实测共 319 个端点),在线文档 https://registry.scalar.com/@stirlingpdf/apis/stirling-pdf-processing-api/
二、前置条件
动手前确认三件事:
- 服务已部署并可达(验证:
curl http://192.168.146.128:8129/api/v1/info/status返回{"version":"3.2.0","status":"UP"},该端点免认证,部署方法见部署篇); - 拥有 admin 账号与密码(本文实测用 admin / q1w2e3r4;首次登录后请修改,修改后以新密码调用登录接口);
metrics.enabled为默认值 true(信息类接口可用性受该开关控制,关闭时/api/v1/info/uptime等返回 403,排查见配置篇 3.3 节实测)。
三、API 总览
3.1 协议与风格
- 协议与风格:HTTP + REST,端点前缀
/api/v1;文件处理类端点全部为POST multipart/form-data(字段名fileInput传文件),信息/会话类端点为GET或POST application/json; - 响应两类:处理类端点直接回传二进制文件流(
application/pdf、application/octet-stream、text/markdown等,按Content-Disposition重命名);信息类端点回传 JSON 或纯文本; - 版本:API 路径版本
v1;应用版本经GET /api/v1/info/status的version字段核实; - 本地接口文档:服务内置 Swagger UI 页面
http://192.168.146.128:8129/swagger-ui/index.html(实测 200);完整 OpenAPI 3.0.3 描述文档以官方 Scalar 站点为准(本机 schema 端点被前端页面路由接管,实测/v3/api-docs返回网页而非 JSON)。
3.2 认证方式约定
| 方式 | 凭据 | 适用 |
|---|---|---|
| 免认证 | 无 | 少数探测端点(/api/v1/info/status) |
| 会话 JWT | Authorization: Bearer <access_token> | 登录接口换取令牌后的全部接口 |
| API Key | X-API-KEY: <apiKey> | 服务间集成(每用户一枚,界面生成或接口签发) |
3.3 端点分组全景
服务端 OpenAPI 描述实测共 319 个端点、28 个分组,分组与规模如下(数量为实测统计):
| 分组 | 数量 | 分组 | 数量 | 分组 | 数量 |
|---|---|---|---|---|---|
| convert(格式转换) | 33 | security(加密签名) | 31 | admin(管理) | 29 |
| misc(压缩/提取等杂项) | 29 | general(页面级操作) | 27 | proprietary(付费功能) | 24 |
| user(用户/密钥) | 18 | storage(文件存储) | 16 | form(表单) | 14 |
| info(服务信息) | 12 | processing-folders(流水线目录) | 9 | analysis(分析) | 8 |
| ui-data(界面数据) | 8 | audit(审计) | 6 | filter(筛选) | 6 |
| invite(邀请) | 6 | team(团队) | 6 | workflow(工作流) | 6 |
| auth(认证会话) | 9 | database(数据库管理) | 4 | ownership(所有权) | 4 |
| ai(AI 问答) | 3 | integration/integrations(集成) | 3+3 | docparse(文档理解) | 2 |
| pipeline(流水线执行) | 1 | usage(用量) | 1 | 其他 | 1 |
关键解读:日常集成的核心是 general(页面操作)+ convert(转换)+ security(加密签名)+ misc(压缩提取) 四组(第五章 5.4–5.7 节逐个实测);
proprietary组 24 个端点为 Pro/Enterprise 许可功能,社区版调用返回 403(实测见 5.8 节)。
四、认证与首次调用
4.1 无凭据调用:401 行为
除 info/status 等探测端点外,未认证请求一律 401:
curl -s -w '\nHTTP %{http_code}\n' http://192.168.146.128:8129/api/v1/info/health
实测回显:
{"error":"Authentication required"}
HTTP 401
4.2 登录换取会话 JWT
curl -s -X POST http://192.168.146.128:8129/api/v1/auth/login \
-H 'Content-Type: application/json' \
-d '{"username":"admin","password":"q1w2e3r4"}'
实测回显(节选,token 中部截断;expires_in 单位秒,即 1 天):
{"session":{"expires_in":86400,"access_token":"eyJraWQiOiJqd3Qta2V5LTIwMjYtMTAtMjItMDA1MzEyLTFjZDY3MzdmIiwiYWxnIjoiUlMyNTYifQ.eyJyb2xlIjoiUk9MRV9BRE1JTiIsImF1dGhUeXBlIjoiV0VCIiwic3ViIjoiYWRtaW4iLCJpc3MiOiJodHRwczovL3N0aXJsaW5nLmNvbSIsImlhdCI6MTc5MjYzMDQ1NiwiZXhwIjoxNzkyNzE2ODU2fQ.…(截断)…"},"user":{"role":"ROLE_ADMIN","team":{"name":"Default","id":1},"enabled":true,"orgOwner":true,"id":1,"username":"admin","email":"admin"}}
用 JWT 调 GET /api/v1/auth/me 核实身份:
curl -s -H "Authorization: Bearer $TOKEN" http://192.168.146.128:8129/api/v1/auth/me
实测回显:
{"user":{"role":"ROLE_ADMIN","portalAccess":true,"team":{"name":"Default","id":1},"enabled":true,"orgOwner":true,"user_metadata":{"firstLogin":false},"loginLandingView":"editor","id":1,"authenticationType":"web","email":"admin","teamLead":false,"username":"admin","app_metadata":{"provider":"web"}}}
💡 说明:access_token 是 RS256 签名的 JWT(payload 实测含
role: ROLE_ADMIN、iss: https://stirling.com、exp等),有效期 1440 分钟(配置项security.jwt.tokenExpiryMinutes,见配置篇 5.2 节)。
4.3 签发 API Key(服务间集成推荐)
每用户一枚 API Key,接口签发(需先持有会话 JWT 或界面操作):
curl -s -X POST -H "Authorization: Bearer $TOKEN" http://192.168.146.128:8129/api/v1/user/get-api-key
实测回显:
{"apiKey":"b07d2b3a-ffda-4893-a32d-196881535fc2"}
之后所有请求用 X-API-KEY 头即可,等效于该用户身份(重复调 get-api-key 返回同一枚;update-api-key 轮换新值):
curl -s -H "X-API-KEY: b07d2b3a-ffda-4893-a32d-196881535fc2" http://192.168.146.128:8129/api/v1/auth/me
实测回显(与 JWT 方式完全一致的用户信息):
{"user":{"role":"ROLE_ADMIN","portalAccess":true,"team":{"name":"Default","id":1},"enabled":true,"orgOwner":true,"user_metadata":{"firstLogin":false},"loginLandingView":"editor","id":1,"authenticationType":"web","email":"admin","teamLead":false,"username":"admin","app_metadata":{"provider":"web"}}}
⚠️ 注意:API Key 是长期凭据,泄露后在界面「账户设置」或经
update-api-key立即轮换;本文的 Key 仅为实测演示值。
五、各 API 域详解
5.1 info 域:服务状态与运行信息
GET /api/v1/info/status(免认证,健康检查同款端点):
curl -s http://192.168.146.128:8129/api/v1/info/status
实测回显:
{"version":"3.2.0","status":"UP"}
GET /api/v1/info/uptime(需认证;服务运行时长,纯文本):
curl -s -H "X-API-KEY: b07d2b3a-ffda-4893-a32d-196881535fc2" http://192.168.146.128:8129/api/v1/info/uptime
实测回显(重启后 32 秒):
0d 0h 0m 32s
GET /api/v1/info/load(需认证;系统负载,纯文本单值):
curl -s -H "X-API-KEY: b07d2b3a-ffda-4893-a32d-196881535fc2" http://192.168.146.128:8129/api/v1/info/load
实测回显:
0.0
💡 说明:info 域共 12 个端点(status/health/uptime/load/requests 等,清单见第三章);除 status 外都受
metrics.enabled开关与认证控制。
5.2 general 域:页面级操作
POST /api/v1/general/merge-pdfs(合并多个 PDF;multipart 字段 fileInput 重复传多份):
curl -s -o merged.pdf -w 'HTTP %{http_code} type=%{content_type} size=%{size_download}\n' \
-H "X-API-KEY: b07d2b3a-ffda-4893-a32d-196881535fc2" \
-F "fileInput=@test1.pdf" -F "fileInput=@scanned.pdf" \
http://192.168.146.128:8129/api/v1/general/merge-pdfs
file merged.pdf
实测回显:
HTTP 200 type=application/pdf size=39026
merged.pdf: PDF document, version 1.5, 4 pages
POST /api/v1/general/rotate-pdf(旋转页面;参数 fileInput + angle,实测响应头):
curl -s -D - -o rotated.pdf -H "X-API-KEY: b07d2b3a-ffda-4893-a32d-196881535fc2" \
-F "fileInput=@test1.pdf" -F "angle=90" \
http://192.168.146.128:8129/api/v1/general/rotate-pdf
实测回显(响应头节选 + 落盘验证):
HTTP/1.1 200 OK
Cache-Control: private, no-store
Content-Type: application/pdf
Content-Disposition: form-data; name="attachment"; filename="test1_rotated.pdf"
X-Frame-Options: DENY
Content-Length: 1469
rotated.pdf: PDF document, version 1.6
要点解读:输出文件名按「原名_操作后缀.pdf」规则重命名(test1.pdf → test1_rotated.pdf),客户端落盘时应取响应头 Content-Disposition 中的 filename 而不是自造名字。
POST /api/v1/general/split-pages(按页码区间拆分;返回 zip 包):
curl -s -o split.zip -w 'HTTP %{http_code} %{content_type} %{size_download}\n' \
-H "X-API-KEY: b07d2b3a-ffda-4893-a32d-196881535fc2" \
-F "fileInput=@test1.pdf" -F "pageNumbers=1-2" \
http://192.168.146.128:8129/api/v1/general/split-pages
file split.zip
实测回显:
HTTP 200 application/octet-stream 1585
split.zip: Zip archive data, at least v2.0 to extract, compression method=deflate
POST /api/v1/general/remove-pages(删除指定页;参数 fileInput + pageNumbers):
curl -s -o removed.pdf -w 'HTTP %{http_code} %{content_type} %{size_download}\n' \
-H "X-API-KEY: b07d2b3a-ffda-4893-a32d-196881535fc2" \
-F "fileInput=@test1.pdf" -F "pageNumbers=1" \
http://192.168.146.128:8129/api/v1/general/remove-pages
实测回显:
HTTP 200 application/pdf 1160
5.3 security 域:加密与解密
POST /api/v1/security/add-password(加密;核心参数 fileInput、password(打开密码)、ownerPassword(权限密码)、keyLength(默认 256)):
curl -s -o locked.pdf -w 'HTTP %{http_code} %{content_type} %{size_download}\n' \
-H "X-API-KEY: b07d2b3a-ffda-4893-a32d-196881535fc2" \
-F "fileInput=@test1.pdf" -F "password=q1w2e3r4" -F "ownerPassword=q1w2e3r4" \
http://192.168.146.128:8129/api/v1/security/add-password
实测回显:
HTTP 200 application/pdf 2085
locked.pdf: PDF document, version 1.6
POST /api/v1/security/remove-password(解除加密;传原密码):
curl -s -o unlocked.pdf -w 'HTTP %{http_code} %{content_type} %{size_download}\n' \
-H "X-API-KEY: b07d2b3a-ffda-4893-a32d-196881535fc2" \
-F "fileInput=@locked.pdf" -F "password=q1w2e3r4" \
http://192.168.146.128:8129/api/v1/security/remove-password
实测回显:
HTTP 200 application/pdf 1473
unlocked.pdf: PDF document, version 1.6
POST /api/v1/security/add-cert-sign 等证书签名、时间戳端点同在 security 组(共 31 个端点),参数结构与 add-password 同风格(AddPasswordRequest 实测 schema 含 preventPrinting、preventModify 等 11 个权限布尔项)。
5.4 convert 域:格式转换
POST /api/v1/convert/pdf/text(PDF → 纯文本;⚠️ 实测发现 outputFormat 为必填,缺省直接 400——见 5.8 节排障实录):
curl -s -o out.txt -w 'HTTP %{http_code} %{size_download}\n' \
-H "X-API-KEY: b07d2b3a-ffda-4893-a32d-196881535fc2" \
-F "fileInput=@test1.pdf" -F "outputFormat=txt" \
http://192.168.146.128:8129/api/v1/convert/pdf/text
cat out.txt
实测回显:
HTTP 200 158
Stirling-PDF Test File 1
Page 1 of test document 1 - generated for API testing
Stirling-PDF Test File 1
Page 2 of test document 1 - generated for API testing
POST /api/v1/convert/pdf/markdown(PDF → Markdown,中文文档实测):
curl -s -o out.md -w 'HTTP %{http_code} %{content_type} %{size_download}\n' \
-H "X-API-KEY: b07d2b3a-ffda-4893-a32d-196881535fc2" \
-F "fileInput=@report.pdf" \
http://192.168.146.128:8129/api/v1/convert/pdf/markdown
head out.md
实测回显(对一份含中文标题/列表的「备份任务记录」文档;首行节选):
HTTP 200 text/markdown 166
# 备份任务记录
- 每日 00:00 自动导出数据库
- 校验和已生成
convert 组共 33 个端点覆盖 pdf/text|markdown|html|word|xlsx|csv|epub|img|pdfa 等双向转换(URL→PDF 端点存在但服务端默认禁用,配置见配置篇 5.3 节)。
5.5 misc 域:压缩与提取
POST /api/v1/misc/compress-pdf(压缩;参数 fileInput、optimizeLevel(整数档位)、grayscale 等):
curl -s -o compressed.pdf -w 'HTTP %{http_code} %{size_download}\n' \
-H "X-API-KEY: b07d2b3a-ffda-4893-a32d-196881535fc2" \
-F "fileInput=@scanned.pdf" \
http://192.168.146.128:8129/api/v1/misc/compress-pdf
实测回显(默认档位压缩扫描样式件):
HTTP 200 25366
misc 组另含 extract-images(提取图片,返回 zip)、ocr-pdf(Tesseract OCR,参数含 languages 语言代码如 eng/chi_sim)等 29 个端点。
5.6 错误响应结构与错误码
所有结构化错误遵循统一 JSON 结构(detail 描述、instance/path 端点、status、title、type 错误类型路径、timestamp,部分带 hints 修复建议与 errorCode)。实测各场景:
参数校验错误(rotate 传非 90 倍数角度):
{"detail":"Angle must be a multiple of 90","instance":"/api/v1/general/rotate-pdf","status":400,"title":"Invalid Argument","type":"/errors/invalid-argument","timestamp":"2026-10-22T00:58:12.669751372Z","path":"/api/v1/general/rotate-pdf","title":"Invalid Argument","hints":["Review the error message and adjust the parameter value.","Consult the API docs for accepted ranges and formats.","Ensure required parameters are present."],"actionRequired":"Correct the invalid argument and retry."}
受密码保护文件未提供/密码错(remove-pages 遇到加密件,errorCode E004):
{"detail":"The PDF Document is passworded and either the password was not provided or was incorrect","instance":"/api/v1/general/remove-pages","status":400,"title":"PDF Password Required","type":"/errors/pdf-password","timestamp":"2026-10-22T00:57:59.661486988Z","path":"/api/v1/general/remove-pages","title":"PDF Password Required","errorCode":"E004"}
端点不存在(404):
{"detail":"No endpoint found for GET /api/v1/no/such/endpoint","instance":"/api/v1/no/such/endpoint","status":404,"title":"Endpoint Not Found","type":"/errors/not-found","timestamp":"2026-10-22T00:57:00.810937570Z","path":"/api/v1/no/such/endpoint","title":"Endpoint Not Found","method":"GET","hints":["Verify the URL path and HTTP method are correct.",...]}
方法不允许(405,对 GET-only 端点 POST):
{"detail":"HTTP method POST is not supported for this endpoint. Supported methods: GET","instance":"/login","status":405,"title":"HTTP Method Not Allowed","type":"/errors/method-not-allowed","timestamp":"2026-10-22T00:49:11.098460849Z","path":"/login","title":"HTTP Method Not Allowed","method":"POST","supportedMethods":["GET"],...}
付费功能越权(社区版调 Enterprise 端点):
curl -s -H "X-API-KEY: b07d2b3a-ffda-4893-a32d-196881535fc2" 'http://192.168.146.128:8129/api/v1/audit/data?page=0&size=2'
实测回显:
{"detail":"This endpoint requires an Enterprise license","instance":"/api/v1/audit/data","status":403,"title":"Forbidden","type":"/errors/403","timestamp":"2026-10-22T02:29:18.092617205Z","path":"/api/v1/audit/data","title":"Forbidden"}
信息接口被配置关闭(metrics.enabled: false 时):
This endpoint is disabled.
HTTP 403
关键解读:排障先看
detail与errorCode(如 E004=PDF 密码问题);403 有两类根因——许可(requires an Enterprise license)与配置开关(This endpoint is disabled.),按文案区分。
六、通用约定:文件响应、分页与重试
文件响应约定(处理类端点实测归纳):
- 成功一律
HTTP 200+ 二进制流;Content-Type随产物类型(application/pdf/application/octet-stream/text/markdown…); Content-Disposition形如form-data; name="attachment"; filename="<原名>_<操作>.pdf",多文件产物(拆分、提取图片)为 zip 包(application/octet-stream);- 响应默认带
Cache-Control: private, no-store、X-Frame-Options: DENY、X-Content-Type-Options: nosniff安全头,客户端不应缓存产物。
分页与过滤约定(实测 OpenAPI 参数清单):管理类列表端点用 page + size(如 GET /api/v1/audit/data?page=0&size=2),付费侧 ui-data 组用 page/pageSize/limit;文件处理类端点无分页概念(单请求单任务)。社区版调用 audit 分页端点受许可限制(5.6 节实测 403)。
幂等与重试:处理类端点天然幂等(同一输入产出同一结果),网络超时后直接重发即可;大文件转换(OCR/压缩)耗时可达数十秒,curl 侧建议 -m 300 设超时上限,服务端对应超时由配置篇 5.5 节 processExecutor.timeoutMinutes.* 管理(默认 20–30 分钟)。
七、常见问题
Q1:处理端点返回 400 且响应体为空?
最常见是必填 multipart 参数缺失。实测案例:/api/v1/convert/pdf/text 不带 outputFormat 时稳定返回 400、0 字节(5.4 节补齐 outputFormat=txt 后 200)。逐个端点核对必填字段(文件 fileInput、输出格式、页码等),参数名以 OpenAPI 描述为准。
Q2:401 {"error":"Authentication required"} 但确实带了 Key?
三步排查:头名是否精确为 X-API-KEY(全大写连字符);Key 是否被轮换过(update-api-key 后旧值立即失效);端点是否本身要求会话而非 API Key(管理类 admin 域端点部分仅限会话登录)。
Q3:合并/转换大文件超时或 502?
自托管直连服务时先确认是服务端慢还是中间有反代超时:直连 curl 同请求复测;服务端处理耗时受 processExecutor.timeoutMinutes.*(默认 30 分钟)约束,一般不会先超时。经 Nginx 等反代时同步调大 proxy_read_timeout 与 client_max_body_size(上传限制另见配置篇 Q5)。
Q4:This endpoint is disabled.(403)?
metrics.enabled: false 所致(配置篇 3.3 节实测:uptime/load/requests 等信息接口 403、status 保留)。改回 true 并重启服务。
Q5:This endpoint requires an Enterprise license(403)?
调用了付费端点(audit 导出、S3 存储配置、集群管理等 proprietary/enterprise 能力)。社区版在免费四组(general/convert/security/misc)+ info/auth/user 内完成绝大多数集成。
Q6:响应文件名乱码或不对?
取 Content-Disposition 的 filename 值(服务端按「原名_操作后缀」生成);curl -o 自定义文件名不影响该头,用 curl -w '%{filename_effective}' 配合 --remote-name 可自动采用服务端命名。
八、参考链接
- 官方在线 API 文档(Scalar):https://registry.scalar.com/@stirlingpdf/apis/stirling-pdf-processing-api/
- 服务内置 Swagger UI:http://192.168.146.128:8129/swagger-ui/index.html(自托管实例)
- 官方仓库(API 源码与 OpenAPI 描述):https://github.com/Stirling-Tools/Stirling-PDF
- 本专栏系列文档:《Stirling-PDF 3.2.0 介绍与选型指南》、《Stirling-PDF 3.2.0 Docker Compose 部署指南》、《Stirling-PDF 3.2.0 配置参数详解》(metrics/processExecutor 等开关与超时)