Zipline 4.8.2 常用操作与 API 详解

Zipline 4.8.2 REST API 实操手册:Token/Cookie 双认证、上传与选项头、分块续传、密码保护、短链 vanity、文件夹与统计接口的逐条实测回显,附 ziplinectl 管理 CLI 全 7 子命令详解。

ZiplineZipline2026/11/01

Zipline 4.8.2 常用操作与 API 详解

目标:给出 Zipline 4.8.2 对外接口的完整实操手册——认证方式、上传/短链/文件管理/统计各域的每个 endpoint、请求示例与实测响应逐行照抄,并沉淀错误码、限流、分块续传、密码保护等行为的真实证据。Zipline 的服务端管理 CLI(ziplinectl)面较窄(7 个子命令),本文末章一并详解。

一、环境信息

  • 被测版本:Zipline 4.8.2(/api/version 实测 "details":{"version":"4.8.2","sha":"5fe2792"})
  • 实机环境:Ubuntu 24.04.5 LTS,Docker 29.9.2 + Compose v5.6.1,PostgreSQL 16
  • 实例地址:http://192.168.1.172:8142(下文 curl 均用 http://127.0.0.1:8142 形态书写)
  • 演示账号:超管 root / q1w2e3r4,普通用户 demo / q1w2e3r4(USER 角色,用于限流对照)
  • 部署过程见 《Zipline 4.8.2 Docker Compose 部署指南》,配置项含义见 《Zipline 4.8.2 配置参数详解》

二、前置条件

  1. 实例已完成首次初始化(/auth/setup 建好超管)。全新实例上 curl -s http://127.0.0.1:8142/api/setup 返回 {"firstSetup":true};已初始化的实例返回 403:
{"error":"E9001: Setup already completed","code":9001,"statusCode":403}
  1. 拿到 API Token:登录后台 → 点右上角头像 → Copy token。Token 是用 CORE_SECRET 做 AES-256-GCM 加密的字符串,形如 <base64时间戳>.<密文>(实测样例长度 273 字符,形如 MTc5MzUyMDE3OTIyOA==.YzYzZWFjNGNl...)。后台用户设置页也能查看/重置 Token;重置 Token 会使旧 Token 全部失效。
  2. 服务器上有 curl(本文全部用 curl 8.5.0 实测)。

三、API 总览

3.1 基本约定

  • 所有接口挂在 /api 前缀下;文件直链走 FILES_ROUTE(本实例 /f),短链走 URLS_ROUTE(本实例 /s)。
  • 认证两种:API Token(Authorization: <token> 头)与会话 Cookie(zipline_session=...,登录接口下发)。二者等价可用,实测同一接口 Token 与 Cookie 都能过。
  • 错误统一结构(实测多个真实样本):
{"error":"E1062: No files in multipart/form-data request","code":1062,"statusCode":400}
{"error":"E2000: Invalid login session","code":2000,"statusCode":401}
{"error":"E3005: Incorrect password","code":3005,"statusCode":403}
{"error":"E3018: Invalid access token provided.","code":3018,"statusCode":403}
  • 限流:/api/upload 与 /api/user/urls 默认每分钟 10 次/用户,管理员豁免(实测见 §5.1);/api/user/files/:id/password 是每秒 2 次的独立限流(实测连发第二次直接 429)。

3.2 路由地图(源码实查)

src/server/routes/api 下的完整路由树,按域归类:

