PARTNER API · V1

API 接入文档

通过 Partner API 把 PDF 和图片转为可编辑 PPTX。包含鉴权、全元素转换、文件上传、任务查询、下载、额度和错误处理,以及可运行的 Python 示例。

英文客户文档见 English integration guide,可运行的全元素示例见 Python 客户端。

1. 基本信息

服务地址(下文接口路径已包含 /api/v1/partner):

https://2pptx.com

Partner API 用于合作方服务端提交 PDF / PNG / JPG / JPEG 文件,并转换为 PPTX。

全元素转换提交 {"mode":"full_element_editable"}。接入前需在后台为合作方开通全元素权限,并分配大于 0 的全元素月页数额度。普通转换额度可以为 0,不影响全元素。test 和 live Key 都会调用真实生产服务。

每个任务只接收一个文件,最大 36,700,160 字节(35 MiB)。不接收 PPTX 或多图片数组;需要把多张图片合成一个成品时,请先合并为 PDF。PDF 按实际页数计量,PNG / JPG / JPEG 按 1 页计量。

所有接口均为服务端调用。请不要在浏览器、App、小程序前端暴露 API Key。

2. 鉴权

每个接口都需要携带 Authorization 请求头:

Authorization: Bearer <partner_api_key>

示例:

Authorization: Bearer 2pptx_test_xxx

请使用创建时保存的完整 API Key。后台列表里的 key_prefix 仅用于识别 Key,不能用于鉴权;完整 Key 只在创建时展示一次。

3. 接入流程

  1. 初始化上传任务,获取文件上传 URL。
  2. 使用 PUT 上传源文件。
  3. 提交转换任务。
  4. 轮询任务状态。
  5. 任务完成后获取下载链接。
  6. 对下载链接发起 GET,保存 PPTX 文件。

使用 Python 示例完成全元素转换

将 partner_full_element.py 保存到本地,安装依赖:

python -m pip install httpx

通过服务端环境变量或密钥管理器设置 PARTNER_API_KEY,然后运行:

python partner_full_element.py --file sample.pdf --idempotency-key customer-order-001 --output result.pptx

每笔新转换使用新的 Idempotency-Key。重试时保持 Key、文件内容、文件名和元数据不变。示例会打印 partner_job_id,请保存它。任务已提交后,可用以下命令继续查询和下载:

python partner_full_element.py --job-id pj_your_job_id --output result.pptx

默认轮询两小时,可通过 --max-wait 14400 调整为四小时。轮询超时不会取消服务端任务,也不会自动新建订单。示例会校验下载文件的 PPTX ZIP 结构及页数,并拒绝覆盖已有文件;文字、版式和元素拆分效果仍需打开成品检查。OCR 可能漏字或识别错误,使用前请对照原稿核对名称、数字和页码。

4. 初始化上传任务

POST /api/v1/partner/jobs/init-upload

Headers:

Authorization: Bearer <partner_api_key>
Idempotency-Key: <本次转换请求唯一 ID>
Content-Type: application/json

Body:

{
  "file_name": "deck.pdf",
  "file_type": "pdf",
  "file_size": 1234567,
  "external_job_id": "your-job-123"
}

字段说明:

字段 必填 说明
file_name 是 非空原始文件名,不能只含空白。
file_type 是 文件类型,支持 pdf / png / jpg / jpeg。
file_size 是 文件的实际字节数,必须为正整数,最大 36,700,160 byte(35 MiB)。
external_job_id 否 合作方自己的任务 ID,便于双方排查。

未知 JSON 字段会返回 422 invalid_request。初始化时不传 mode,转换模式在提交时选择。页数额度也在提交时按模式检查:初始化成功不代表额度足够,普通额度为 0 或已用完不会阻止全元素任务初始化和提交。

Idempotency-Key 说明:

  • 这是合作方为“本次转换请求”生成的唯一字符串,用来防止网络重试时重复创建任务。
  • 初始请求时随机生成即可,推荐使用 UUID,也可以使用合作方系统里的订单 ID、任务 ID。
  • 同一个文件、同一次转换请求,如果需要重试,必须继续使用同一个 Idempotency-Key。
  • 新的转换任务必须换一个新的 Idempotency-Key。
  • 不要用同一个 Idempotency-Key 提交不同文件;元数据不同会返回 idempotency_conflict。
  • 服务端比对的是文件名、类型、大小和 external_job_id 等元数据,不是文件内容哈希;即使两个文件大小相同,也不能复用同一个请求 ID。

