Jotty 1.29.2 REST API 实战指南
基于 1.29.2 实测:x-api-key 鉴权、笔记/清单/看板/搜索全链路 curl 实测回显、OpenAPI 3.1 自描述、错误模型与自动化集成建议。
Jotty 1.29.2 REST API 实战指南
目标:面向自动化与集成场景,讲清 Jotty 1.29.2 REST API 的鉴权方式、核心端点、请求/响应结构与易错点。本文全部请求与回显均在 1.29.2 实测环境用 curl 取得(2026-10-30);参数语义以实例自带的 OpenAPI 3.1 文档与官方 howto/API.md 为准。部署与配置前置见《Jotty 1.29.2 Docker Compose 部署指南》与《Jotty 1.29.2 配置参数详解》。
一、API 能力概览
Jotty 为笔记、清单、任务与看板提供全量 REST API,核心事实(实测取得):
- 实例自带 OpenAPI 3.1 自描述文档:
GET /api/openapi.json(需密钥),实测回显Jotty API 1.29.2 paths: 62——62 个端点覆盖笔记、清单、任务、看板、标签、分类、模板、共享、agents 等; GET /api/docs在ENABLE_API_DOCS=true时免密钥提供同一文档(JSON/YAML),默认关闭时返回 404(开关行为实测见配置详解第八节);- 鉴权方式统一为请求头
x-api-key,除健康检查外所有端点都需要密钥(官方 howto/API.md)。
主要端点族(依据实测 OpenAPI 文档整理):
| 端点族 | 代表路径 |
|---|---|
| 笔记 | /notes、/notes/{noteId}、/notes/{noteId}/tags |
| 清单 | /checklists、/checklists/{listId}、/checklists/{listId}/items、.../check、.../uncheck、.../sort、.../reorder |
| 看板 | /kanban、/kanban/{boardId}/items(含 batch)、/kanban/{boardId}/spec、.../agent、.../context |
| 检索与元数据 | /search、/tags、/categories、/templates |
| 协作与集成 | /agents/tasks、共享端点、剪藏(Clippers)端点、审计日志 |
二、密钥签发与认证
签发(官方 howto/API.md"Getting an API key"):登录 → 侧边栏点用户名进入 Profile → Settings 标签 → API Key 区点 Generate → 复制。密钥以 ck_ 前缀开头;重新生成即替换旧密钥,持有密钥者拥有与该账户完全相同的权限。
认证(实测):
# 未认证(实测):
curl -s -o /dev/null -w "HTTP %{http_code}\n" http://127.0.0.1:8131/api/notes
# 回显:HTTP 401
# 认证(实测):
curl -s -H "x-api-key: ck_xxxx" http://127.0.0.1:8131/api/notes
# 回显:{"notes":[],"total":0}
安全纪律:密钥等效于账户本身,只放服务端环境变量或密钥管理器,不入代码库;泄露后立即在 Profile 页重新生成。
三、笔记 CRUD 实测
3.1 创建(POST /api/notes)
curl -s -X POST -H "x-api-key: $KEY" -H "Content-Type: application/json" \
-d '{"title":"S9 验收笔记","content":"# S9 验收笔记\n\n这是 Jotty 1.29.2 部署实验的验证内容。 #s9test #部署实验"}' \
http://127.0.0.1:8131/api/notes
# 实测回显:
# {"success":true,"data":{"id":"c387ff39-4619-4de3-b628-bf47b58b83fb","title":"S9 验收笔记","category":"Uncategorized","content":"# S9 验收笔记\n\n... #s9test #部署实验","createdAt":"2026-10-30T08:05:17.350Z","updatedAt":"2026-10-30T08:05:17.351Z","owner":"admin"}}
要点:id 即该笔记的 UUID,后续读写/删除都用它;正文中的 #hashtag 会被自动提取为标签。
3.2 标签联动(实测)
curl -s -H "x-api-key: $KEY" http://127.0.0.1:8131/api/tags
# 实测回显:
# {"tags":[{"tag":"s9test","notes":1,"checklists":0}],"total":1}
curl -s -H "x-api-key: $KEY" "http://127.0.0.1:8131/api/notes?tag=s9test" | head -c 200
# 实测回显(节选):
# {"notes":[{"id":"c387ff39-...","title":"S9 验收笔记","tags":["s9test"],...}]}
官方 howto/API.md 特别提醒:标签的唯一事实来源是正文 hashtag,只在 frontmatter 里写 tags: 而正文没有,下次保存就会被清掉——脚本写入时务必把 hashtag 写进正文。
3.3 更新(PUT /api/notes/{noteId},实测)
curl -s -X PUT -H "x-api-key: $KEY" -H "Content-Type: application/json" \
-d '{"id":"c387ff39-...","title":"S9 验收笔记","content":"# S9 验收笔记\n\n更新后的内容,验证 PUT。 #s9test"}' \
http://127.0.0.1:8131/api/notes/c387ff39-...
# 实测回显:
# {"success":true,"data":{"id":"c387ff39-...","title":"S9 验收笔记","content":"# S9 验收笔记\n\n更新后的内容,验证 PUT。 #s9test","createdAt":"2026-10-30T08:05:17.350Z","updatedAt":"..."}}
createdAt 保持不变、updatedAt 刷新,符合预期。由外部脚本持续重写的笔记,官方建议在 frontmatter 标记 managed: true,API 对这类笔记的写操作会返回 warning 提醒(howto/API.md"Note files")。
四、清单与任务实测
4.1 创建清单与追加条目
# 创建清单(实测):
curl -s -X POST -H "x-api-key: $KEY" -H "Content-Type: application/json" \
-d '{"title":"S9 验收清单","category":"Uncategorized"}' http://127.0.0.1:8131/api/checklists
# 回显:{"success":true,"data":{"id":"684c3483-...","title":"S9 验收清单","category":"Uncategorized","type":"simple","items":[],...}}
# 追加条目(实测;字段名是 text,不是 content):
curl -s -X POST -H "x-api-key: $KEY" -H "Content-Type: application/json" \
-d '{"text":"验证 Docker 部署"}' http://127.0.0.1:8131/api/checklists/684c3483-.../items
# 回显:{"success":true,"data":{"id":"684c3483-...-1793347551724","index":"0"}}
4.2 勾选与查询
curl -s -X PUT -H "x-api-key: $KEY" http://127.0.0.1:8131/api/checklists/684c3483-.../items/0/check
# 实测回显:{"success":true}
curl -s -H "x-api-key: $KEY" http://127.0.0.1:8131/api/checklists/684c3483-... | head -c 300
# 实测回显(节选):
# {"success":true,"data":{..."items":[{"id":"684c3483-...-1793347551753","index":0,"itemIndex":"0","text":"验证 REST API","completed":true,"createdBy":"admin",...}]}}
条目寻址用树形索引:0 为第一项,2.1 为第三项的第二个子项(howto/API.md"Ids")。取消勾选用 .../uncheck;整表排序用 PUT .../items/sort,支持 {"sort":"alphabetical","direction":"asc"}、created、modified、shuffle。
五、看板(Kanban)实测
创建看板的请求体字段是 type(OpenAPI schema:enum simple|task|kanban,task 为 kanban 的旧名仍被接受):
# 错误字段名会静默降级为普通清单(排障实录,见第七节)
# 正确创建(实测):
curl -s -X POST -H "x-api-key: $KEY" -H "Content-Type: application/json" \
-d '{"title":"S9 看板","type":"kanban"}' http://127.0.0.1:8131/api/checklists
# 回显:{"success":true,"data":{"id":"77f6b70c-...","title":"S9 看板","category":"Uncategorized","type":"kanban","items":[],...}}
curl -s -H "x-api-key: $KEY" http://127.0.0.1:8131/api/kanban
# 实测回显(节选):
# {"boards":[{"id":"77f6b70c-...","title":"S9 看板","category":"Uncategorized","statuses":[
# {"id":"todo","label":"To Do","order":0,"autoComplete":false},
# {"id":"in_progress","label":"In Progress","order":1,"autoComplete":false},
# {"id":"completed","label":"Completed","order":2,"autoComplete":true},
# {"id":"paused","label":"Paused","order":3,"autoComplete":false}],"items":[],...}]}
看板卡片移动用 POST /api/kanban/{boardId}/items(单张)或 POST /api/kanban/{boardId}/items/batch(最多 200 张,幂等导入靠 externalId 去重)。面向 AI 编排的三件套(官方 howto/API.md):PUT .../spec 把普通笔记钉为看板 spec(规划文档,含 Goal/Acceptance criteria/Agents/Tasks 等约定章节)、PUT .../items/{itemId}/agent 把卡片指派给虚拟 agent、GET .../items/{itemId}/context 拉取单卡完整工作上下文;GET /api/agents/tasks 汇总所有 agent 在办任务。
六、搜索与分类(实测)
curl -s -H "x-api-key: $KEY" "http://127.0.0.1:8131/api/search?q=%E9%AA%8C%E8%AF%81"
# 实测回显:
# {"query":"验证","results":[{"uuid":"c387ff39-...","slug":"S9 验收笔记","type":"note","title":"S9 验收笔记","category":"Uncategorized","excerpt":"这是 Jotty 1.29.2 部署实验的验证内容。 #s9test #部署实验","id":"S9 验收笔记"}],"total":1}
curl -s -H "x-api-key: $KEY" http://127.0.0.1:8131/api/categories
# 实测回显:
# {"categories":{"notes":[{"name":"Uncategorized","path":"Uncategorized","count":1,"level":0}],"checklists":[{"name":"Uncategorized","path":"Uncategorized","count":2,"level":0}]}}
/api/search 一次聚合笔记/清单/看板结果,返回 type 字段区分类型;分类以路径树表示(嵌套用 /)。
七、错误模型与排障实录(实测沉淀)
-
400 + Zod 校验详情:参数名写错会得到结构化错误。实测把条目字段写成
content:{"error":"Text is required","details":[{"expected":"string","code":"invalid_type","path":["text"],"message":"Text is required"}]}details[].path直接给出正确字段名——遇到 400 先看details,不必翻文档。 -
创建看板时
type写成checklistType静默降级:实测以{"checklistType":"kanban"}请求创建,返回 200 但"type":"simple",看板列表(GET /api/kanban)为空。该端点对未知字段不报错,创建后务必核对回显中的type字段;受影响的数据可在界面或 API 中修正类型。 -
Item index out of range:对空清单调用check时实测回显{"error":"Item index out of range"}(HTTP 400)——先创建条目再勾选,树形索引从 0 起。 -
slug 寻址已弃用:官方 howto/API.md 明示旧的文件名 slug 查找(
?category=)仍兼容但每次请求记录警告,未来版本将移除;存量集成应尽快切换为 UUID。 -
401 排查顺序:密钥是否完整粘贴(
ck_前缀 + 32 位十六进制)、是否使用了重新生成前的旧密钥、x-api-key头名是否拼写正确(不是Authorization: Bearer)。实测未携带密钥访问/api/openapi.json返回 401,属预期行为而非故障。
八、自动化集成建议
- 备份联动:结合数据落盘形态(
data/下纯 Markdown/JSON,见部署指南第四节),用GET /api/notes、GET /api/checklists做逻辑导出,与data/目录物理快照互为补充。 - 幂等导入:批量建卡走
POST /api/kanban/{boardId}/items/batch并携带externalId(如工单 URL),重跑不重复(官方语义 + OpenAPI 描述)。 - 外部事件驱动:Webhook 类需求可由轮询
GET /api/search?q=...或按updatedAt过滤笔记列表实现轻量监听。 - 探索新端点:优先读实例自带
/api/openapi.json(62 路径全集,随版本自描述),比静态文档更贴合所部署版本。
九、验收清单
- 未认证 401 / 认证 200(鉴权链路)
- 笔记创建/更新/标签自动提取/按标签过滤
- 清单创建/条目追加(
text)/勾选/树形索引 - 看板创建(
type:"kanban")/默认四状态列 - 聚合搜索与分类树
- OpenAPI 自描述(
/api/openapi.json密钥访问、/api/docs开关控制) - 错误模型(Zod details、400/401 语义)
至此 Jotty 批次四篇闭环:选型(《Jotty 1.29.2 介绍与选型指南》)→ 部署 → 配置 → API 集成。