域路由
认证/api/auth/login、/logout、/register、/invites/*、/oauth/<provider>、/webauthn
上传/api/upload、/api/upload/partial
文件/api/user/files(列表/批量)、/api/user/files/:id(查/改/删)、/:id/password、/:id/raw、/incomplete、/transaction
短链/api/user/urls、/api/user/urls/:id、/:id/password
用户/api/user、/token、/stats、/recent、/activity、/sessions、/avatar、/export、/mfa/totp、/mfa/passkey、/folders*、/tags*
实例/api/setup、/api/healthcheck、/api/version、/api/stats、/api/server/settings、/api/server/status、/api/server/folder、/api/server/themes、`/api/server/import/v3

四、认证与首次调用

curl -s -c cookiejar.txt -X POST http://127.0.0.1:8142/api/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"demo","password":"q1w2e3r4"}'

实测回显(节选):

{"user":{"id":"nqcbgnte8j43i2a92nuzosu1","username":"demo","createdAt":"2026-11-01T07:56:37.978Z","updatedAt":"2026-11-01T07:56:37.978Z","role":"USER","view":{},"quickLinks":[],"sessions":[{"id":"WZpY2hE4C1ntCPsMcC8Ap73U7B5qybWr","createdAt":"2026-11-01T07:56:37.983Z","ua":"curl/8.5.0",...

响应同时下发 Set-Cookie: zipline_session=Fe26.2*1*...。后续请求带 -H "Cookie: zipline_session=<值>" 即可(从 cookiejar 提取时注意 Netscape 格式第 7 列才是值,直接整行拼会 401——实测踩过)。

4.2 API Token 方式(推荐脚本用)

printf 'hello zipline\n' > d1demo.txt
curl -s -X POST http://127.0.0.1:8142/api/upload \
  -H "Authorization: <你的Token>" \
  -F 'file=@d1demo.txt'

实测回显:

{"files":[{"id":"ergkbw2h6xbvzg1rz7zsql4z","name":"2026-11-01_08:03:18.txt","type":"text/plain","url":"http://127.0.0.1:8142/f/2026-11-01_08%3A03%3A18.txt"}]}

url 即直链。本实例 FILES_DEFAULT_FORMAT=date,所以文件名按 YYYY-MM-DD_HH:mm:ss 生成(配置详解篇有命名格式全表)。

五、各 API 域详解

5.1 上传域 POST /api/upload

multipart 表单,字段名 file,可一次多文件(上限 FILES_MAX_FILE_SIZE/FILES_MAX_FILES_PER_UPLOAD)。

行为实测清单:

  1. 正常上传 → 200 + files 数组(§4.2)。
  2. 同一秒重名自动加后缀:连续上传时实测返回 2026-11-01_08:48:52.txt、2026-11-01_08:48:52-1.txt、2026-11-01_08:48:52-2.txt……不覆盖。
  3. 超限文件报错有误导性——上传 6MB 文件(上限 5mb)实测:
{"error":"E1062: No files in multipart/form-data request","code":1062,"statusCode":400}

实际原因是大小闸把超限 part 静默丢弃。2MB 文件同场上限下实测 200 成功。 4. 限流对照实测:root(SUPERADMIN)一分钟内 12 连传全部 200(adminBypass);demo(USER)12 连传前 10 次 200,第 11、12 次:

{"error":"Rate limit exceeded, retry in 1 minute","statusCode":429}

上传选项头(全部可选,加在 POST /api/upload 上;来源官方 upload-options 文档,其中带 ⭐ 的为本篇实测):

头作用
x-zipline-format ⭐本次命名格式(random/date/uuid/name/gfycat)
x-zipline-password ⭐给文件设访问密码
x-zipline-deletes-at过期时间,相对时长(1d)或 date=2025-01-01T00:00:00Z
x-zipline-max-views最大查看次数
x-zipline-folder上传进指定文件夹(ID)
x-zipline-filename直接指定文件名(优先级高于 format)
x-zipline-no-json响应改为纯文本 URL 逐行,方便管道
x-zipline-original-name保留原始文件名(下载时可见)
x-zipline-extensionless返回无扩展名直链(需服务端开启该特性)
x-zipline-domain用指定域名生成链接(可逗号列表随机)
x-zipline-image-compression-percent / -type图片压缩百分比/格式
x-zipline-file-extension覆盖文件扩展名
  1. 过期文件实测:带 x-zipline-deletes-at: 10s 上传,响应体直接回显到期时间 "deletesAt":"2026-11-01T08:58:04.661Z";到期前文件可正常访问,到期后访问原始流接口实测返回:
{"error":"E9002: Not found","code":9002,"statusCode":404}

到期即拒(访问层拦截),物理删除由后台任务在 TASKS_DELETE_INTERVAL 周期内完成。

5.2 分块上传 POST /api/upload/partial

大文件绕反代请求体限制的正解。每请求恰好一片,头:Content-Range: bytes start-end/total(end 含)、x-zipline-p-content-length(整文件字节数)、x-zipline-p-content-type、x-zipline-p-filename、x-zipline-p-lastchunk、续传带 x-zipline-p-token。

全流程实测(32 字节文件切两片,每片 16 字节):

第一片(不带 token):

curl -s -X POST http://127.0.0.1:8142/api/upload/partial \
  -H "Authorization: <你的Token>" \
  -H 'Content-Range: bytes 0-15/32' \
  -H 'x-zipline-p-content-length: 32' \
  -H 'x-zipline-p-content-type: text/plain' \
  -H 'x-zipline-p-filename: persist32.txt' \
  -H 'x-zipline-p-lastchunk: false' \
  -F 'file=@p1.bin'

实测回显:

{"files":[],"partialSuccess":true,"partialToken":"5d97d4a1a847299945c014b6.d93223731d9d8437d4f95d067a688c490ff8b29629dd8d68e2a3b5774295ce88113de12c423a4d4edf8ab38ea26a738eea9130aebae2df8b49663d9d9df74ae7.24119a2ee113e7a61584ae86bf9196b8"}

第二片(带上一步返回的 partialToken,lastchunk: true)实测回显:

{"files":[{"id":"raoa0qqpi01ou1fhr2tm72xa","name":"2026-11-01_08:49:23.txt","type":"text/plain","url":"http://127.0.0.1:8142/f/2026-11-01_08%3A49%3A23.txt","pending":true}],"partialSuccess":true}

要点(官方文档 + 实测):token 一次性,每片响应都要换用新 token;续传 token 有效期 30 分钟,服务重启会丢未完成的会话;只有第一片吃上传限流额度;末片响应里的 pending:true 表示后台还在装配,完成状态查 GET /api/user/files/incomplete。

5.3 文件管理域

列表 GET /api/user/files?page=1(分页参数必填,实测缺省直接 400):

{"error":"querystring/page Invalid input: expected number, received NaN","statusCode":400,"code":1000,"issues":[{"keyword":"invalid_type","instancePath":"/page","schemaPath":"#/page/invalid_type","message":"Invalid type: expected number, received NaN"}]}

带 page=1 实测回显(节选):

{"page":[{"id":"jwkb77a2ecvxfmwqe0yjgadq","createdAt":"2026-11-01T08:50:10.652Z","deletesAt":null,"name":"2026-11-01_08:50:10.png","originalName":null,"size":74,"type":"image/png","views":0,"maxViews":null,"favorite":false,"password":true,"anonymous":false,...

删除 DELETE /api/user/files/:id——实测返回被删记录的完整 JSON:

{"id":"zyqwuva2gu5g49qefl2axhgu","createdAt":"2026-11-01T08:48:16.510Z","name":"2026-11-01_08:48:16.bin","size":2000000,"type":"application/octet-stream","views":1,"maxViews":null,"favorite":false,"folderId":null,"thumbnail":null,"tags":[]}

删除后访问原直链实测 404。

原始流 GET /api/user/files/:id/raw(属主认证,可 ?download=true 触发下载头)。无密码文件实测 200 直出字节;密码文件则必须再带 ?token=<访问token>(见 §5.4),否则实测 403 E3018: Invalid access token provided.。

5.4 密码保护文件全流程(实测)

上传时设密码:

curl -s -X POST http://127.0.0.1:8142/api/upload \
  -H "Authorization: <你的Token>" \
  -H 'x-zipline-password: q1w2e3r4' \
  -F 'file=@red.png'

实测返回 "url":"http://127.0.0.1:8142/f/2026-11-01_08%3A50%3A10.png"。此后行为(源码 files.dy.ts 与实测一致):

  • 直接访问 /f/... 的密码保护文件 → 实测 302 重定向到 /view/<name>(浏览器端弹密码框的页面);
  • 换访问 token:POST /api/user/files/:id/password,body {"password":"q1w2e3r4"},实测回显:
{"success":true,"token":"c35d3816a51471ead98bb7c2.eda4e176607ac005084f538fe65ade925b03f5759b8cde675e655264aecc213a19e482cebd0b0cef44747322e5ebe83bb591807cc76fe6575de8f491a176c31740e6eb8e2f70.1a5218625640b5cbff9d589ab92fffa5"}
  • 密码错误实测:{"error":"E3005: Incorrect password","code":3005,"statusCode":403};
  • 拿访问 token 调 raw:GET /api/user/files/:id/raw?token=<访问token>(同时带属主 API Token)实测 200 image/png 74 字节放行;不带 token 裸调 raw 实测 401 E2000。
  • 该密码接口限流每秒 2 次,实测连发第三次直接 429 Rate limit exceeded, retry in 2 seconds。

补充实测发现:text/* 类型文件访问 /f 直链一律 302 到 /view 渲染页(源码行为),纯文本粘贴分享靠这个页面;要拿原始字节用 raw 接口。

5.5 短链域

创建 POST /api/user/urls(body JSON):

curl -s -X POST http://127.0.0.1:8142/api/user/urls \
  -H "Authorization: <你的Token>" -H 'Content-Type: application/json' \
  -d '{"destination":"https://github.com/diced/zipline"}'

实测回显:

{"id":"jrre05ojv4kks9nnjd0t91fe","createdAt":"2026-11-01T08:03:18.323Z","code":"uNMfdrDa","vanity":null,"destination":"https://github.com/diced/zipline","views":0,"maxViews":null,"enabled":true,"userId":"x48cfnti1ir8atu0qbnha9oa","url":"http://127.0.0.1:8142/s/uNMfdrDa"}

code 长度 8 位(URLS_LENGTH=8 生效)。自定义 vanity:body 加 "vanity":"zipline-doc",实测返回 "vanity":"zipline-doc"、"url":"http://127.0.0.1:8142/s/zipline-doc"。

访问跳转实测:

curl -s -o /dev/null -w '%{http_code} -> %{redirect_url}\n' http://127.0.0.1:8142/s/zipline-doc
302 -> https://github.com/diced/zipline

短链同样支持 maxViews、密码(/api/user/urls/:id/password);删除走 DELETE /api/user/urls/:id。

5.6 实例信息域

接口认证实测回显
GET /api/healthcheck无{"pass":true}(FEATURES_HEALTHCHECK 关闭后此端点消失)
GET /api/version需登录不带 Token 实测 401 E2000;带 Token:{"data":{"isUpstream":false,"isRelease":true,"isLatest":true,"version":{"tag":"v4.8.2","sha":"5fe2792f...","url":"https://github.com/diced/zipline/releases/v4.8.2"},"latest":{"tag":"v4.8.2",...}},"details":{"version":"4.8.2","sha":"5fe2792"},"cached":false}
GET /api/stats需登录{"latest":{"id":"f1bdzd1jgxr9zm1fc990xr1h","data":{"users":2,"files":17,"fileViews":3,"urls":8,"urlViews":3,"storage":10276,"filesUsers":[{"username":"root","sum":17,"storage":10276,"views":3}],...,"types":[{"type":"image/webp","sum":1},...(后台 metrics 页图表的数据源)
GET /api/setup无全新实例 {"firstSetup":true};已初始化 403 E9001

⚠️ 再次纠偏:v4.8.2 没有 Prometheus 抓取端点,curl http://127.0.0.1:8142/metrics 实测返回 Next.js 页面 HTML。监控对接请用 /api/stats。

5.7 文件夹与批量操作

文件夹经 POST /api/user/folders 创建,实测回显(节选):

{"id":"vr5106d2opno70hey0mtmp4y","name":"d1folder","public":false,"allowUploads":false,"parentId":null,"userId":"x48cfnti1ir8atu0qbnha9oa","_count":{"children":0,"files":0}}

上传时带 x-zipline-folder: vr5106d2opno70hey0mtmp4y,随后查文件详情实测归属生效:

{"id": "woorsbwdofti9uzjaz5ot71r", "name": "2026-11-01_08:58:18.txt", "folderId": "vr5106d2opno70hey0mtmp4y"}

事后批量移动/删除/收藏走 POST /api/user/files/transaction(一次请求带 ID 列表)。把 public/allowUploads 打开的文件夹可让访客直传(配合 GET /api/server/folder/{idOrName} 查询),这是 Zipline 唯一的匿名上传通道。

5.8 ShareX 等客户端对接

后台上传页可导出 .sxcu 自定义上传器配置(含 Token 与选项头),ShareX 导入即用;iTake/iShare(macOS)、Flameshot、iOS 快捷指令的对接配置官方文档均有专页。手工对接本质就是 §4.2 + §5.1 的选项头组合。

六、分页/过滤通用约定

  • 列表接口(/api/user/files)分页参数 page 必填且必须是数字(实测缺省 400,见 §5.3),响应包在 page 数组里;
  • 时间字段一律 UTC ISO8601(2026-11-01T08:03:18.323Z);
  • ID 为 cuid2 短串,接口同时接受文件 ID 或 name(password 路由源码实测两者皆可)。

七、常见问题

  1. 带 Cookie 请求全 401——从 cookiejar 取错了列(Netscape 格式第 7 列才是值),或会话过期(实测过期会话报 E2000: Invalid login session)。脚本场景直接用 API Token 更稳。
  2. 上传报 E1062「没有文件」——先查大小限制(FILES_MAX_FILE_SIZE),不是真的没带文件(§5.1 实测)。
  3. 分块续传突然 400/丢会话——token 一次性 + 30 分钟过期 + 服务重启即丢,任一发生都要从第 0 字节重来(§5.2)。
  4. 密码文件脚本直取拿不到字节——/f 直链对密码文件一律 302 到 /view,程序化访问必须走 raw?token=(§5.4)。
  5. /api/version 401——它需要登录态,带 Token 即可(§5.6)。
  6. Prometheus 抓不到指标——v4 无此端点,用 /api/stats(§5.6 警告框)。

八、ziplinectl:服务端管理 CLI 详解

Zipline 的进程内 CLI 面只有 ziplinectl(7 个子命令,无第三方生态命令),不足以撑起独立命令篇,故并入本篇。--help 实测原文:

Usage: ziplinectl [options] [command]

control utility for zipline

Options:
  -V, --version                          output the version number
  -h, --help                             display help for command

Commands:
  read-config [options]                  output the configuration as json, exactly how Zipline sees it
  list-users [options]                   list all users
  set-user [options] <property> <value>
  import-dir [options] <directory>
  export-config [options]                export the current configuration as environment variables
  migrate-pglite [options] <directory>   copy an upgraded PostgreSQL database to a new PGlite directory; stop Zipline before cutover
  upgrade-pglite [options]               upgrade PGlite in place, retaining the old database; stop Zipline first
  help [command]                         display help for command

在 Compose 部署里统一用 docker compose exec zipline ziplinectl <子命令> 执行。逐命令说明:

命令关键参数实测/用途
read-config无输出最终生效配置 JSON(配置详解篇 §3.2 有全解)
export-config-y YAML、-d 含默认值只导出与默认值不同的键,适合生成精简 .env
list-users无实测回显 [{"id":"x48cfnti1ir8atu0qbnha9oa","username":"root","role":"SUPERADMIN"},{"id":"nqcbgnte8j43i2a92nuzosu1","username":"demo","role":"USER"}]
set-user <属性> <值>-i <id> 或 -u <用户名>改角色/重置密码,超管丢失自救通道
import-dir <目录>-i 归属用户、-f 目标文件夹、--skip-db非递归导入本地目录;换 S3 后端后重导入也用它
migrate-pglite <目录>—PostgreSQL → PGlite 迁移,先停服务
upgrade-pglite—PGlite 原地升级,保留旧库,先停服务

九、参考链接