推荐示例:

Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000

或:

Idempotency-Key: order_123456

Response:

{
  "partner_job_id": "pj_xxx",
  "external_job_id": "your-job-123",
  "status": "awaiting_upload",
  "upload": {
    "method": "PUT",
    "url": "https://...",
    "expires_in": 1800
  }
}

只有任务仍处于 awaiting_upload 时才会返回 upload。如果使用同一个 Idempotency-Key 重放已经提交、处理中或已完成的任务,接口只返回 partner_job_id、external_job_id 和 status,不会再次返回上传 URL。

5. 上传文件

使用初始化接口返回的 upload.url 上传源文件:

PUT <upload.url>

请求体直接传文件二进制内容。

curl --fail-with-body --request PUT "$UPLOAD_URL" \
  --header "Content-Type: application/octet-stream" \
  --data-binary @deck.pdf

UPLOAD_URL 为初始化返回的完整签名 URL。不要使用 multipart 表单或 base64,也不要向存储地址发送 Partner API Key;签名 URL 本身就是临时凭证。

上传 URL 默认 30 分钟有效,需要在窗口内完成上传并提交。重放初始化不会延长原上传期限。如果任务已确认上传过期,请重新初始化并使用新的 Idempotency-Key;已提交的任务应继续查询。

任务提交后,服务端会把源文件锁定到内部处理位置。提交成功后请不要再覆盖原上传 URL;即使原上传 URL 尚未过期,后续覆盖也不会影响已提交任务的处理内容。

6. 提交转换任务

POST /api/v1/partner/jobs/{partner_job_id}/submit

Headers:

Authorization: Bearer <partner_api_key>
Content-Type: application/json

Body:

{
  "mode": "auto",
  "remove_notebooklm_watermark": true,
  "original_quality_export": false,
  "ocr_textbox_merge_beta": false
}

参数说明:

字段 必填 说明
mode 否 auto 为普通转换(默认);full_element_editable 为全元素转换,需提前开通并配置页数额度。
remove_notebooklm_watermark 否 是否移除 NotebookLM 水印,默认 true。
original_quality_export 否 是否启用高清导出,需要提前为该 Partner 开通。
ocr_textbox_merge_beta 否 是否启用文本框智能合并,需要提前为该 Partner 开通。

全元素请求请显式传 mode=full_element_editable。model 等拼写错误或其他未知字段会被拒绝,避免误执行默认的普通转换。

Response:

{
  "partner_job_id": "pj_xxx",
  "status": "queued"
}

普通和全元素任务都支持重复提交。同一个 partner_job_id 的有效参数一致时,返回原任务当前状态,包括处理中的任务和终态任务;参数不一致返回 409 submit_options_conflict。重试不会重新制作、修改已保存的参数或再次预占页数。未提交过且上传已过期的任务无法通过重试恢复。

全元素转换

继续使用同一套初始化上传、上传、提交、查询和下载接口,提交 Body 为:

{"mode": "full_element_editable"}

全元素模式使用固定的预处理和制作组合,请省略普通转换增强选项。首次提交时显式开启 original_quality_export、ocr_textbox_merge_beta 或关闭 remove_notebooklm_watermark 会返回 invalid_options。文件仍支持 PDF / PNG / JPG / JPEG,最大 35 MiB。

服务端会锁定源文件,并解析 PDF 实际页数(图片计 1 页)。实际页数不得超过合作方的单单页数上限,默认 100 页。提交时在事务内预占全元素页数额度;额度不足不会创建生产订单。全元素额度独立于普通、高清、文本框合并额度,其内部预处理不会再次扣这几类额度。

图片在创建全元素订单前需通过解码校验,且内容格式应与 file_type 一致。损坏图片或格式不匹配返回 400 invalid_source_file,不会占用全元素页数。PDF 无法解析时返回 page_count_failed。

订单与网站全元素订单共用生产队列,受总产能、Partner 全局全元素并发、单合作方全元素并发限制。提交可能立即返回 processing,也可能返回 queued。队列默认只允许所有 Partner 合计 1 单、每家最多 1 单进入生产;排队上限沿用 max_queued_jobs。test API Key 同样执行真实生产任务,并非免费沙箱。

查询全元素订单时,额外返回:

