kisenon

事件流

面向组织和项目活动的服务器发送事件。

Kisenon 将组织和项目活动以 服务器发送事件 的形式流式推送。打开一个长期的 HTTP 连接,设置 Accept: text/event-stream,每当有变化发生时,控制平面就会推送一个 JSON 信封。

控制台的实时活动视图正是基于这同一个流来驱动的。

端点

两条路由,都是 SSE:

路由作用域
GET /v1/events调用方组织中的每个项目。
GET /v1/projects/{id}/events单个项目。

两者都位于 https://api.test.kisenon.com 之下。如果项目不属于您的 组织,项目作用域的路由会返回 404,因此存在性永远不会跨组织泄露。

身份验证

与其他每个控制平面调用相同的 Bearer 凭据:一个 API 密钥 (nsk_…)或一个由 cp 签名的 web JWT。参见 身份验证。 调用方必须是该组织的成员;非成员会得到一个 403

事件信封

每个事件都是一个形态稳定的 JSON 对象:

字段类型含义
idstringULID(26 个字符)。单调递增;同时充当 SSE 事件 id。
typestring事件类型,例如 operation.updated.v1
sourcestring产生事件的子系统,例如 operations
org_idstring所属组织(UUID 文本)。
project_idstring?所属项目;组织级事件中省略。
region_idstring发出该事件的区域。
atstringRFC 3339 时间戳。
dataobject类型特定的负载。

信封形态永远不会以不兼容的方式变更。新字段是增量式的,而新的事件 变体会获得一个新的 type(例如未来的 operation.updated.v2), 而不是改变现有的。

事件类型

如今控制平面发布一种应用事件类型:

  • operation.updated.v1(source 为 operations)—— 一个操作改变了 生命周期状态。data 携带 operation_idactionstatus, 以及当该行仍然存在时,branch_idendpoint_iderrorinitiator

broker 还发出三种内部控制事件(source 为 _broker):

  • resume.gap.v1 —— 您的 Last-Event-ID 比 broker 的缓冲区更旧; 有事件被遗漏了。通过 REST 重新获取完整状态,然后继续流式接收。
  • overflow.v1 —— 您的客户端读取太慢而被丢弃;data.dropped 统计丢失的事件数。重新连接并重新获取完整状态。
  • error.v1 —— 一个生产者侧的错误标记。

auditinvitationsbilling 这几个 source 是预留的,但尚不 发出事件;随着那些工作线落地,这个列表会增长。

续传

每个事件的 id 就是它的 SSE id,因此一个原生的 EventSource 会在 重连时自动将最后一个作为 Last-Event-ID 头重新发送,broker 会重放 其后缓冲的一切。您也可以显式传入它:

Last-Event-ID: 01JX5N4R8ZT2W7Q9V3B1C6D8EF

如果间隔比 broker 的内存环更宽,您会收到一个 resume.gap.v1 而非 重放。把它(以及 overflow.v1)当作"您遗漏了事件":通过 REST API 重新获取受影响的状态,然后从最新的 id 续传流式接收。

示例

curl -N -H "Authorization: Bearer $KISENON_API_KEY" \
  -H "Accept: text/event-stream" \
  https://api.test.kisenon.com/v1/events

一个流式事件看起来像:

id: 01JX5N4R8ZT2W7Q9V3B1C6D8EF
event: operation.updated.v1
data: {"id":"01JX5N4R8ZT2W7Q9V3B1C6D8EF","type":"operation.updated.v1","source":"operations","org_id":"6f1d2c3b-4a59-4e87-9b10-2d3e4f5a6b7c","project_id":"prj_4c1d9e2a7b3f5c8d0e1f2a3b","region_id":"home-proxmox","at":"2026-06-03T12:00:00Z","data":{"operation_id":"op_77a1","action":"create_branch","status":"finished","branch_id":"br_91c2"}}

: 开头的行(例如 : keepalive)是心跳注释;忽略它们。

在控制台中

控制台的实时活动视图消费这同一个流(通过控制台来源代理,因为浏览器 的 EventSource 无法设置 Authorization 头)。在 resume.gap.v1overflow.v1 时,它会通过 REST 重新获取完整状态 —— 正是上面的 约定。如果您正在构建自己的消费者,请照此行事。

相关