/v1/* 端点完整参考 + 错误码 + curl 例子
REST API 参考
所有 v1 接口都在 /api/v1 下,通过
Authorization: Bearer pd_<前缀>_<密钥> 鉴权。token 在
/developers/tokens 创建;机器可读的 OpenAPI 3.1 描述位于
/api/openapi.json。
限流: 新建 token 默认 5 次/分钟,创建时可配置
rateLimitPerMinute(1-600)。达到上限会返回 429,并带上
Retry-After、X-RateLimit-Limit 与 X-RateLimit-Remaining: 0 响应头。
错误信封: 非 2xx 响应统一是
{ "error": "<可读消息>", "code": "<机器码>" }。机器码枚举在所有接口里都相同
(见文末"错误码"小节)。
接口列表
GET /v1/me
返回 token 所属的用户,以及本次请求走的是哪种鉴权路径。验证 token 是否可用的最快方式。
curl -H "Authorization: Bearer $TOKEN" $BASE/api/v1/me
{
"user": { "id": "cm...", "email": "you@example.com", "quotaBytes": 524288000, "usedBytes": 12345 },
"auth": { "source": "token", "tokenId": "cm..." }
}
GET /v1/files
列出你的文件。可选 ?folderId= 限定到某个目录。响应包含 kind(HTML / MARKDOWN /
TEXT)、scanStatus、shareCount。
POST /v1/files(multipart)
上传单个 .html / .htm / .md / .markdown / .txt / .text 文件。可选附带一个
share 表单字段(JSON 编码),在同一个事务里直接创建分享链接,并在响应里把 URL
一起返回。新建分享的 URL 形如 /s/<用户公开段>/<分享 token>;旧的
/s/<分享 token> 仍保持兼容。
curl -H "Authorization: Bearer $TOKEN" \
-F "file=@notes.md;type=text/markdown" \
-F 'share={"expiresInDays":7,"password":"hello12"}' \
$BASE/api/v1/files
限制:单文件 10 MB;不接受 ZIP、视频、音频、可执行文件或目录打包。同目录下同名上传会返回
409 DUPLICATE(如需覆盖 / 自动重命名,请用控制台 UI——版本机制只在 UI 路径生效)。
GET /v1/files/{id} · DELETE /v1/files/{id}
读取元数据,或软删除(同时会撤销该文件的所有分享)。
GET /v1/shares · POST /v1/shares · GET /v1/shares/{id} · DELETE /v1/shares/{id}
标准的 列表 / 创建 / 获取 / 撤销。POST /v1/shares 请求体:
{
"fileId": "cm...",
"expiresInDays": 7, // null = 永久
"password": "hello12", // null = 无密码
"maxVisits": 100,
"perVisitorMaxVisits": 3, // 每个独立访客最多访问 3 次;null = 每人不限
"perLoginUserMaxVisits": 2, // 每个登录账号最多访问 2 次;设置后访客必须登录
"oneTime": false, // true 时强制 maxVisits=1
"requireLogin": false, // true = 访客必须登录 PageDrop 后才能查看
"slug": "weekly-report", // 3-32 位,可用字符 base62 + - _
"lockedVersionId": "fv_...", // 钉到某个具体 FileVersion
"oneSession": false, // 同一浏览器 session 才能访问
"emailAllowlist": ["a@b.com"], // 访客必须登录且邮箱命中白名单
"copyProtectionEnabled": false,
"burnAfterReadEnabled": false // 阅后即焚:当前浏览器记住已读位置,刷新后从未读处继续
}
所有 share 字段都是可选的。返回 { share, url }(url 是绝对的查看地址)。
share 里的访问统计包含两个口径:visitCount 是累计访问量,每次成功渲染主页面都加 1;
uniqueVisitCount 是独立访问量,按渲染域访客 Cookie 去重,首次没有 Cookie 时用脱敏 IP 段 + User-Agent 生成初始标识。
POST /v1/validate
不入库地预校验内容。给 Agent 生成的文本做预检很合适——把问题挡在落盘之前。
curl -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"content":"# hi","kind":"MARKDOWN"}' \
$BASE/api/v1/validate
响应:{ ok: boolean, normalized: string, issues: [{ level, message, line? }] }。
level 取值 error(会让 ok=false)、warning、info。normalized 是把 CRLF → LF、
Tab → 4 空格、BOM 剥掉、尾随空白裁掉之后的内容。
错误码
| code | HTTP | 含义 |
|---|---|---|
UNAUTHENTICATED | 401 | token 缺失 / 无效 / 已撤销 |
FORBIDDEN | 403 | 已鉴权但没有权限 |
NOT_FOUND | 404 | 资源不存在或不属于你 |
VALIDATION | 400 | 请求体 / 参数不合法 |
RATE_LIMITED | 429 | 单 token 60/min 桶被打空 |
OVER_QUOTA | 413 | 文件超大或账号配额已用尽 |
INFECTED | 409 | 被 ClamAV 标记为不安全 |
SLUG_TAKEN | 409 | 自定义短链已被占用 |
DUPLICATE | 409 | 同目录下已有同名文件 |
CONFLICT | 409 | 通用冲突 |
INTERNAL | 500 | 服务端错误(已写日志 + Sentry) |
CORS
所有 /v1/* 响应都带 Access-Control-Allow-Origin: * 和
Allow-Headers: Authorization, Content-Type。跨域浏览器代码可以直接带 Bearer
token 调用(我们故意不设 Allow-Credentials,所以 cookie 不会跨域传播)。
试一试
Playground 把每个接口都渲染成了带输入框的表单——粘一次 token 然后点 Send 就能跑。