{
  "mode": "full_element_editable",
  "status": "processing",
  "phase": "preprocessing",
  "page_count": 3,
  "quota_status": "reserved"
}

以上只列出新增/关键字段,其余通用字段保持不变。phase 可为:

phase 含义
waiting_capacity 等待生产名额,对外 status=queued。
preprocessing 自动预处理。
preprocess_failed 预处理遇到问题,等待运营恢复。
awaiting_manual 等待 Runner 或人工处理。
manual_processing Runner 或人工制作中。
manual_recovery 等待恢复已领取的任务。
manual_failed Runner 遇到问题,等待运营恢复。
manual_review 等待人工检查。
completed 最终 PPTX 已交付。
failed / expired 已终止或处理期限已过。

恢复阶段仍返回 status=processing 并保留预占额度,不应自动新建订单。以顶层 status 判断终态:只有最终交付才会变为 completed;后台明确终止返回 cancelled 或 failed,处理过期返回 expired。后台取消、处理失败或处理过期释放预占额度;预处理文件不会通过 Partner 下载接口交付。

quota_status 为 reserved(已预占)、settled(交付已结算)或 released(已释放)。已交付文件替换、重复提交、重复交付不会再次扣页数。全元素已提交订单在处理中或终态重复提交相同 Body,均返回原订单状态;修改模式或参数返回 submit_options_conflict。终止订单不能通过重试重新启动,如需重新制作,应使用新的 Idempotency-Key 新建请求并重新预占。

月度已结算页数按交付时间归入自然月。尚未完成的预占跨月保留,并占用新月份可用额度;成品下载过期不会退回当月已结算页数。降低额度不会取消已有预占,但可用额度可能为 0。关闭合作方全元素权限会阻止新提交和新放行/领取,已接单任务仍可用相同参数重放提交、查询状态,已领取制作仍允许恢复和交付。停用整个合作方账户会拒绝所有 Partner API 请求;需要停止已接单任务时,由管理员明确终止。

处理期限与成品保留期限分开,排队/处理的 expires_at 随当前处理期限返回;交付后重置为从交付时刻开始计算的合作方成品保留期限(默认 24 小时)。没有固定交付时长承诺,恢复期请持续查询或联系运营。

成品中的文字可编辑,非文字内容通常为可单独选择的透明图片;不保证恢复原生矢量图形、图表数据或动画。全元素处理涉及图像模型和 Canva,参见数据处理说明。

7. 查询任务状态

GET /api/v1/partner/jobs/{partner_job_id}

Headers:

Authorization: Bearer <partner_api_key>

Response:

{
  "partner_job_id": "pj_xxx",
  "external_job_id": "your-job-123",
  "status": "completed",
  "file_name": "deck.pdf",
  "file_type": "pdf",
  "file_size": 1234567,
  "page_count": 12,
  "created_at": "2026-05-07T10:00:00+00:00",
  "submitted_at": "2026-05-07T10:01:00+00:00",
  "completed_at": "2026-05-07T10:03:00+00:00",
  "expires_at": "2026-05-08T10:03:00+00:00",
  "error": null
}

status 可能值:

状态 说明
awaiting_upload 等待上传源文件。
queued 已排队。
processing 正在转换。
completed 转换完成。
failed 转换失败。
expired 任务或结果已过期。
cancelled 任务已取消。

建议轮询间隔为 3-5 秒。状态为 completed 后再获取下载链接。

8. 获取下载链接

GET /api/v1/partner/jobs/{partner_job_id}/download

Headers:

Authorization: Bearer <partner_api_key>

Response:

{
  "download_url": "https://...",
  "expires_in": 3600
}

该接口返回 JSON,需再对 download_url 发起 GET,才能得到 PPTX 文件;下载时不要发送 Partner API Key。下载链接默认 1 小时有效,链接失效但任务仍未到期时,可以为同一任务重新获取链接。成品 API 访问窗口默认从交付起 24 小时,以返回的 expires_at 为准,请及时保存文件。API 到期、已签发链接的到期时间、存储生命周期删除和外部服务保留是不同概念,参见数据处理说明。

9. 配额说明

普通转换配额按已交付任务的 page_count 统计。未交付就失败、取消或处理过期的任务不计入配额;已交付成品的下载期限结束后,页数仍计入交付月份的普通、高清和文本框合并额度及用量报表。全元素采用上文独立的预占和结算规则。

