AppFlowy 0.19.10 API 使用详解

AppFlowy Cloud 0.19.10 服务端 REST API 实测手册:认证与 JWT 调用闭环、用户/工作区/成员/文件存储/AI/聊天/导入等全 API 域路由表与请求响应示例,含错误码(422/1003/1017/1018)与未配置 AI 的行为实测,全部 curl 命令实测通过。

AppFlowy自动化部署知识库协作编辑人工智能2026/10/23

AppFlowy 0.19.10 API 使用详解

目标:面向自托管运维与集成开发,给出 AppFlowy Cloud 0.19.10 服务端 REST API 的完整路由总览与逐域调用示例——认证闭环、用户、工作区与成员、文件存储、AI、聊天、数据导入、共享协作。本文基于源码部署环境(Ubuntu 22.04,Nginx 80 统一入口)实测,全部 curl 命令与回显均实测通过;路由表提取自 0.19.10 源码快照(c5bcfd33)。

一、环境信息

  • 服务端:AppFlowy Cloud 0.19.10(源码快照 c5bcfd33,2026-10-22 官方最新稳定版);
  • 认证服务:GoTrue(AppFlowy-IO/auth 快照 7337e21c),JWT 签发;
  • 测试入口:http://127.0.0.1(Nginx 80 统一入口,反代规则见《Ubuntu 22.04 安装 AppFlowy 0.19.10 指南》4.9 节);
  • 测试账号:user1@example.com / admin@example.com,口令 q1w2e3r4(示例环境,生产请替换);
  • 输出格式:全部业务接口返回统一包络 {"data":..., "code":0, "message":"..."},code 为 0 表示成功,非 0 见第六章错误码表;
  • 官方二进制差异:0.19.10 官方二进制主服务健康检查为 /api/health(源码版为 /health),其余路由一致。

二、前置条件

curl http://127.0.0.1/health
OK
curl http://127.0.0.1/gotrue/health
{"version":"","name":"GoTrue","description":"GoTrue is a user registration and authentication API"}

三、API 总览

AppFlowy Cloud 对外暴露 11 个 API 域,全部经 Nginx 80 端口访问(/metrics 除外,仅监听服务本机 8000):

