轻湖文本快递柜 API 文档
轻湖文本快递柜(LiteTextShare)取件码模式 API 参考。本页面供人阅读;AI Agent 请直接抓取下方 Markdown 原文。
TextShare API(轻湖文本快递柜后端)
文本快递柜(TextShare)后端 API——前端(BFF)与 AI Agent 对接的单一事实源。本文档的任何变更必须与对应的接口变更同版本发布。
- REST 基址(经 BFF 代理):
https://textshare.litelake.com/api/** - 协同编辑(WebSocket,浏览器直连,不经 BFF):
wss://ws.textshare.{env}/collab/{noteId}?token={editToken}——wsUrl基址由创建/verify 响应下发,调用方不自行拼接。
通用约定
- 除
/docs/*与 WebSocket 端点为GET外,全部 REST 接口为POST+application/json。 - 统一响应信封:
{ "code": number, "message": string, "data": T };成功code = 200。 - 业务错误 HTTP 恒 200,靠
body.code区分(4101/4103/4104);限流用真实 HTTP 429 +Retry-After;存储故障(fail-closed)用真实 HTTP 503。 - 全部请求应携带
X-Device-Id头(localStorage 生成的 UUID)。非法/缺失按「无设备号」处理,防爆破自动退化为仅 IP 维度(不报错)。
POST /api/public/notes —— 创建文档并生成取件码
携带本地已书写内容创建文档(先写后生成码),创建即 active。
请求体:
{
"mode": "md",
"initState": "<base64(本地 Y.Doc 的 V1 update)>"
}
mode:txt|md(白名单,其余 → 4103)initState:本地 Y.DocY.encodeStateAsUpdate()的 base64(V1)。空串表示空文档。服务端将 update 应用到空 doc,fold 后实测纯文本字节数。
响应 data:
{
"noteId": "cz9fkq2wm4xv...",
"pickupCode": "K7M2XQ",
"mode": "md",
"expiresAt": "2026-09-16T08:00:00Z",
"wsUrl": "wss://ws.textshare.{env}/collab",
"editToken": "9f2c8e...64 位 hex"
}
错误:4103 mode 非法 / initState 无法应用(HTTP 200);4104 文本超过 128KB(HTTP 200);429 创建限流(每 IP 12 次/小时 + 30 次/天,真实 HTTP 429 + Retry-After);503 存储不可用(fail-closed)。
POST /api/public/pickup/verify —— 凭码换取协同入口
请求体:
{ "pickupCode": "K7M2XQ" }
服务端归一化:去空格与连字符、转大写、O→0、I/L→1。响应 data 与创建响应字段一致(pickupCode 回显归一化后的值)。
错误:4101 取件码无效或已过期——统一文案防枚举(HTTP 200;每次失败对 IP 与设备号双维度计数 +1)。防爆破:任一维度 5 次/10 分钟即封禁,返回真实 HTTP 429 + Retry-After;成功不清零。Redis 故障 → 真实 HTTP 503(fail-closed)。
GET /collab/{noteId}?token={editToken} —— 协同 WebSocket
Yjs 协同端点,兼容 Hocuspocus 消息协议(@hocuspocus/provider 可直连;每帧带 VarString(docName) 前缀)。浏览器直连(不经 BFF;网关按域名转发)。
握手鉴权(在 WebSocket 升级之前执行):
noteId存在、status = active且未过期(Redis 缓存 60s + MySQL 兜底;过期/不存在 → 401 拒绝,业务码 4102)editToken有效且绑定该noteId(Redis;miss 或 Redis 故障 → 拒绝,fail-closed,业务码 4105)- 单 IP 连接数 < 10、单房间人数 < 16、单 update ≤ 768KB、单帧 ≤ 1MB
升级完成后服务端执行 y-protocols 同步握手(SyncStep1/2)、广播 awareness(光标/在线状态),并把每次 commit 以增量 V1 update 持久化(append-then-compact 写 MySQL:notes.snapshot + note_updates 流水)。文档创建后 48 小时过期;过期时强制关房(客户端收到 close 事件)。
没有只读连接:持 token 即得编辑权(v1 产品定义)。
GET /docs/api.md、/docs/api.en.md、/docs/api.zhs.md
本文档(内嵌于二进制;en 为默认/兜底,zhs 为简体中文)。以 text/markdown 输出,Cache-Control: no-cache。
GET /api/health、/api/ready
框架内置存活/就绪探针(网关 healthcheck 指向 /api/health)。
错误码表
| body.code | 语义 | HTTP 状态码 |
|---|---|---|
| 200 | 成功 | 200 |
| 400 | 参数/绑定错误 | 200 |
| 4101 | PICKUP_NOT_VALID(统一文案,防枚举) | 200 |
| 4102 | NOTE_NOT_FOUND / 已过期(WS Authorize 用,REST 一般不触达) | 200 |
| 4103 | INVALID_ARGUMENT(mode / initState) | 200 |
| 4104 | NOTE_TOO_LARGE(fold 后纯文本 > 128KB) | 200 |
| 4105 | EDIT_TOKEN_INVALID(WS 握手被拒) | 200 |
| 429 | RATE_LIMITED | 429 + Retry-After |
| 503 | STORAGE_UNAVAILABLE(Redis 故障 fail-closed) | 503 |
| 500 | 内部错误 | 500 |
注:/api/public 写方法的基线限流中间件(30 次/min/IP)触发时响应体为中间件自拼格式;调用方对 429 一律按 HTTP 状态码处理,不依赖 body 形状。