月度配额按自然月重置,默认按北京时间 Asia/Shanghai 计算:每月 1 日 00:00 重置,不是创建后 30 天。

如果一个任务同时启用了:

  • original_quality_export = true
  • ocr_textbox_merge_beta = true

则该任务页数会同时计入:

  • 总月页数
  • 高清月页数
  • 合并月页数

10. 错误格式

应用生成的 Partner API 错误统一返回以下格式。存储服务和反向代理仍可能返回 XML、HTML 或其他非 JSON 错误,客户端需同时处理 HTTP 状态码。

{
  "error": {
    "code": "quota_exceeded",
    "message": "Monthly page quota exceeded."
  }
}

常见错误码:

code 说明
invalid_api_key API Key 无效。
partner_disabled Partner 已停用。
idempotency_key_required 缺少 Idempotency-Key。
idempotency_conflict 同一个 Idempotency-Key 被用于不同请求。
unsupported_file_type 文件类型不支持。
file_too_large 文件超过 35 MiB(36,700,160 字节)。
upload_expired 上传 URL 已过期。
upload_not_found 未找到已上传文件。
submit_options_conflict 重复提交时转换参数和第一次提交不一致。
option_not_enabled 请求的增强功能未开通。
invalid_options 全元素模式携带不兼容的普通转换选项。
page_count_failed 源文件页数解析失败。
invalid_source_file HTTP 400;图片损坏、无法解码或内容格式与 file_type 不匹配。
full_element_page_limit_exceeded 超过合作方全元素单单页数上限。
full_element_quota_exceeded 全元素额度不足,已计入未完成订单预占。
quota_exceeded 总月页数配额不足。
original_quality_quota_exceeded 高清月页数配额不足。
textbox_merge_quota_exceeded 文本框合并月页数配额不足。
too_many_queued_jobs 排队任务过多。
rate_limited 请求过于频繁。
job_not_found 任务不存在。
job_not_completed 任务尚未完成。
job_expired 任务或结果已过期。
invalid_request HTTP 422;缺少字段、字段值不合法、JSON 格式错误或含未知字段。
not_found / method_not_allowed HTTP 404 / 405;接口路径或请求方法错误。
storage_unavailable HTTP 503;存储暂时不可用,保留原请求并重试。
internal_error HTTP 500;内部错误,有限重试后仍失败请联系支持。
http_error 其他 HTTP 请求错误。

invalid_request 额外返回 error.details,每项包含 field、message 和 type,不回显字段值。完整的 HTTP 状态码对照见英文错误表。

HTTP 429 带 Retry-After: 60,存储不可用的 HTTP 503 带 Retry-After: 5。客户端按秒等待后使用原请求重试,并限制重试次数。超时或代理返回 502/504 不代表任务未创建:初始化应保留原 Idempotency-Key 和元数据,全元素提交应保留原任务 ID 和参数。先查询现有任务,不要因响应丢失自动创建新订单。

11. curl 示例

初始化上传:

curl -sS -X POST "https://2pptx.com/api/v1/partner/jobs/init-upload" \
  -H "Authorization: Bearer 2pptx_test_xxx" \
  -H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
  -H "Content-Type: application/json" \
  -d '{"file_name":"deck.pdf","file_type":"pdf","file_size":1234567,"external_job_id":"your-job-123"}'

提交转换:

curl -sS -X POST "https://2pptx.com/api/v1/partner/jobs/pj_xxx/submit" \
  -H "Authorization: Bearer 2pptx_test_xxx" \
  -H "Content-Type: application/json" \
  -d '{"mode":"full_element_editable"}'

查询状态:

curl -sS "https://2pptx.com/api/v1/partner/jobs/pj_xxx" \
  -H "Authorization: Bearer 2pptx_test_xxx"

获取下载链接:

curl -sS "https://2pptx.com/api/v1/partner/jobs/pj_xxx/download" \
  -H "Authorization: Bearer 2pptx_test_xxx"

保存文件(DOWNLOAD_URL 为上一接口返回的 download_url):

curl --fail-with-body "$DOWNLOAD_URL" --output result.pptx

开户、报价、结算、额度调整及异常终止请联系 support@2pptx.com。目前没有面向 Partner 的余额/用量查询、任务列表、取消或 webhook 接口;请保存任务 ID 并轮询。test Key 也会调用真实生产服务,应先约定测试额度。