Conduit 0.10.15 API 使用详解

Conduit 0.10.15 Matrix Client-Server API 使用详解:UIAA 两步注册、登录/登出、whoami、房间与消息、错误码与 admin 房间机器人管理命令全集,全部 curl 实测回显。

ConduitConduitMatrix自托管即时通信2026/10/25

Conduit 0.10.15 API 使用详解

目标:用 curl 调通 Conduit 0.10.15 的 Matrix Client-Server API 全流程——版本探测、UIAA 两步注册、登录/登出、身份确认、建房、发消息、读消息、错误码处理,以及 admin 房间机器人管理命令全集。全部请求与响应均在 Conduit v0.10.15 真实环境逐条实测,回显原样照抄。

一、环境信息

  • 服务端:Conduit v0.10.15(conduit 0.10.15 (db37763)),监听 127.0.0.1:8128;
  • server_name:conduit.example.com;注册令牌:q1w2e3r4-reg-token;
  • 演示账号:admin / 密码 q1w2e3r4(本文第一个注册的用户,自动获得管理房间);
  • 客户端工具:curl(任意 Linux 发行版自带或 apt-get install -y curl);
  • API 基准:Matrix Client-Server API,实测覆盖 r0.5.0~v1.12;本文统一用稳定版前缀 /_matrix/client/v3。

二、前置条件

  1. Conduit 服务已启动(安装见《Ubuntu 22.04 安装 Conduit 0.10.15 指南》或《Conduit Docker Compose 部署指南》),且 allow_registration = true、已配置 registration_token;
  2. 本文所有命令在能访问服务端口(8128)的机器上执行;你自己的环境把 http://127.0.0.1:8128 替换为实际地址即可。

三、API 总览

  • 协议:Matrix Client-Server API,REST 风格、JSON 报文,稳定版路径前缀 /_matrix/client/v3(另有 /_matrix/client/versions 等无前缀端点);
  • 认证:除版本探测与注册/登录外,一律在请求头携带访问令牌:Authorization: Bearer <access_token>;
  • 令牌生命周期:登录/注册签发 access_token + device_id;调用 logout 后该令牌立即失效(本文有实测对照);
  • 限流:Conduit 按来源 IP 做限流(配置项 ip_address_detection,默认读 X-Forwarded-For,反代后需正确传递);本文测试量级未触发限流。

四、认证与首次调用

本章完成「探测版本 → 注册账号 → 登录 → 确认身份 → 登出」的完整闭环。

4.1 版本探测(无需认证)

curl -s http://127.0.0.1:8128/_matrix/client/versions

实测响应(r0.5.0~v1.12,并启用 E2EE 交叉签名等不稳定特性):

{"versions":["r0.5.0","r0.6.0","v1.1","v1.2","v1.3","v1.4","v1.5","v1.6","v1.7","v1.8","v1.9","v1.10","v1.11","v1.12"],"unstable_features":{"org.matrix.e2e_cross_signing":true,"org.matrix.msc3916.stable":true,"org.matrix.simplified_msc3575":true}}

4.2 注册账号(UIAA 两步 + 注册令牌)

Matrix 注册走 UIAA(User-Interactive Authentication) 多阶段认证:第一步不带 auth 发起请求,服务端以 401 返回所需认证流程与 session 标识;第二步携带 session 与对应阶段的凭据完成注册。

第一步:

curl -s -X POST http://127.0.0.1:8128/_matrix/client/v3/register \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"q1w2e3r4"}'

实测响应(HTTP 401;flows 声明需要 m.login.registration_token 阶段):

{"flows":[{"stages":["m.login.registration_token"]}],"session":"wCtiQwV7ZbS0TNP25tTFcJX8wqv7JyqA"}

第二步(session 换上一步返回的值,token 即服务端配置的 registration_token):