API 域前缀用途认证
认证/gotrue/*注册、登录、token 刷新(GoTrue)匿名/JWT
用户/api/user用户建档、资料、注销Bearer JWT
工作区/api/workspace工作区 CRUD、成员、邀请Bearer JWT
文件存储/api/file_storage附件上传(分片)、用量统计Bearer JWT
AI/api/ai/{workspace_id}文本补全、行摘要/翻译、模型列表Bearer JWT
聊天/api/chat/{workspace_id}AI 聊天室与消息管理Bearer JWT
搜索/api/search全文/语义文档检索Bearer JWT
数据导入/api/importNotion 等外部数据导入Bearer JWT
访问申请/api/access-request工作区/视图访问审批Bearer JWT
共享访客/api/sharing/workspace访客视图授权Bearer JWT
服务器信息/api/server服务能力与版本信息匿名
实时协作/ws/v1、/ws/v2/{workspace_id}WebSocket 长连接(客户端场景)Bearer JWT
指标/metrics(本机 8000)Prometheus 指标匿名(仅内网)

💡 说明:文档内容读写(视图/页面数据)走 /ws 长连接与 collab 通道,不在 REST 范畴;/api/search、/api/access-request、/api/sharing 主要由桌面客户端内部调用,本文给出路由表与实测要点。

四、认证与首次调用

4.1 注册(POST /gotrue/signup)

curl -s -X POST http://127.0.0.1/gotrue/signup \
  -H "Content-Type: application/json" \
  -d '{"email":"user1@example.com","password":"q1w2e3r4"}' | head -c 220
{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIzMDA2MWFmZi0yMmZkLTQzZDMtOGJlNy00M2VmNDhlMDAzYzIiLCJhdWQiOiIiLCJleHAiOjE3OTMyOTgwMzYsImlhdCI6MTc5MjY5MzIzNiwiZW1haWwiOiJ1c2VyMUBleGFtcGxlLmNvbSIsInBob25lIj ...(truncated)

返回 access_token(700+ 字符 JWT,本文截断展示)与 refresh_token。重复注册同一邮箱返回 422:

curl -s -w "\nHTTP %{http_code}\n" -X POST http://127.0.0.1/gotrue/signup \
  -H "Content-Type: application/json" \
  -d '{"email":"user1@example.com","password":"q1w2e3r4"}'
{"code":422,"error_code":"user_already_exists","msg":"User already registered"}
HTTP 422

4.2 密码登录(POST /gotrue/token?grant_type=password)

curl -s -X POST "http://127.0.0.1/gotrue/token?grant_type=password" \
  -H "Content-Type: application/json" \
  -d '{"email":"user1@example.com","password":"q1w2e3r4"}' > /tmp/u1.json
python3 -c "import json;d=json.load(open('/tmp/u1.json'));print({k:(str(v)[:40]+'...' if k=='access_token' else v) for k,v in d.items() if k in ('token_type','expires_in','expires_at')})"
{'token_type': 'bearer', 'expires_in': 604800, 'expires_at': 1793298036}

expires_in 604800 秒(7 天,对应 GOTRUE_JWT_EXP=604800)。后续所有业务接口用 Authorization: Bearer <access_token> 头。

4.3 首次建档(GET /api/user/verify/{access_token})

注册/登录拿到的 token 只存在于认证库,首次调用 verify 接口才会在业务库创建用户档案与默认工作区 My Workspace:

TOK=$(python3 -c "import json;print(json.load(open('/tmp/u1.json'))['access_token'])")
curl -s "http://127.0.0.1/api/user/verify/$TOK"
{"data":{"is_new":true},"code":0,"message":"Operation completed successfully."}

同一用户再次调用返回 is_new:false(实测):

{"data":{"is_new":false},"code":0,"message":"Operation completed successfully."}

⚠️ 注意:这是 AppFlowy 与通用 JWT 服务最大的差异点——拿到 token 后必须先调 verify 建档,否则 /api/user/profile 报 Record not found(实测回显:{"code":-2,"message":"Record not found:Can't find the user profile for user: ..."})。

无效 token 的行为(实测):

curl -s "http://127.0.0.1/api/user/verify/not-a-token"
{"code":1003,"message":"invalid JWT: unable to parse or verify signature, token is malformed: token contains an invalid number of segments"}

4.4 缺失/无效认证头

curl -s -w "\nHTTP %{http_code}\n" http://127.0.0.1/api/user/profile
No Authorization header
HTTP 401

五、各 API 域详解

5.1 系统与观测(/api/server、/health、/metrics)

curl -s http://127.0.0.1/api/server
{"data":{"supported_client_features":[],"minimum_supported_client_version":null,"appflowy_web_url":"http://localhost"},"code":0,"message":"Operation completed successfully."}

appflowy_web_url 来自 APPFLOWY_WEB_URL 配置。Prometheus 指标仅暴露在服务本机 8000 端口(Nginx 未放行,属内网观测面):

curl -s http://127.0.0.1:8000/metrics | head -2
# HELP appflowy_cloud_requests_count number of requests.
# TYPE appflowy_cloud_requests_count counter

5.2 用户域(/api/user)

方法路径用途
GET/api/user/verify/{access_token}首次建档(4.3 节)
GET/api/user/profile查询当前用户资料
POST/api/user/update更新资料(姓名、头像等)
GET/api/user/workspace当前用户工作区概览
POST/api/user/asset/image上传用户图片资产
GET/api/user/asset/image/person/{person_id}/file/{file_id}读取图片资产
DELETE/api/user注销当前用户(带查询参数确认)
TOK=$(python3 -c "import json;print(json.load(open('/tmp/u1.json'))['access_token'])")
curl -s http://127.0.0.1/api/user/profile -H "Authorization: Bearer $TOK" | head -c 260
{"data":{"uid":649641193512112128,"uuid":"30061aff-22fd-43d3-8be7-43ef48e003c2","email":"user1@example.com","password":"","name":"user1@example.com","metadata":{},"encryption_sign":null,"latest_workspace_id":"155a17bc-00c7-47f2-828a-b2271a153235","updated_at": ...(truncated)

uid(int64 主键)与 uuid(与 GoTrue 用户一致)均可用于后续成员管理接口;latest_workspace_id 即首次建档创建的 My Workspace。

5.3 工作区与成员域(/api/workspace)

方法路径用途
GET / POST / PATCH/api/workspace列表 / 创建 / 改名换图标
DELETE/api/workspace/{workspace_id}删除工作区
PUT/api/workspace/{workspace_id}/open打开(标记最近使用)
POST/api/workspace/{workspace_id}/invite邮箱邀请成员(数组)
GET/api/workspace/invite、/invite/{invite_id}查询收到的邀请
POST/api/workspace/accept-invite/{invite_id}接受邀请
POST/api/workspace/join-by-invite-code邀请码加入
GET / PUT / DELETE/api/workspace/{workspace_id}/member成员列表 / 改角色 / 移除
POST/api/workspace/{workspace_id}/leave退出工作区
GET / POST/api/workspace/{workspace_id}/settings工作区设置

创建工作区(请求体 workspace_name 可选,缺省自动命名):

TOK=$(python3 -c "import json;print(json.load(open('/tmp/login.json'))['access_token'])")
curl -s -X POST http://127.0.0.1/api/workspace \
  -H "Authorization: Bearer $TOK" -H "Content-Type: application/json" \
  -d '{"workspace_name":"Doc Test WS"}' | head -c 300
{"data":{"workspace_id":"93ed8817-5310-474b-8aec-9e989dacaf27","database_storage_id":"5f0fbaac-97e7-4042-9d34-2343bc9815da","owner_uid":649641193512112128,"owner_name":"user1@example.com","owner_email":"user1@example.com","workspace_type":0,"workspace_name":"Doc Test WS","created_at":"2026-10-22T18: ...(truncated)

列表(实测一个账号下 2 个工作区):

curl -s http://127.0.0.1/api/workspace -H "Authorization: Bearer $TOK" \
  | python3 -c "import sys,json;d=json.load(sys.stdin)['data'];print(len(d),[w['workspace_name'] for w in d])"
2 ['My Workspace', 'Doc Test WS']

邀请成员(请求体为对象数组;skip_email_send:true 跳过邮件发送,适合未配 SMTP 的环境):

WID=93ed8817-5310-474b-8aec-9e989dacaf27
curl -s -X POST "http://127.0.0.1/api/workspace/$WID/invite" \
  -H "Authorization: Bearer $TOK" -H "Content-Type: application/json" \
  -d '[{"email":"user2@example.com","role":"Member","skip_email_send":true}]'
{"code":0,"message":"Operation completed successfully."}

被邀请人调用 POST /api/workspace/accept-invite/{invite_id} 接受后才出现在成员列表(实测接受前成员列表仅 Owner):

curl -s "http://127.0.0.1/api/workspace/$WID/member" -H "Authorization: Bearer $TOK"
{"data":[{"name":"user1@example.com","email":"user1@example.com","role":"Owner","avatar_url":null,"joined_at":"2026-10-22T18:20:44.050748Z"}],"code":0,"message":"Operation completed successfully."}

5.4 文件存储域(/api/file_storage)

方法路径用途
PUT / GET / DELETE/api/file_storage/{workspace_id}/blob/{file_id}小文件直传/下载/删除
GET / PUT/api/file_storage/{workspace_id}/metadata/{file_id}附件元数据
GET/api/file_storage/{workspace_id}/usage空间用量
GET/api/file_storage/{workspace_id}/blobs附件列表
POST/api/file_storage/{workspace_id}/create_upload创建分片上传任务
PUT/api/file_storage/{workspace_id}/upload_part/{parent_dir}/{file_id}/{upload_id}/{part_num}上传分片
PUT/api/file_storage/{workspace_id}/complete_upload完成分片合并
PUT / GET/api/file_storage/{workspace_id}/v1/blob/{parent_dir}…v1 分目录通道
WID=93ed8817-5310-474b-8aec-9e989dacaf27
curl -s "http://127.0.0.1/api/file_storage/$WID/usage" -H "Authorization: Bearer $TOK"
{"data":{"consumed_capacity":0},"code":0,"message":"Operation completed successfully."}

💡 提示:桌面客户端上传大附件走 create_upload → upload_part → complete_upload 三步分片流程,最终文件落在对象存储(本文环境为 SeaweedFS 的 appflowy 桶),consumed_capacity 随上传增长。

5.5 AI 域(/api/ai/{workspace_id})

方法路径用途
POST/api/ai/{workspace_id}/complete/stream流式文本补全
POST/api/ai/{workspace_id}/v2/complete/streamv2 流式补全
POST/api/ai/{workspace_id}/summarize_row、/translate_row行摘要/翻译
GET/api/ai/{workspace_id}/local/config、/model/list本地 AI 配置与模型列表
POST/api/ai/{workspace_id}/calculate_similarity相似度计算

completion_type 为整数枚举(传字符串会报 400,实测:Json deserialize error: invalid type: string "improve_writing", expected u8)。未配置 AI 时的行为(本文环境 AI_OPENAI_API_KEY 留空,实测):经 Nginx 调用补全接口返回 502(服务端在无 AI 后端时断开该连接),聊天与 AI 功能不可用,其余功能不受影响:

curl -s -w "\nHTTP %{http_code}\n" -X POST "http://127.0.0.1/api/ai/$WID/complete/stream" \
  -H "Authorization: Bearer $TOK" -H "Content-Type: application/json" \
  -d '{"text":"hello","completion_type":1}' | tail -1
HTTP 502

💡 提示:官方编排部署(B2 指南)自带 appflowy_ai 服务并预置本地模型;源码部署需配置 OpenAI 兼容接口(AI_OPENAI_API_KEY 等)后 AI 域才可用。

5.6 聊天域(/api/chat/{workspace_id})

方法路径用途
POST / DELETE/api/chat/{workspace_id}、/{chat_id}创建聊天室 / 删除(chat_id 必须为 UUID)
GET/api/chat/{workspace_id}/{chat_id}/message?limit&offset分页拉取消息
GET / POST/api/chat/{workspace_id}/{chat_id}/settings聊天设置
GET/api/chat/{workspace_id}/{chat_id}/{message_id}/related_question相关问题推荐
POST/api/chat/{workspace_id}/{chat_id}/message/question、/answer写入问答消息
POST/api/chat/{workspace_id}/{chat_id}/{message_id}/v3/answer/streamv3 流式回答
POST/api/chat/{workspace_id}/{chat_id}/context/text注入聊天上下文

创建聊天室时 chat_id 由调用方指定且必须是 UUID 格式,否则实测报错:

curl -s -X POST "http://127.0.0.1/api/chat/$WID" \
  -H "Authorization: Bearer $TOK" -H "Content-Type: application/json" \
  -d '{"chat_id":"doc-chat-001","name":"Doc Chat","rag_ids":[]}'
{"code":1018,"message":"invalid character: expected an optional prefix of `urn:uuid:` followed by [0-9a-fA-F-], found `o` at 2"}

改用 UUID 后创建成功并拉取消息(实测空聊天室):

CID=9e6bfec3-f1a0-4a15-9cc5-aec8d2c04a6a
curl -s -X POST "http://127.0.0.1/api/chat/$WID" \
  -H "Authorization: Bearer $TOK" -H "Content-Type: application/json" \
  -d "{\"chat_id\":\"$CID\",\"name\":\"Doc Chat\",\"rag_ids\":[]}"
{"code":0,"message":"Operation completed successfully."}
curl -s "http://127.0.0.1/api/chat/$WID/$CID/message?limit=10&offset=0" -H "Authorization: Bearer $TOK"
{"data":{"messages":[],"has_more":false,"total":0},"code":0,"message":"Operation completed successfully."}

5.7 数据导入域(/api/import)

方法路径用途
POST/api/import提交导入(multipart,承载 Notion 导出包等文件)
GET/api/import查询导入任务列表(含状态)
POST/api/import/create创建导入任务

该域为 multipart/form-data 上传(源码 handler 签名确认),由后台 worker(appflowy_worker)异步处理,桌面客户端「导入 Notion」功能即走此通道。APPFLOWY_WORKER_IMPORT_TICK_INTERVAL=30 决定 worker 的轮询间隔(秒)。

5.8 搜索、共享与实时协作域

方法路径域用途
GET/api/search/{workspace_id}搜索文档检索
GET/api/search/{workspace_id}/summary搜索检索结果摘要
POST / GET/api/access-request、/{request_id}、/{request_id}/approve访问申请申请/查询/批准
GET/api/sharing/workspace/{workspace_id}/view 等共享访客访客视图与授权管理
GET/api/invite-code-info邀请码邀请码信息查询
GET/ws/v1、/ws/v2/{workspace_id}实时协作WebSocket 升级连接
GET/api/realtime/*(collab 通道)实时协作协同编辑消息

💡 说明:以上接口由桌面客户端内部调用(WebSocket 与 collab 通道需专用客户端协议),运维排障时可通过本表确认路由归属;/api/search 依赖检索服务(源码部署未分发检索服务,官方编排部署自带 appflowy_search)。

六、通用约定

  1. 响应包络:业务接口统一 {"data":...,"code":N,"message":"..."};code=0 成功。注意部分错误(如 4.3 节无效 token)以 HTTP 200 + 非 0 code 返回,调用方应以 code 字段而非 HTTP 状态码做成功判定;GoTrue 域(/gotrue/*)为 Supabase 风格裸 JSON(422 时返回 {"code":422,"error_code":...,"msg":...});
  2. 认证:除 /gotrue/*、/api/server、/health 外全部要求 Authorization: Bearer <access_token>;缺失时 HTTP 401(实测回显 No Authorization header);
  3. 错误码速查(本文实测命中的):
code含义实测触发场景
0成功—
422user_already_exists重复注册(GoTrue 域)
1003invalid JWTtoken 格式错误/签名不符
-2Record not found未 verify 建档先查 profile
1017数据库唯一键冲突chat_id 已被其他聊天室占用
1018UUID 解析失败chat_id 非法
  1. 分页:列表类接口用 limit + offset 查询参数,响应带 has_more;
  2. UUID:chat_id 由客户端生成(UUID v4),workspace_id/user 资源 ID 由服务端生成,均按 UUID 校验;
  3. 幂等与删除:DELETE 类接口(删工作区、删聊天室、注销用户)为硬删除,调用前自行备份。

七、常见问题

Q1:登录成功但 /api/user/profile 报 Record not found(code -2)?

先调用 GET /api/user/verify/{access_token} 完成业务建档(is_new:true),再访问资料与工作区接口(见 4.3 节)。

Q2:所有业务接口都返回 401「No Authorization header」?

请求头缺少 Authorization: Bearer <token>。注意 Bearer 与 token 之间有一个空格;token 过期(默认 7 天)后需重新登录或用 GoTrue 的 refresh_token 换新。

Q3:创建聊天室报 code 1018 或 1017?

chat_id 必须是 UUID(如 9e6bfec3-f1a0-4a15-9cc5-aec8d2c04a6a),自定义字符串 ID 不被接受,报 code 1018(实测回显见 5.6 节);code 1017 表示该 chat_id 已被占用——实测确认 chat_id 是全局唯一主键(跨工作区),重复创建返回 duplicate key value violates unique constraint "af_chat_pkey",换一个新 UUID 即可。

Q4:AI 补全接口返回 502?

未配置 AI 后端。源码部署需在 appflowy.env 配置 AI_OPENAI_API_KEY(OpenAI 兼容接口)后重启 appflowy_cloud;官方编排部署自带 appflowy_ai 服务。配置参数详见《AppFlowy 0.19.10 配置参数详解》。

Q5:curl /metrics 返回 404?

/metrics 只在服务本机 8000 端口暴露(curl http://127.0.0.1:8000/metrics),未纳入 Nginx 反代是刻意的内网观测面设计;如需采集,请在服务器本机部署 Prometheus 抓取或自行增加仅内网可达的 location。

Q6:如何用 API 判断服务端版本?

GET /api/server 返回服务能力信息;健康检查 GET /health(源码版)或 GET /api/health(官方二进制)。版本本身以部署时的快照/发布物为准(0.19.10)。

Q7:邀请发出后成员列表里看不到被邀请人?

邀请需被邀请人调用 POST /api/workspace/accept-invite/{invite_id} 接受后才入列(5.3 节实测:接受前列表仅 Owner)。未配 SMTP 时邀请邮件不会发出,可在邀请请求中置 skip_email_send:true,并从 GET /api/workspace/invite(被邀请人视角)查到 invite_id。

八、参考链接

站内系列文档: