เมนู
Async API

Pilio API Documentation

Use permanent API keys to create asynchronous image watermark removal and GPT Image 2 tasks. API calls reuse your existing Pilio credits and task limits.

公共基础

Pilio API 当前提供异步任务接口:创建任务后立即返回任务 ID,再通过任务查询接口轮询状态并读取结果。

Pilio API 异步接口使用流程:上传文件、创建任务、轮询结果、下载文件
异步接口推荐流程:先准备文件 ID,再创建任务,随后轮询状态和结果,最后下载输出文件。

鉴权

Base URL
https://pilio.ai
Content-Type
application/json
认证方式
Authorization: Bearer <API Key> 或 X-API-Key: <API Key>

Send your API key with every request:

Authorization: Bearer pilio_sk_your_key_here
# or
X-API-Key: pilio_sk_your_key_here

`X-API-Key` is also accepted for compatibility. API keys are permanent until you revoke them in your account.

5 分钟接入

这段流程按 AI agent 生成代码最容易出错的顺序写:先拿文件 ID,再上传对象,最后创建任务。可以直接复制给代码生成器作为集成约束。

# 1) 创建上传文件记录。这个示例固定选择单文件上传:upload_mode=simple
#    返回 data.items[0].id 和 data.items[0].upload_url
curl -X POST "https://pilio.ai/v1/files/batch-create"   -H "Authorization: Bearer pilio_sk_your_key_here"   -H "Content-Type: application/json"   -d '{"files":[{"nanoid":"V1StGXR8_Z5jdHi6B-myT","name":"reference.png","type":"png","size":1024}],"upload_mode":"simple","storage_intent":"temporary"}'

# 2) 上传文件到预签名地址。注意:这里不要带 Pilio API Key
#    单文件 upload_url 上传完成后,直接进入第 3 步,不要调用 /v1/files/:id/complete
curl -X PUT "<upload_url>"   -H "Content-Type: image/png"   --data-binary @reference.png

# 3) 用文件 ID 创建任务
curl -X POST "https://pilio.ai/v1/images/remove-watermark"   -H "Authorization: Bearer pilio_sk_your_key_here"   -H "Content-Type: application/json"   -d '{"image_file_id":"<file_id>","mode":"auto"}'

# 4) 轮询任务状态,直到 status 为 Succeeded 或 Failed
curl -H "Authorization: Bearer pilio_sk_your_key_here"   "https://pilio.ai/v1/tasks/<task_id>/status"

# 5) 获取结果并下载 data.files[0].download_url
curl -H "Authorization: Bearer pilio_sk_your_key_here"   "https://pilio.ai/v1/tasks/<task_id>/result"

TypeScript 单文件上传示例

const API_BASE = "https://pilio.ai";
const apiKey = process.env.PILIO_API_KEY!;

async function pilioFetch(path: string, init: RequestInit = {}) {
  const response = await fetch(API_BASE + path, {
    ...init,
    headers: {
      Authorization: `Bearer ${apiKey}`,
      "Content-Type": "application/json",
      ...init.headers,
    },
  });

  const payload = await response.json();
  if (!response.ok || payload.code !== 200) {
    throw new Error(payload.message || `Pilio API failed: ${payload.code}`);
  }
  return payload.data;
}

async function removeWatermark(file: File) {
  const created = await pilioFetch("/v1/files/batch-create", {
    method: "POST",
    body: JSON.stringify({
      files: [{
        nanoid: crypto.randomUUID().replaceAll("-", "").slice(0, 21),
        name: file.name,
        type: file.name.split(".").pop()?.toLowerCase(),
        size: file.size,
      }],
      upload_mode: "simple",
      storage_intent: "temporary",
    }),
  });

  const source = created.items[0];

  if (source.upload_url) {
    // 预签名地址不需要 Pilio API Key
    await fetch(source.upload_url, {
      method: "PUT",
      headers: { "Content-Type": file.type || "application/octet-stream" },
      body: file,
    });
  } else {
    throw new Error("This sample only covers single upload_url uploads. Use upload_urls + complete for multipart files.");
  }

  const task = await pilioFetch("/v1/images/remove-watermark", {
    method: "POST",
    body: JSON.stringify({ image_file_id: source.id, mode: "auto" }),
  });

  while (true) {
    await new Promise((resolve) => setTimeout(resolve, 2000));
    const status = await pilioFetch(task.status_url);
    if (status.status === "Failed") throw new Error(status.error_message || "Task failed");
    if (status.status === "Succeeded") break;
  }

  const result = await pilioFetch(task.result_url);
  return result.files?.[0]?.download_url || result.zip_file?.download_url;
}