curl -s -X POST http://127.0.0.1:8128/_matrix/client/v3/register \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"q1w2e3r4","auth":{"type":"m.login.registration_token","token":"q1w2e3r4-reg-token","session":"wCtiQwV7ZbS0TNP25tTFcJX8wqv7JyqA"}}'

实测注册成功响应:

{"access_token":"OOh9cF5DTMCcts5qHYDGtwmIMsAzq1Ub","user_id":"@admin:conduit.example.com","device_id":"bpPzcaktvK"}

返回三要素:access_token(后续 API 的 Bearer 令牌)、user_id(完整 Matrix ID)、device_id(本次设备标识)。

💡 说明:服务端关闭注册(allow_registration = false)时,第一步即返回 403 {"errcode":"M_FORBIDDEN","error":"M_FORBIDDEN: Registration has been disabled."}(实测);未提供令牌或令牌错误时同样在第二步被拒。

4.3 登录

已有账号用密码登录(m.login.password):

curl -s -X POST http://127.0.0.1:8128/_matrix/client/v3/login \
  -H 'Content-Type: application/json' \
  -d '{"type":"m.login.password","identifier":{"type":"m.id.user","user":"admin"},"password":"q1w2e3r4"}'

实测响应:

{"user_id":"@admin:conduit.example.com","access_token":"7eHZt7xRZwCdWKFCk0i4JZfmEzFP8ksG","home_server":"conduit.example.com","device_id":"Uygt7hvz87"}

密码错误实测(HTTP 403):

{"errcode":"M_FORBIDDEN","error":"M_FORBIDDEN: Wrong username or password."}

4.4 确认当前身份(whoami)

用 4.3 登录拿到的令牌确认身份:

curl -s -H "Authorization: Bearer 7eHZt7xRZwCdWKFCk0i4JZfmEzFP8ksG" \
  http://127.0.0.1:8128/_matrix/client/v3/account/whoami

实测响应:

{"user_id":"@admin:conduit.example.com","device_id":"Uygt7hvz87"}

4.5 登出与令牌失效

curl -s -X POST http://127.0.0.1:8128/_matrix/client/v3/logout \
  -H "Authorization: Bearer 7eHZt7xRZwCdWKFCk0i4JZfmEzFP8ksG"

实测响应(空对象即成功):

{}

登出后再用同一令牌调 whoami,实测返回 HTTP 401(令牌立即失效):

{"errcode":"M_UNKNOWN_TOKEN","error":"M_UNKNOWN_TOKEN: Unknown access token."}

4.6 服务能力(capabilities)

curl -s -H "Authorization: Bearer <有效令牌>" \
  http://127.0.0.1:8128/_matrix/client/v3/capabilities

实测响应(房间版本能力:默认 12,可用 6–12 stable、3–5 unstable):

{"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"}}}}

五、房间与消息 API

本章完成「建房 → 发消息 → 读消息 → 查房间列表」闭环。以下命令的 <TOKEN> 换成 4.2/4.3 实际拿到的令牌。

5.1 创建房间

curl -s -X POST http://127.0.0.1:8128/_matrix/client/v3/createRoom \
  -H "Authorization: Bearer <TOKEN>" \
  -H 'Content-Type: application/json' \
  -d '{"name":"Conduit 实测房间","topic":"Conduit 实测房间"}'

实测响应(room_id 以 ! 开头、server_name 为后缀):

{"room_id":"!zLcm2ktwPH7SZCSvdoaoEnADY_8vmjIEFnc4yBjqlWc"}

5.2 发送文本消息

路径中 {roomId} 为房间 ID、{txnId} 为客户端生成的事务 ID(幂等去重用,重复提交同一 txnId 不会重发):

curl -s -X PUT "http://127.0.0.1:8128/_matrix/client/v3/rooms/!zLcm2ktwPH7SZCSvdoaoEnADY_8vmjIEFnc4yBjqlWc/send/m.room.message/txn1" \
  -H "Authorization: Bearer <TOKEN>" \
  -H 'Content-Type: application/json' \
  -d '{"msgtype":"m.text","body":"Hello Conduit"}'

