Zipline 4.8.2 常用操作与 API 详解
Zipline 4.8.2 REST API 实操手册:Token/Cookie 双认证、上传与选项头、分块续传、密码保护、短链 vanity、文件夹与统计接口的逐条实测回显,附 ziplinectl 管理 CLI 全 7 子命令详解。
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 配置参数详解》
二、前置条件
- 实例已完成首次初始化(
/auth/setup建好超管)。全新实例上curl -s http://127.0.0.1:8142/api/setup返回{"firstSetup":true};已初始化的实例返回 403:
{"error":"E9001: Setup already completed","code":9001,"statusCode":403}
- 拿到 API Token:登录后台 → 点右上角头像 → Copy token。Token 是用
CORE_SECRET做 AES-256-GCM 加密的字符串,形如<base64时间戳>.<密文>(实测样例长度 273 字符,形如MTc5MzUyMDE3OTIyOA==.YzYzZWFjNGNl...)。后台用户设置页也能查看/重置 Token;重置 Token 会使旧 Token 全部失效。 - 服务器上有 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 |
四、认证与首次调用
4.1 会话 Cookie 方式(登录)
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)。
行为实测清单:
- 正常上传 → 200 +
files数组(§4.2)。 - 同一秒重名自动加后缀:连续上传时实测返回
2026-11-01_08:48:52.txt、2026-11-01_08:48:52-1.txt、2026-11-01_08:48:52-2.txt……不覆盖。 - 超限文件报错有误导性——上传 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 | 覆盖文件扩展名 |
- 过期文件实测:带
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 实测 401E2000。 - 该密码接口限流每秒 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 路由源码实测两者皆可)。
七、常见问题
- 带 Cookie 请求全 401——从 cookiejar 取错了列(Netscape 格式第 7 列才是值),或会话过期(实测过期会话报
E2000: Invalid login session)。脚本场景直接用 API Token 更稳。 - 上传报 E1062「没有文件」——先查大小限制(
FILES_MAX_FILE_SIZE),不是真的没带文件(§5.1 实测)。 - 分块续传突然 400/丢会话——token 一次性 + 30 分钟过期 + 服务重启即丢,任一发生都要从第 0 字节重来(§5.2)。
- 密码文件脚本直取拿不到字节——
/f直链对密码文件一律 302 到/view,程序化访问必须走raw?token=(§5.4)。 /api/version401——它需要登录态,带 Token 即可(§5.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 原地升级,保留旧库,先停服务 |
九、参考链接
- 官方 API 文档:https://zipline.diced.sh/docs/api
- 官方认证说明:https://zipline.diced.sh/docs/api/authentication
- 官方分块上传:https://zipline.diced.sh/docs/api/chunked-uploads
- 官方错误码:https://zipline.diced.sh/docs/api/errors
- 官方上传选项头:https://zipline.diced.sh/docs/guides/upload-options
- 官方 ziplinectl:https://zipline.diced.sh/docs/guides/ctl
- OpenAPI 规范:https://zipline.diced.sh/docs/api(页面提供下载)
- 同系列:《Zipline 介绍与选型指南》、《Zipline 4.8.2 Docker Compose 部署指南》、《Zipline 4.8.2 配置参数详解》