AI 接入提示

  • 只把 Pilio API Key 发给 https://pilio.ai/v1/*;不要把 API Key 发给 upload_urlupload_urlsdownload_url
  • 创建任务时传 items[].id,不要传 nanoidupload_idupload_url
  • batch-create 返回字段决定上传路径:有 upload_url 就走单文件 PUT,有 upload_urls 才走分片 PUT + complete。
  • 单文件 upload_url 上传完成后不要调用 complete;只有返回 upload_urls 的分片上传才调用 /v1/files/:id/complete
  • 先等所有预签名 PUT 请求成功,再创建任务;否则任务创建可能返回 source_file_upload_not_completed
  • 轮询时以 Succeeded / Failed 为终态;不要解析自然语言 message 判断任务状态。

响应外壳

所有成功响应都包在 codemessagedata 中;业务字段位于 data

{
  "code": 200,
  "message": "success",
  "data": { ... }
}

文件上传与下载

图片编辑、图片/PDF 处理接口需要先拿到文件 ID。推荐流程是:创建文件记录 → PUT 预签名地址上传文件 → 用返回的文件 ID 创建任务 → 查询任务结果 → 下载输出文件。

  • upload_mode=simple 固定选择单文件上传;返回 upload_url 时,直接把文件二进制用 PUT 上传到该地址,不需要再调用 complete。
  • upload_mode=multipart 固定选择分片上传;返回 upload_urls 时,按数组顺序分片 PUT,收集每个分片响应头里的 ETag 后调用完成接口。
  • upload_mode=auto 由服务端按文件大小选择上传方式;客户端应以返回字段为准,而不是自己猜测是否分片。
  • 上传到预签名地址时不需要携带 Pilio API Key;只需要按对象存储要求设置文件内容和必要的 Content-Type
  • 任务成功后调用 result_url,从 files[].download_urlzip_file.download_url 获取临时下载地址。

主流程边界

  • batch-create 只创建文件记录和上传地址,不代表文件内容已经上传完成。
  • 返回 upload_url:执行一次 PUT,成功后直接用 items[].id 创建任务,不调用 /v1/files/:id/complete
  • 返回 upload_urls:每个分片 PUT 成功后,必须调用 /v1/files/:id/complete 合并对象,再用 items[].id 创建任务。
  • 创建任务时只传文件 ID,例如 image_file_idimage_file_idspdf_file_id;不要传 nanoidupload_urlupload_urlsupload_id
  • 上传地址过期或分片上传丢失时,重新调用 batch-create 获取新的上传地址。

上传限制

字段类型必填说明 / 可选值
单次创建文件数integer固定限制最多 500 个文件。
单文件大小bytes固定限制最大 2 GB。
分片阈值bytes固定规则upload_mode=auto 时,文件大于 5 MB 通常返回 upload_urls;simple 会固定尝试单文件上传。
上传地址有效期duration固定规则upload_url / upload_urls 约 2 小时有效,过期后重新 batch-create。
下载地址有效期duration固定规则download_url 约 24 小时有效,过期后重新查询 result_url 获取新地址。

POST/v1/files/batch-create

创建上传文件记录并返回预签名上传地址。根据 upload_mode 和文件大小返回单文件 upload_url 或分片 upload_urls。