实测响应(event_id 以 $ 开头):

{"event_id":"$rt2Z0PCU1nhRlyuDk71FVtIgs5DoX3r1q0EHP5YD8bg"}

5.3 读取房间消息

dir=b 表示向前(向历史方向)翻页,limit 控制条数;响应 chunk 为消息事件、state 为相关状态事件:

curl -s "http://127.0.0.1:8128/_matrix/client/v3/rooms/!zLcm2ktwPH7SZCSvdoaoEnADY_8vmjIEFnc4yBjqlWc/messages?dir=b&limit=10" \
  -H "Authorization: Bearer <TOKEN>"

实测响应(逐字段真实回显;可见 5.2 发送的 Hello Conduit 与建房时的 topic 状态事件,以及成员显示名 admin ⚡️——enable_lightning_bolt 的效果):

{"start":"18446744073709551615","end":"246","chunk":[{"content":{"body":"Hello Conduit","msgtype":"m.text"},"event_id":"$rt2Z0PCU1nhRlyuDk71FVtIgs5DoX3r1q0EHP5YD8bg","origin_server_ts":1792897115538,"room_id":"!zLcm2ktwPH7SZCSvdoaoEnADY_8vmjIEFnc4yBjqlWc","sender":"@admin:conduit.example.com","type":"m.room.message","unsigned":{"age":1,"transaction_id":"1792897115528314159"}},{"content":{"m.topic":{"m.text":[{"body":"Conduit 实测房间"}]},"topic":"Conduit 实测房间"},"event_id":"$N-IZZI5jewOaWV8XbRo81T6UF5SrOG9TVyxW275yWgY","origin_server_ts":1792897102320,"room_id":"!zLcm2ktwPH7SZCSvdoaoEnADY_8vmjIEFnc4yBjqlWc","sender":"@admin:conduit.example.com","state_key":"","type":"m.room.topic","unsigned":{"age":1}}],"state":[{"content":{"displayname":"admin ⚡️","is_direct":false,"membership":"join"},"event_id":"$yo2yxhsS3dIkKaPk2eGdXcyhvDMLdlV5zNiahcpG1Js","origin_server_ts":1792897102318,"room_id":"!zLcm2ktwPH7SZCSvdoaoEnADY_8vmjIEFnc4yBjqlWc","sender":"@admin:conduit.example.com","state_key":"@admin:conduit.example.com","type":"m.room.member","unsigned":{}}]}

翻页约定:下一次请求带 from=<本次响应的 end 值> 即可继续向历史翻页。

5.4 查询已加入的房间

curl -s -H "Authorization: Bearer <TOKEN>" \
  http://127.0.0.1:8128/_matrix/client/v3/joined_rooms

实测响应(两个房间:5.1 创建的房间 + 系统自动拉入的管理房间,见第六章):

{"joined_rooms":["!zLcm2ktwPH7SZCSvdoaoEnADY_8vmjIEFnc4yBjqlWc","!zogz3xkquX8M84FAItXEzLh6lvQp9o7h-s5L-bW3d3A"]}

六、admin 房间管理命令

Conduit 没有独立的管理 CLI/管理 API,服务器管理通过「admin 房间」进行:第一个注册的用户会被自动邀请加入与系统用户 @conduit:<域名> 的会话房间(5.4 实测列表中的第二个房间即它),在房间里以消息形式向机器人发命令。

6.1 调用方式

向 admin 房间发送一条 m.room.message,正文为 @conduit:<server_name>: <命令>。以查询全部命令为例:

curl -s -X PUT "http://127.0.0.1:8128/_matrix/client/v3/rooms/!zogz3xkquX8M84FAItXEzLh6lvQp9o7h-s5L-bW3d3A/send/m.room.message/txn2" \
  -H "Authorization: Bearer <TOKEN>" \
  -H 'Content-Type: application/json' \
  -d '{"msgtype":"m.text","body":"@conduit:conduit.example.com: --help"}'

