{"openapi":"3.0.3","info":{"title":"HSpace API","version":"0.2.1","license":{"name":"MIT"},"description":"私密分享 AI 生成的内容:把一段 HTML/Markdown(或一批文档的合集)发布成带密码的公开链接。\n\n**给 AI 调用方的要点:**\n- 私密是产品默认。要让页面受保护,必须在 `password` 里传一个访问密码(建议生成 4 位数字);省略 `password` 会创建任何人可访问的公开页面。\n- 发布成功后请把返回的 `url` 和你使用的密码**一起**转达给用户——没有密码无法访问。\n- Markdown 会被渲染成排版精良的阅读页;合集(`files`)会生成一个目录页与逐篇导航。"},"servers":[{"url":"https://html-share.kzhan.workers.dev","description":"HSpace API"}],"security":[{},{"bearerAuth":[]}],"paths":{"/publish":{"post":{"operationId":"publish","summary":"发布内容为带密码的私密链接","description":"发布单个文档(`html` 或 `markdown` 三选一其一)或一个合集(`files`,≥2 篇)。要保持私密请务必传 `password`。","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishRequest"},"examples":{"markdown":{"summary":"发布一篇 Markdown(带密码)","value":{"markdown":"# 标题\n\n正文……","password":"4831","filename":"note.md"}},"collection":{"summary":"发布一个合集(md/html 混排)","value":{"title":"Q3 方案","password":"4831","files":[{"name":"1-总览.md","markdown":"# 总览\n…"},{"name":"2-附录.html","html":"<!doctype html><title>附录</title>…"}]}}}}}},"responses":{"200":{"description":"发布成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishResult"}}}},"400":{"description":"请求无效(missing_content / collection_too_few / too_many_docs)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"API Key 无效(invalid_api_key)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"内容超过体积上限(too_large)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"内容被安全扫描拦截(content_blocked)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"发布过于频繁(rate_limited)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"服务繁忙,全局日配额熔断(service_busy)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/pages/{slug}":{"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"description":"页面/合集短码"}],"patch":{"operationId":"updatePage","summary":"更新内容(升版)/ 改密码 / 改有效期","description":"带 `html`/`markdown`(单页)或 `files`(合集)即更新内容并升一个版本,旧版保留可回滚,类型需与原页面一致。也可改密码或续期(把有效期从现在往后推,最长 30 天/期;没有永久链接)。已过期的链接不可再更新/续期,需重新发布。匿名可更新自己页面的内容(每次重新扫描),但不可移除密码、不可续期,也不能用每人一链 / 版本历史(这些需登录)。鉴权用 Bearer(登录)或 `X-Edit-Token`。","parameters":[{"$ref":"#/components/parameters/EditToken"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRequest"}}}},"responses":{"200":{"description":"已更新","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"slug":{"type":"string"}}}}}},"400":{"description":"无可更新字段 / 类型不符 / 合集不可变","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"无权限或该操作需登录","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"页面不存在","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deletePage","summary":"删除页面/合集(链接立即失效)","parameters":[{"$ref":"#/components/parameters/EditToken"}],"responses":{"200":{"description":"已删除","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"slug":{"type":"string"}}}}}},"403":{"description":"无权限","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"页面不存在","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/pages/{slug}/stats":{"get":{"operationId":"getPageStats","summary":"查看访问量(访问回执)","description":"返回该页面/合集的累计访问次数等。鉴权用 Bearer(登录)或 `X-Edit-Token`。","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/EditToken"}],"responses":{"200":{"description":"访问统计","content":{"application/json":{"schema":{"type":"object","properties":{"slug":{"type":"string"},"hits":{"type":"integer","description":"累计访问次数(合集为目录+各篇总和)"},"createdAt":{"type":"integer"},"expiresAt":{"type":"string","nullable":true},"passwordProtected":{"type":"boolean"},"isCollection":{"type":"boolean"}}}}}},"403":{"description":"无权限","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"页面不存在","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/pages/{slug}/versions":{"get":{"operationId":"listVersions","summary":"内容版本历史","description":"列出该页面/合集的所有内容版本。鉴权:Bearer 或 X-Edit-Token。","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/EditToken"}],"responses":{"200":{"description":"版本列表","content":{"application/json":{"schema":{"type":"object","properties":{"current":{"type":"integer"},"versions":{"type":"array","items":{"type":"object","properties":{"version":{"type":"integer"},"size_bytes":{"type":"integer"},"created_at":{"type":"integer"}}}}}}}}},"403":{"description":"无权限","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"页面不存在","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/pages/{slug}/versions/{v}/restore":{"post":{"operationId":"restoreVersion","summary":"回滚到某个内容版本","description":"把当前内容指回指定版本(会升为一个新版本)。鉴权:Bearer 或 X-Edit-Token。","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"v","in":"path","required":true,"schema":{"type":"integer"}},{"$ref":"#/components/parameters/EditToken"}],"responses":{"200":{"description":"已回滚","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"slug":{"type":"string"},"version":{"type":"integer"},"restoredFrom":{"type":"integer"}}}}}},"403":{"description":"无权限","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"页面或版本不存在","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/pages/{slug}/grants":{"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"post":{"operationId":"createGrant","summary":"创建访问人(每人一链):返回一次性密码","description":"为页面新增一个独立密码的访问人,可按人统计与单独撤销。密码仅在创建时返回一次。鉴权:Bearer 或 X-Edit-Token。","parameters":[{"$ref":"#/components/parameters/EditToken"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string","description":"访问人标签,如“张三”"},"password":{"type":"string","description":"可选;省略则自动生成 4 位数字"}}}}}},"responses":{"200":{"description":"已创建","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string","nullable":true},"password":{"type":"string","description":"一次性返回,请连同 url 转达该访问人"},"url":{"type":"string"}}}}}},"403":{"description":"无权限","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"页面不存在","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"listGrants","summary":"列出访问人(不含密码)","parameters":[{"$ref":"#/components/parameters/EditToken"}],"responses":{"200":{"description":"访问人列表","content":{"application/json":{"schema":{"type":"object","properties":{"grants":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string","nullable":true},"created_at":{"type":"integer"},"revoked":{"type":"integer"},"hits":{"type":"integer"},"last_seen_at":{"type":"integer","nullable":true}}}}}}}}},"403":{"description":"无权限","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"页面不存在","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/pages/{slug}/grants/{id}":{"delete":{"operationId":"revokeGrant","summary":"撤销访问人(软删,统计保留)","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/EditToken"}],"responses":{"200":{"description":"已撤销","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"slug":{"type":"string"}}}}}},"403":{"description":"无权限","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"页面不存在","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/pages":{"get":{"operationId":"listPages","summary":"列出当前账户的页面(需登录)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"页面列表","content":{"application/json":{"schema":{"type":"object","properties":{"pages":{"type":"array","items":{"$ref":"#/components/schemas/PageSummary"}}}}}}},"401":{"description":"未登录(unauthorized)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/health":{"get":{"operationId":"health","summary":"健康检查","security":[{}],"responses":{"200":{"description":"服务正常","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"service":{"type":"string"}}}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"账户 API Key"}},"parameters":{"EditToken":{"name":"X-Edit-Token","in":"header","required":false,"schema":{"type":"string"},"description":"匿名发布时返回的编辑凭据(改/删非本账户页面时使用)"}},"schemas":{"PublishRequest":{"type":"object","description":"`html`、`markdown`、`files` 三者恰选其一。要保持私密请传 `password`。","properties":{"html":{"type":"string","description":"HTML 源码(单文件发布)"},"markdown":{"type":"string","description":"Markdown 文本(单文件发布,渲染成阅读页)"},"files":{"type":"array","minItems":2,"description":"合集篇目(≥2 篇);每项 `html`/`markdown` 二选一,可混排","items":{"$ref":"#/components/schemas/CollectionFile"}},"title":{"type":"string","description":"合集标题(仅 files 时用)"},"filename":{"type":"string","description":"文件名(单文件,用于展示与标题回退)"},"password":{"type":"string","description":"访问密码。省略则页面公开可访问;要私密务必提供(建议 4 位数字)。"},"expiresIn":{"type":"integer","nullable":true,"description":"有效期(秒),从现在起算。钳制在 [60, 该档上限]:匿名 7 天、登录 30 天。没有永久链接;null 或省略都取该档上限。"}}},"CollectionFile":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"文件名,如 1-总览.md(用于排序与标题回退)"},"html":{"type":"string"},"markdown":{"type":"string"}}},"UpdateRequest":{"type":"object","properties":{"password":{"type":"string","nullable":true,"description":"新密码;null 或空串=移除密码(仅登录)"},"expiresIn":{"type":"integer","nullable":true,"description":"续期:把有效期从现在起重设为该秒数(钳制在档内上限,登录 30 天);null=续到上限。没有永久。"},"html":{"type":"string","description":"覆盖内容(仅登录、非合集、类型需一致)"},"markdown":{"type":"string","description":"覆盖内容(仅登录、非合集、类型需一致)"}}},"PublishResult":{"type":"object","properties":{"slug":{"type":"string"},"url":{"type":"string","description":"分享链接;私密页面需配合密码访问"},"expiresAt":{"type":"string","description":"过期时间 ISO8601(所有链接都有有效期)"},"passwordProtected":{"type":"boolean"},"docs":{"type":"array","description":"合集时返回的篇目清单","items":{"type":"object","properties":{"index":{"type":"integer"},"title":{"type":"string"}}}},"editToken":{"type":"string","nullable":true,"description":"匿名发布返回的编辑凭据;请妥善保存,是后续改/删的唯一凭据"}}},"PageSummary":{"type":"object","properties":{"slug":{"type":"string"},"filename":{"type":"string","nullable":true},"created_at":{"type":"integer"},"expires_at":{"type":"integer","nullable":true},"hits":{"type":"integer"},"protected":{"type":"integer","description":"1=有密码"}}},"Error":{"type":"object","properties":{"error":{"type":"string"},"file":{"type":"string"},"maxBytes":{"type":"integer"}}}}}}