请求示例
{
  "files": [
    {
      "nanoid": "V1StGXR8_Z5jdHi6B-myT",
      "name": "reference.png",
      "type": "png",
      "size": 1024
    }
  ],
  "upload_mode": "simple",
  "storage_intent": "temporary"
}
传入参数
字段类型必填说明 / 可选值
filesSourceFile[]要创建上传凭证的文件列表,至少 1 个。
files[].nanoidstring客户端生成的 21 位 nanoid,用于把返回文件和本地文件对应起来。
files[].namestring原始文件名,最长 300 字符;后缀需与 type 匹配。
files[].typeenum文件扩展名类型,例如 jpg、jpeg、png、webp、pdf。
files[].sizeinteger文件大小,单位 byte;auto 模式会用它判断返回 upload_url 还是 upload_urls。
upload_modeenumauto、simple 或 multipart。simple 固定返回单文件 upload_url;multipart 固定返回 upload_urls;auto 由服务端按大小选择。
storage_intentenumtemporary 或 permanent;图片/PDF 处理输入通常使用 temporary。
返回 data 字段
字段类型必填说明 / 可选值
totalinteger本次成功创建的文件数量。
itemsFile[]文件记录列表;用返回的 id 作为后续任务的 image_file_id、image_file_ids 或 pdf_file_id。
items[].idstring文件 ID。
items[].nanoidstring请求中的 nanoid,便于客户端配对。
items[].statusFileStatus初始为 Pending;必须先完成预签名 PUT 上传,再用文件 ID 创建任务。
items[].upload_urlstring单文件时是单文件 PUT 上传地址;直接把文件二进制 PUT 到该地址。使用这个字段时不需要调用 complete。
items[].upload_urlsstring[]分片上传时是分片 PUT 上传地址数组;按顺序上传每个分片,随后才调用 complete。
items[].upload_idstring分片上传时是对象存储分片上传 ID,仅用于排查;完成接口只需要 parts。

POST/v1/files/:id/complete

完成大文件分片上传(可选)。只有 batch-create 返回 upload_urls 时才需要调用;返回 upload_url 的单文件上传不要调用。

请求示例
{
  "parts": [
    { "part_number": 1, "etag": ""etag-from-upload-response"" }
  ]
}
传入参数
字段类型必填说明 / 可选值
idstring(path)分片上传时是文件 ID,即 batch-create 返回的 items[].id;单文件 upload_url 上传不要调用此接口。
partsCompletedPart[]分片上传时是已成功上传的分片列表,必须从 1 开始连续。
parts[].part_numberinteger分片上传时是分片序号,从 1 开始。
parts[].etagstring分片上传时是上传每个分片后对象存储返回的 ETag 响应头。
返回 data 字段
字段类型必填说明 / 可选值
datanull/object完成成功即表示分片对象已合并;单文件 upload_url 上传不需要调用此接口。

下载结果文件

  • 先轮询 GET /v1/tasks/:id/status,直到任务状态为 Succeeded
  • 再调用 GET /v1/tasks/:id/result,读取返回的 download_url
  • download_url 是对象存储临时签名地址,过期后重新查询 result 即可刷新。

任务查询

All creation endpoints return immediately with a task ID.

{
  "code": 200,
  "message": "success",
  "data": {
    "task_id": "2048...",
    "status": "Processing",
    "status_url": "/v1/tasks/2048.../status",
    "result_url": "/v1/tasks/2048.../result",
    "created_at": "2026-04-25T12:00:00Z"
  }
}

Poll `status_url` until the task reaches `Succeeded` or `Failed`, then read result files from `result_url`.

GET/v1/tasks/:id/status

查询任务状态。:id 是创建接口返回的 task_id。

请求示例
无请求体。
传入参数
字段类型必填说明 / 可选值
idstring(path)任务 ID。
返回 data 字段
字段类型必填说明 / 可选值
task_idstring任务 ID。
statusTaskStatusPending、Processing、Succeeded、Failed。
error_typestring失败分类,仅失败时通常存在。
error_messagestring失败说明,仅失败时通常存在。
created_atstring(date-time)任务创建时间。
updated_atstring(date-time)最近更新时间。
result_urlstring结果查询地址。

GET/v1/tasks/:id/result

查询任务结果。任务成功后会返回可下载文件。

请求示例
无请求体。
传入参数
字段类型必填说明 / 可选值
idstring(path)任务 ID。
返回 data 字段
字段类型必填说明 / 可选值
task_idstring任务 ID。
statusTaskStatus如果还未 Succeeded,files 可能为空。
error_typestring失败分类。
error_messagestring失败说明。
filesResultFile[]单个或多个输出文件。
zip_fileResultFile批量输出时可能提供 zip。

公共结构

TaskStatus 可选值

Pending已创建,等待 Worker 调度。
Processing正在处理;客户端应继续轮询 status_url。
Succeeded处理成功;可调用 result_url 获取结果文件。
Failed处理失败;读取 error_type 和 error_message。

ResultFile 字段

字段类型必填说明 / 可选值
idstring文件 ID。
namestring文件名。
typestring文件类型。
sizeinteger文件大小,单位 byte。
download_urlstring临时下载地址,仅成功结果会签发。

错误处理

失败响应仍使用同一层响应外壳。AI 生成代码时应优先判断 code !== 200,再读取 messagedata;不要通过自然语言 message 推断业务状态。

{
  "code": 1402,
  "message": "Invalid token",
  "data": null
}

常见错误

字段类型必填说明 / 可选值
1402Unauthorized常见API Key 缺失、无效或已撤销;检查 Authorization / X-API-Key。
1505Too many files上传单次创建文件数量超过系统限制;拆分请求。
1510Multipart upload not found上传分片上传不存在或已过期;重新创建上传文件并重传分片。
source_file_upload_not_completedBadRequest任务创建文件对象还没有上传完成;先完成 PUT,再创建任务。
quota_or_inflight_limitLimit计费积分不足、套餐限制或 Pending + Processing 在途任务超过 20。

轮询建议

  • 初始每 2 秒查询一次 status_url;长任务可退避到 5 秒。
  • SucceededFailed 是终态,进入终态后停止轮询。
  • 不要并发轮询同一个任务;客户端应保存 task_id,刷新页面后可继续查询。

OpenAPI 文件

已提供独立的公开 API OpenAPI 文件,可下载后导入 Postman、Apifox、Insomnia、Bruno 等 API 测试工具,也可以交给 AI 读取接口结构。

下载 /developers/pilio-openapi.json

如果你只需要把接口导入 API 测试工具,直接下载上面的 OpenAPI JSON 即可。页面正文用于快速阅读,OpenAPI 文件用于测试、调试和作为生成代码的结构化真源。

导入测试工具推荐
下载 OpenAPI JSON 后,可直接导入 Postman、Apifox、Insomnia 或 Bruno,并在工具里配置 API Key。
交给 AI 读接口
把 OpenAPI JSON 和本页快速接入示例一起提供给 AI,让它按你的代码风格生成薄封装。
版本稳定性
公开 API 会尽量保持向后兼容;新增能力优先通过新字段或新路径扩展,避免破坏已有集成。

SDK

Pilio 目前不维护官方 SDK。现在大量接入代码会由 AI 生成,官方维护多语言 SDK 反而容易滞后;推荐把 OpenAPI JSON 作为真源,按项目语言生成类型、请求方法,或让 AI 直接基于接口描述写薄封装。

常用生成工具

OpenAPI Generator
适合 Java、Go、Python、TypeScript 等多语言客户端生成。
orval
适合 TypeScript 前端项目,生成类型、请求函数和 React Query 集成。
openapi-typescript
适合只需要 TypeScript 类型,再让 AI 或现有 fetch 封装生成调用代码。
Kiota
适合 .NET、TypeScript、Go 等项目生成结构化 API 客户端。

推荐接入方式

  • 后端服务:让 AI 基于 OpenAPI JSON 生成一个很薄的 client,只封装鉴权、错误外壳、轮询和下载。
  • 前端项目:优先生成 TypeScript 类型,再接入你已有的 fetch / axios / React Query 封装。
  • 不建议直接依赖第三方生成器产出的厚 SDK 作为业务核心;保留薄封装更容易审查和修改。

工具接口

GPT Image 2

POST/v1/images/gpt-image-2/generations

创建 GPT Image 2 文生图任务。

请求示例

{
  "prompt": "A cinematic product photo of an orange perfume bottle",
  "aspect_ratio": "3:2",
  "output_count": 2,
  "quality": "high"
}

传入参数

字段类型必填说明 / 可选值
promptstring生成/编辑提示词,最长 32000 字符。
negative_promptstring负向提示词,最长 32000 字符。
aspect_ratioenum文生图必填;图像编辑可选1:1、3:2、2:3、3:4、4:3、4:5、5:4、16:9、9:16、21:9、auto。
output_countinteger输出张数,可选 1、2、4。
resolutionenum可选 0.5K、1K、2K、4K。
qualityenum可选 low、medium、high。
preprocess_modeenum可选 off、auto。

返回 data 字段

字段类型必填说明 / 可选值
task_idstring异步任务 ID。
statusTaskStatus初始通常为 Processing。
status_urlstring任务状态查询地址。
result_urlstring任务结果查询地址。
created_atstring(date-time)任务创建时间。

POST/v1/images/gpt-image-2/edits

创建 GPT Image 2 图像编辑任务,可传 1-16 张参考图。

请求示例

{
  "prompt": "Turn this reference into a studio product photo",
  "image_file_ids": ["123456789", "123456790"],
  "aspect_ratio": "auto",
  "quality": "medium"
}

传入参数

字段类型必填说明 / 可选值
image_file_idsstring[]参考图片文件 ID,1-16 个;支持 jpg、jpeg、png、webp。
promptstring生成/编辑提示词,最长 32000 字符。
negative_promptstring负向提示词,最长 32000 字符。
aspect_ratioenum文生图必填;图像编辑可选1:1、3:2、2:3、3:4、4:3、4:5、5:4、16:9、9:16、21:9、auto。
output_countinteger输出张数,可选 1、2、4。
resolutionenum可选 0.5K、1K、2K、4K。
qualityenum可选 low、medium、high。
preprocess_modeenum可选 off、auto。

返回 data 字段

字段类型必填说明 / 可选值
task_idstring异步任务 ID。
statusTaskStatus初始通常为 Processing。
status_urlstring任务状态查询地址。
result_urlstring任务结果查询地址。
created_atstring(date-time)任务创建时间。

图片去水印

POST/v1/images/remove-watermark

创建图片去水印任务,支持自动识别或手动框选区域。

请求示例

{
  "image_file_id": "123456789",
  "mode": "manual",
  "boxes": [{ "x1": 10, "y1": 15, "x2": 60, "y2": 70 }]
}

传入参数

字段类型必填说明 / 可选值
image_file_idstring待去水印图片文件 ID。
modeenumauto 自动识别;manual 手动框选。默认 auto。
boxesBox[]manual 时是手动框选区域,1-5 个。坐标为图片宽高百分比。
boxes[].x1integermanual 时是左上角 X,0-100。
boxes[].y1integermanual 时是左上角 Y,0-100。
boxes[].x2integermanual 时是右下角 X,0-100。
boxes[].y2integermanual 时是右下角 Y,0-100。

返回 data 字段

字段类型必填说明 / 可选值
task_idstring异步任务 ID。
statusTaskStatus初始通常为 Processing。
status_urlstring任务状态查询地址。
result_urlstring任务结果查询地址。
created_atstring(date-time)任务创建时间。

去水印说明

  • auto 模式适合水印位置明显、希望自动识别处理的图片,不需要传 boxes
  • manual 模式适合你已知道水印区域的位置,需要传 1-5 个 boxes
  • boxes 坐标使用百分比而不是像素,范围为 0-100,便于不同分辨率图片复用同一标注方式。
  • 建议让 x1 < x2y1 < y2,并让框选区域略大于水印本身,避免边缘残留。
  • 接口创建的是异步任务;提交后继续调用 status_urlresult_url 获取处理结果。

抠图

POST/v1/images/remove-background

创建图片抠图任务,输出透明背景图片。

请求示例

{
  "image_file_id": "123456789",
  "industry_type": "portrait",
  "quality_type": "original",
  "trim_transparent_background": true
}

传入参数

字段类型必填说明 / 可选值
image_file_idstring待抠图图片文件 ID;支持 jpg、jpeg、png、webp、heic。
industry_typeenumportrait、product、general 等;默认 portrait。
quality_typeenumoriginal 或 fast 等;默认 original。
trim_transparent_backgroundboolean是否裁切多余透明背景,默认 false。

返回 data 字段

字段类型必填说明 / 可选值
task_idstring异步任务 ID。
statusTaskStatus初始通常为 Processing。
status_urlstring任务状态查询地址。
result_urlstring任务结果查询地址。
created_atstring(date-time)任务创建时间。

图片超分

POST/v1/images/upscale

创建图片超分任务,提升图片分辨率和清晰度。

请求示例

{
  "image_file_id": "123456789",
  "method": "ai_super_resolution",
  "preset": "hd",
  "type": "2X",
  "enhance_face": true,
  "enhance_quality": true
}

传入参数

字段类型必填说明 / 可选值
image_file_idstring待超分图片文件 ID;支持 heic、jpg、png、webp。
methodenumai_super_resolution、super_resolution、enhance;默认 ai_super_resolution。
presetenumauto 或 hd;默认 auto。
typestring超分倍率,默认 2X。
enhance_faceboolean是否增强人脸细节。
enhance_qualityboolean是否增强整体画质。
enhance_textboolean是否增强文字清晰度。

返回 data 字段

字段类型必填说明 / 可选值
task_idstring异步任务 ID。
statusTaskStatus初始通常为 Processing。
status_urlstring任务状态查询地址。
result_urlstring任务结果查询地址。
created_atstring(date-time)任务创建时间。

PDF 去水印

POST/v1/pdfs/remove-watermark

创建 PDF 去水印任务,支持结构化去水印和 AI 逐页重建。

请求示例

{
  "pdf_file_id": "123456789",
  "mode": "editable"
}

传入参数

字段类型必填说明 / 可选值
pdf_file_idstring待去水印 PDF 文件 ID。
modeenumeditable 结构化去水印;ai 逐页图片重建。默认 editable。

返回 data 字段

字段类型必填说明 / 可选值
task_idstring异步任务 ID。
statusTaskStatus初始通常为 Processing。
status_urlstring任务状态查询地址。
result_urlstring任务结果查询地址。
created_atstring(date-time)任务创建时间。

限制与计费

上传限制

字段类型必填说明 / 可选值
单次创建文件数integer固定限制最多 500 个文件。
单文件大小bytes固定限制最大 2 GB。
分片阈值bytes固定规则upload_mode=auto 时,文件大于 5 MB 通常返回 upload_urls;simple 会固定尝试单文件上传。
上传地址有效期duration固定规则upload_url / upload_urls 约 2 小时有效,过期后重新 batch-create。
下载地址有效期duration固定规则download_url 约 24 小时有效,过期后重新查询 result_url 获取新地址。
  • Credits are deducted from your normal Pilio credit balance.
  • 图片去水印按图片计费:1 credits / 张。
  • 抠图按图片计费:1 credits / 张。
  • 图片超分按图片计费:3 credits / 张。
  • PDF 去水印结构化模式按文件计费:2 credits / 文件。
  • PDF 去水印 AI 模式按页计费:1 credits / 页。
  • GPT Image 2 无水印模式按输出图计费:2 credits / 张。
  • No separate API usage ledger is created; credit records remain the source of truth.
  • Web and API tasks share the same in-flight pool: `Pending + Processing <= 20`.
  • The first version only supports asynchronous APIs.
  • 完整功能价格可查看 功能价格表
  • 图片编辑、图片/PDF 处理接口需要传入文件 ID;如果你还没有文件 ID,请先调用 /v1/files/batch-create 创建上传地址并完成文件上传。