Continuwuity 26.9 API 使用详解

Continuwuity 无独立管理 CLI,管理全靠 Matrix Client-Server API 与管理房间机器人:版本发现、登录认证、房间/消息/目录、sync 与 !admin 命令全链路实测(v26.9.1)。

ContinuwuityMatrix即时通信自托管API2026/10/25

Continuwuity 26.9 API 使用详解

目标:摸清 Continuwuity(Matrix homeserver)对外的全部 API 面——Matrix Client-Server API、Federation API、服务私有端点与管理房间机器人命令,并以一台已部署 v26.9.1 的服务器实测「登录认证 → 建房 → 发消息 → 读消息 → 同步 → 服务器管理」全链路。本文所有命令与回显均为 v26.9.1(commit 046074b)实测逐行照抄(实测日 2026-10-25)。

一、环境信息与前置条件

项目实测值
操作系统Ubuntu 22.04 LTS(systemd 249)
Continuwuity 版本26.9.1(commit 046074b,2026-09-28 发布)
安装方式官方静态二进制 + systemd(见本专栏安装篇)
监听地址127.0.0.1:8008(默认仅回环)
server_nameexample.com
管理员账号@admin:example.com(密码 q1w2e3r4,首次启动注册令牌注册)
API 根地址http://127.0.0.1:8008

前置条件:

  1. 已按 《Ubuntu 22.04 安装 Continuwuity 26.9 指南》 完成部署,服务 systemctl is-active conduwuit 为 active。
  2. 已用首次启动打印的一次性注册令牌创建管理员账号(安装篇第四节)。
  3. 服务器本地有 curl;所有命令在服务器本机执行(默认监听回环,外部机器直接访问会被拒)。

一个重要认知:Continuwuity 没有独立的管理 CLI——二进制 conduwuit 只有启动参数(-c/--config、-O、--maintenance 等,详见 《Continuwuity 26.9 配置参数详解》),没有任何 user create、room list 之类的管理子命令。全部运行时管理都通过两条通道完成:

  • Matrix Client-Server API(HTTP REST,/_matrix/client/...)——用户、房间、消息的一切标准操作;
  • 管理房间机器人命令(!admin ...)——服务器级管理(建用户、发注册令牌、 federation 管控等),本质也是走 Client API 发消息。

二、API 体系总览

Continuwuity 26.9 暴露四组 HTTP 端点:

端点前缀体系认证用途
/_matrix/client/Client-Server API多数需 access_token客户端全部操作:登录、房间、消息、同步
/_matrix/federation/Server-Server(Federation)API服务端签名服务器间联邦;仅版本端点可匿名查
/_continuwuity/服务私有端点视端点实现状态、版本等信息查询
/.well-known/发现文件匿名委托部署时告知客户端/联邦真实地址(配置见 C1 篇)

先确认服务存活与版本(无需认证):

curl -s http://127.0.0.1:8008/_continuwuity/server_version
{"name":"continuwuity","version":"26.9.1 (046074b)"}

三、版本与服务发现(无需认证)

3.1 Client API 版本协商:GET /_matrix/client/versions

curl -s http://127.0.0.1:8008/_matrix/client/versions
{"versions":["r0.0.1","r0.1.0","r0.2.0","r0.3.0","r0.4.0","r0.5.0","r0.6.0","r0.6.1","v1.1","v1.2","v1.3","v1.4","v1.5","v1.8","v1.11","v1.12","v1.13","v1.14","v1.15","v1.16","v1.17","v1.18"],"unstable_features":{"computer.gingershaped.msc4466":true,"org.matrix.msc4143":true,"org.matrix.msc4155":true,"org.matrix.msc4174":true,"org.matrix.simplified_msc3575":true,...}}

v26.9.1 支持到 Client-Server API v1.18,并带若干 MSC 实验特性(如 MSC4143 低频联邦探测、MSC4174 WebPush)。客户端据此决定可调用的最高版本路径,下文统一使用 v3 路径前缀(/_matrix/client/v3/...)。

3.2 联邦版本:GET /_matrix/federation/v1/version

curl -s http://127.0.0.1:8008/_matrix/federation/v1/version
{"server":{"name":"continuwuity","version":"26.9.1 (046074b)"}}

这是联邦侧探测本端实现与版本的标准端点,与 /_continuwuity/server_version 信息一致,仅外层多一个 server 包装。

四、认证域

4.1 密码登录:POST /_matrix/client/v3/login

正确口令(管理员 admin / q1w2e3r4):

curl -s -X POST -H "Content-Type: application/json" \
  -d '{"type":"m.login.password","identifier":{"type":"m.id.user","user":"admin"},"password":"q1w2e3r4"}' \
  http://127.0.0.1:8008/_matrix/client/v3/login
{"user_id":"@admin:example.com","access_token":"JGAZcCt9RvhSwOISF8BujOgw","home_server":"example.com","device_id":"iw1Bo6zz5i"}

返回的 access_token 是后续一切受保护调用的凭证;device_id 标识本次登录设备。错误口令:

curl -s -X POST -H "Content-Type: application/json" \
  -d '{"type":"m.login.password","identifier":{"type":"m.id.user","user":"admin"},"password":"wrongpass"}' \
  http://127.0.0.1:8008/_matrix/client/v3/login
{"errcode":"M_FORBIDDEN","error":"Invalid identifier or password."}

注意错误码是 M_FORBIDDEN(403)而非 401,且文案不区分「用户不存在」与「密码错误」——这是 Matrix 规范要求的防枚举行为。

后续命令统一把令牌放进环境变量:

TOKEN=JGAZcCt9RvhSwOISF8BujOgw

4.2 验证令牌:GET /_matrix/client/v3/account/whoami

curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8008/_matrix/client/v3/account/whoami
{"user_id":"@admin:example.com","device_id":"iw1Bo6zz5i"}

不带令牌访问受保护端点:

curl -s http://127.0.0.1:8008/_matrix/client/v3/account/whoami
{"errcode":"M_UNAUTHORIZED","error":"Failed to extract authorization: no access token found, but this endpoint requires one"}

4.3 开放注册默认关闭:POST /_matrix/client/v3/register

allow_registration 默认为 false,直接注册被拒:

curl -s -X POST -H "Content-Type: application/json" \
  -d '{"username":"hacker","password":"x","auth":{"type":"m.login.dummy"}}' \
  http://127.0.0.1:8008/_matrix/client/v3/register
{"errcode":"M_FORBIDDEN","error":"This server is not accepting registrations at this time."}

要放人进来有两条路(均见 C1 篇与本文第八节):配置 registration_token 后客户端在注册流程提交令牌,或管理员用 !admin token 命令签发一次性注册令牌。

五、能力协商:GET /_matrix/client/v3/capabilities

curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8008/_matrix/client/v3/capabilities
{"capabilities":{"m.room_versions":{"default":"12","available":{"10":"stable","11":"stable","12":"stable","3":"unstable","4":"unstable","5":"unstable","6":"stable","7":"stable","8":"stable","9":"stable"}},"m.3pid_changes":{"enabled":false},"m.get_login_token":{"enabled":true},"m.profile_fields":{"enabled":true,"disallowed":[]},"m.forget_forced_upon_leave":{"enabled":true},"m.account_moderation":{"suspend":true,"lock":true},"org.matrix.msc4174.webpush":{"enabled":true,"vapid":"BNjJVmnYTgYE-0rFihkVP2_2jAfFtA3rJwvCFJvemAYIL8ZPfGMqLAKMVldBWnHALhC_TrSCXtK5L5ruz_8W5k0"}}}

要点:

  • 默认房间版本 12(Matrix 当前稳定房间版本,对应配置 default_room_version,见 C1 篇 5.2 节);
  • m.3pid_changes: false——不支持自助绑定/解绑邮箱、手机号第三方标识;
  • m.account_moderation: suspend/lock——v26 新增的账号封禁/锁定管理能力(配合 !admin users 子命令使用)。

六、房间域

6.1 创建房间:POST /_matrix/client/v3/createRoom

curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"name":"测试房间","topic":"API 实测房间","preset":"public_chat"}' \
  http://127.0.0.1:8008/_matrix/client/v3/createRoom
{"room_id":"!UKSF8pTVEHmRTB1bPHrd8ZrQ-rmY4BH8J_SbMkiSnGw"}

preset 三选一:private_chat(默认,邀请制)、trusted_private_chat(邀请制+受邀者高权限)、public_chat(任何人可加入)。注意 public_chat 只决定加入规则,并不会把房间挂到公开目录(见 6.3)。记下返回的 room_id,后续消息读写都用它。

6.2 列出已加入房间:GET /_matrix/client/v3/joined_rooms

curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8008/_matrix/client/v3/joined_rooms
{"joined_rooms":["!hYLQQMztlXqxJ1bB4jKrz6oYg7HkZeBRTUpQY0hCmOQ","!UKSF8pTVEHmRTB1bPHrd8ZrQ-rmY4BH8J_SbMkiSnGw"]}

其中第一个 !hYLQQMztlXqx... 是服务器自动把管理员拉入的 #admin 管理房间(第八节要用)。

6.3 房间目录:发布与浏览

默认新房不出现在公开目录:

curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8008/_matrix/client/v3/publicRooms
{"chunk":[],"total_room_count_estimate":0}

把房间发布到目录:PUT /_matrix/client/v3/directory/list/room/{roomId}

curl -s -X PUT -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"visibility":"public"}' \
  "http://127.0.0.1:8008/_matrix/client/v3/directory/list/room/!UKSF8pTVEHmRTB1bPHrd8ZrQ-rmY4BH8J_SbMkiSnGw"
{}

再次查询:

curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8008/_matrix/client/v3/publicRooms
{"chunk":[{"name":"测试房间","num_joined_members":1,"room_id":"!UKSF8pTVEHmRTB1bPHrd8ZrQ-rmY4BH8J_SbMkiSnGw","topic":"API 实测房间","world_readable":false,"guest_can_join":false}],"total_room_count_estimate":1}

visibility 取 private 即从目录下架。

七、消息域

7.1 发送消息:PUT /rooms/{roomId}/send/{eventType}/{txnId}

ROOM='!UKSF8pTVEHmRTB1bPHrd8ZrQ-rmY4BH8J_SbMkiSnGw'
curl -s -X PUT -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"msgtype":"m.text","body":"Hello Continuwuity API"}' \
  "http://127.0.0.1:8008/_matrix/client/v3/rooms/$ROOM/send/m.room.message/txn001"
{"event_id":"$DhB3pj_t7lk8WsEJK0KBcaOIqdKyepmZXbYNJmwDHUI"}

txnId(事务 ID)由客户端生成,用于幂等去重——网络重试时同一 txnId 不会产生重复消息。再发一条中文消息:

curl -s -X PUT -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"msgtype":"m.text","body":"第二条消息"}' \
  "http://127.0.0.1:8008/_matrix/client/v3/rooms/$ROOM/send/m.room.message/txn002"
{"event_id":"$vkLRK93fP7SQWpExiHVYfYrdNKxyZBuXQ9I59GllVYI"}

7.2 读取历史:GET /rooms/{roomId}/messages

curl -s -H "Authorization: Bearer $TOKEN" \
  "http://127.0.0.1:8008/_matrix/client/v3/rooms/$ROOM/messages?dir=b&limit=5"

格式化后的回显(实测):

{
    "start": "9223372036854775807",
    "end": "144",
    "chunk": [
        {
            "content": {"body": "第二条消息", "msgtype": "m.text"},
            "event_id": "$vkLRK93fP7SQWpExiHVYfYrdNKxyZBuXQ9I59GllVYI",
            "origin_server_ts": 1792900601318,
            "room_id": "!UKSF8pTVEHmRTB1bPHrd8ZrQ-rmY4BH8J_SbMkiSnGw",
            "sender": "@admin:example.com",
            "type": "m.room.message",
            "unsigned": {"age": 10770, "membership": "join", "transaction_id": "txn002"}
        },
        {
            "content": {"body": "Hello Continuwuity API", "msgtype": "m.text"},
            "event_id": "$DhB3pj_t7lk8WsEJK0KBcaOIqdKyepmZXbYNJmwDHUI",
            "origin_server_ts": 1792900601311,
            "room_id": "!UKSF8pTVEHmRTB1bPHrd8ZrQ-rmY4BH8J_SbMkiSnGw",
            "sender": "@admin:example.com",
            "type": "m.room.message",
            "unsigned": {"age": 10777, "membership": "join", "transaction_id": "txn001"}
        },
        { "...(略)": "m.room.topic / m.room.name / m.room.guest_access 三个房间状态事件" }
    ]
}

dir=b 表示从最新往前翻;end 即下次翻页用的 from 令牌(见第九节)。可以看到建房时的名称、话题等状态事件也在时间线里。

7.3 增量同步:GET /_matrix/client/v3/sync

客户端的主循环端点,一次拉回所有房间的新事件:

curl -s -H "Authorization: Bearer $TOKEN" \
  "http://127.0.0.1:8008/_matrix/client/v3/sync?timeout=3000"

回显较长,截取关键结构(实测):

{"next_batch":"169","rooms":{"join":{"!UKSF8pTVEHmRTB1bPHrd8ZrQ-rmY4BH8J_SbMkiSnGw":{"summary":{"m.joined_member_count":1,"m.invited_member_count":0},"unread_notifications":{"highlight_count":0,"notification_count":0},"timeline":{"prev_batch":"114","events":[{"content":{"room_version":"12"},"event_id":"$UKSF8pTVEHmRTB1bPHrd8ZrQ-rmY4BH8J_SbMkiSnGw","type":"m.room.create",...},...]}}},...}}

next_batch 是下次同步的 since 游标;timeout=3000 表示长轮询最多挂 3 秒等事件。房间时间线里的 prev_batch 则对接 7.2 的历史翻页。

八、服务器管理:管理房间机器人命令

Continuwuity 把服务器管理做成了一个 Matrix 房间:首个管理员注册时,服务端机器人 @conduit:example.com 会创建 #admin 房间并把管理员拉入,欢迎消息里写明「This room is your server's admin room」。在房间里发以 !admin 开头的消息即执行管理命令——本质是把命令当 m.room.message 发到管理房间,机器人以房间消息回复。因此用 API 也能完成全部管理操作。

8.1 命令树:!admin --help

向管理房间发送:

ADMIN='!hYLQQMztlXqxJ1bB4jKrz6oYg7HkZeBRTUpQY0hCmOQ'
curl -s -X PUT -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"msgtype":"m.text","body":"!admin --help"}' \
  "http://127.0.0.1:8008/_matrix/client/v3/rooms/$ADMIN/send/m.room.message/txn103"
{"event_id":"$vRGvMv8tKyyS5FAsMEOQG1B7kX_2qMubGbpe7KlmdtY"}

读取管理房间消息即可看到机器人回复(dir=b&limit=2 取最新两条):

Usage: !admin <COMMAND>

Commands:
  appservices  Commands for managing appservices
  users        Commands for managing local users
  token        Commands for managing registration tokens
  oidc         Commands for managing OIDC
  rooms        Commands for managing rooms
  federation   Commands for managing federation
  server       Commands for managing the server
  media        Commands for managing media
  check        Commands for checking integrity
  debug        Commands for debugging things
  query        Low-level queries for database getters and iterators
  help         Print this message or the help of the given subcommand(s)

Options:
  -h, --help     Print help
  -V, --version  Print version

每个子命令还有下一级(如 !admin users --help),常用路径:users(本地用户)、token(注册令牌)、rooms(房间管控)、federation(联邦黑名单等)、server(服务器级操作)、media(媒体配额与清理)。

8.2 列出本地用户:!admin users list

发送命令(同上,body 换成 "!admin users list"),机器人回复:

Found 2 local user account(s):
```
@admin:example.com
@conduit:example.com
```

即当前服务器只有两个本地账号:管理员与机器人自身。

8.3 创建用户:!admin users create-user

body 换成 "!admin users create-user testuser1",机器人回复:

Created new user account for @testuser1:example.com

Created user @testuser1:example.com with password `8zpPHdvAvFL93b4hLFehWEMWC`

服务端为该用户生成了随机密码。立即用新账号走 4.1 的登录端点验证:

curl -s -X POST -H "Content-Type: application/json" \
  -d '{"type":"m.login.password","identifier":{"type":"m.id.user","user":"testuser1"},"password":"8zpPHdvAvFL93b4hLFehWEMWC"}' \
  http://127.0.0.1:8008/_matrix/client/v3/login
{"user_id":"@testuser1:example.com","access_token":"cYe2mrfpEv1xZYlOBRdPYukk","home_server":"example.com","device_id":"5uZCDU3Rak"}

登录成功,说明「机器人建号 → API 登录」链路闭环。要创建管理员账号加 --admin 标志(!admin users create-user <name> --admin)。

九、分页与错误码约定

分页:messages、publicRooms、sync 等列表端点统一用令牌游标——响应里的 end/next_batch 作为下次请求的 from/since;dir=b 向历史翻、dir=f 向最新翻;limit 控制单页条数。不要试图解析令牌内容(v26.9.1 的游标是纯数字但属于内部实现)。

错误结构:所有错误统一为 {"errcode": "M_xxx", "error": "人类可读描述"},本文实测遇到:

errcodeHTTP触发场景
M_UNAUTHORIZED401受保护端点未带 access_token(4.2)
M_FORBIDDEN403密码错误(4.1)、未开放注册(4.3)、无权限操作
M_LIMIT_EXCEEDED429触发限流(配置 sender_limit 等,见 C1 篇)

十、FAQ

Q1:Continuwuity 有没有 conduwuit user create 这类独立管理 CLI? 没有。conduwuit --help 只有启动参数(-c/-O/--maintenance/--console/--execute/-h/-V),无任何管理子命令。管理=Client API + 管理房间 !admin 命令。这也是本文替代「常用 CLI 命令详解」篇型的原因。--console 仅提供一个启动期的调试控制台,--execute 只执行单条启动命令,都不是日常管理入口。

Q2:access_token 泄露了怎么办? 调 POST /_matrix/client/v3/logout(吊销当前令牌)或 logout_all(吊销该用户全部令牌),或让管理员在管理房间执行 !admin users deactivate @user:example.com 后重建。

Q3:为什么我在外部机器 curl 不通 8008? 默认 address = ["127.0.0.1", "::1"] 只监听回环。生产正确做法是保持回环监听、前置 Nginx/Caddy 反向代理终结 TLS(well-known 与反代配置见 C1 篇 5.10 节),而不是直接把 8008 暴露到公网。

Q4:这些 API 和 Synapse、conduwuit 兼容吗? /_matrix/client/ 与 /_matrix/federation/ 是 Matrix 规范标准端点,客户端(Element、FluffyChat 等)与联邦对端无差别可用;/_continuwuity/ 前缀是 Continuwuity 私有信息端点,各实现不同。管理机器人命令语法与 conduwuit 同源(都是 !admin 前缀),但子命令集随版本演进,以 !admin --help 实测输出为准。

Q5:能用 API 批量导入用户吗? 可以,循环调 !admin users create-user(管理房间消息)或先用 !admin token create 签发注册令牌再走标准 register 流程。注意 register 有 UIAA(交互式认证)流程,脚本里用令牌认证阶段 m.login.registration_token 一步到位。

十一、参考链接