实测响应(消息入队成功):

{"event_id":"$AvqLayu8R6eH3wQWjpsjtQulj-VEUhOQ2kXazGGhQro"}

随后用 5.3 的 messages 接口读该房间,即可看到机器人的回复消息。

6.2 命令全集(v0.10.15 实测)

机器人 --help 实测回复的完整命令清单(按用途分组整理,命令名逐字照抄):

分组命令作用
用户管理create-user创建新用户
用户管理reset-password重置用户密码
用户管理deactivate-user / deactivate-all停用单个/一批用户
用户管理list-local-users列出本地用户
注册管控allow-registration临时开关注册(true/false,重启后不保留)
房间管理list-rooms列出服务器已知的全部房间
房间管理disable-room / enable-room关闭/恢复某房间的入向联邦处理
房间管理remove-alias移除房间别名
房间管理incoming-federation列出正在处理入向 PDU 的房间
媒体治理query-media / show-media / list-media查询/预览/列选媒体
媒体治理purge-media / purge-media-from-users / purge-media-from-server按 MXC 列表/用户/来源服务器删除媒体
媒体治理block-media / block-media-from-users / list-blocked-media / unblock-media按 SHA256 封禁/解封媒体(封禁不删已下载文件)
应用服务register-appservice / unregister-appservice / list-appservices按注册 YAML 登记/注销/列出 appservice(桥)
系统与调试show-config查看当前生效配置
系统与调试memory-usage打印数据库内存占用统计
系统与调试clear-database-caches / clear-service-caches清理数据库/服务缓存
系统与调试get-auth-chain / parse-pdu / get-pdu取事件认证链/解析 PDU/按 ID 取 PDU
系统与调试sign-json / verify-json / hash-and-sign-event用服务器钥匙签名/验签/构造事件
帮助help打印帮助(-h/--help、-V/--version)

表格解读:管理面覆盖了「用户、房间、媒体、桥、缓存、签名调试」六类日常运维动作;其中 allow-registration 的临时开关与配置文件的 allow_registration 是两套开关(一个运行时、一个持久),生产管控注册时两处都要留意。

七、错误码与异常处理

本文实测到的错误形态汇总:

HTTPerrcode触发场景处理
401 + flows 体(无 errcode)注册第一步(UIAA 流程声明)非错误,按 flows 完成第二步
403M_FORBIDDEN密码错误:Wrong username or password.核对账号密码
403M_FORBIDDEN注册被关闭:Registration has been disabled.开启 allow_registration 或找管理员建房/建号
401M_UNKNOWN_TOKEN令牌无效或已登出:Unknown access token.重新登录获取令牌

八、常见问题(FAQ)

Q1:令牌放哪? 统一放请求头 Authorization: Bearer <access_token>;不要放 URL query(access_token= 是旧版做法,容易进日志泄露)。

Q2:注册第二步报 session 相关错误? UIAA 的 session 有时效且必须与第一步一致;失败就重新走第一步拿新 session。客户端掉线重试时同理。

Q3:不想用 curl,图形客户端怎么接? 客户端登录时 homeserver 填 http://127.0.0.1:8128(生产填域名,配合 well-known 委派);开启注册令牌时官方点名支持令牌填写的客户端为 Element web、Nheko、SchildiChat web。

Q4:怎么确认某条消息发成功了? send 接口返回 event_id 即已落库;用 5.3 的 messages 接口按 dir=b 拉最新一条核对 content.body 与 event_id 即可(本文实测对照一致)。

Q5:admin 房间找不到? 只有本服务器第一个注册的用户会被自动拉入 admin 房间;后续用户需由该管理员邀请。房间 ID 用 5.4 的 joined_rooms 查看(与 @conduit 系统用户共处的那个)。

九、参考链接