이벤트 스트림
조직 및 프로젝트 활동을 위한 서버 전송 이벤트.
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 서명 웹 JWT. 인증을 참조하세요. 호출자는
조직의 멤버여야 합니다. 비멤버는 403을 받습니다.
이벤트 봉투
모든 이벤트는 안정적인 형태를 가진 하나의 JSON 객체입니다:
| 필드 | 유형 | 의미 |
|---|---|---|
id | string | ULID(26자). 단조 증가. SSE 이벤트 id 역할도 합니다. |
type | string | 이벤트 유형, 예: operation.updated.v1. |
source | string | 생산 서브시스템, 예: operations. |
org_id | string | 소유 조직(UUID 텍스트). |
project_id | string? | 소유 프로젝트. 조직 수준 이벤트에서는 생략됩니다. |
region_id | string | 이벤트를 방출한 리전. |
at | string | RFC 3339 타임스탬프. |
data | object | 유형별 페이로드. |
봉투 형태는 호환되지 않게 변경되지 않습니다. 새 필드는 추가적이며, 새 이벤트
변형은 기존 것을 변형하는 대신 새 type(예: 향후
operation.updated.v2)을 받습니다.
이벤트 유형
오늘날 컨트롤 플레인은 하나의 애플리케이션 이벤트 유형을 게시합니다:
operation.updated.v1(sourceoperations) — 작업이 수명 주기 상태를 변경했습니다.data는operation_id,action,status를 지니며, 행이 여전히 존재할 때는branch_id,endpoint_id,error,initiator도 지닙니다.
브로커는 또한 세 가지 내부 제어 이벤트(source _broker)를 방출합니다:
resume.gap.v1— 당신의Last-Event-ID가 브로커의 버퍼보다 오래되었습니다. 이벤트가 누락되었습니다. REST를 통해 전체 상태를 다시 가져온 다음 스트리밍을 계속하세요.overflow.v1— 당신의 클라이언트가 너무 느리게 읽어서 드롭되었습니다.data.dropped가 잃어버린 이벤트 수를 셉니다. 다시 연결하고 전체 상태를 다시 가져오세요.error.v1— 생산자 측 오류 마커.
audit, invitations, billing 소스는 예약되어 있지만 아직 이벤트를
방출하지 않습니다. 이 목록은 해당 트랙이 출시됨에 따라 늘어납니다.
재개
각 이벤트의 id는 그 SSE id이므로, 네이티브 EventSource는 재연결 시
마지막 것을 Last-Event-ID 헤더로 자동으로 다시 보내고, 브로커는 그 이후
버퍼링된 모든 것을 재생합니다. 명시적으로 전달할 수도 있습니다:
Last-Event-ID: 01JX5N4R8ZT2W7Q9V3B1C6D8EF간격이 브로커의 인메모리 링보다 넓으면 재생 대신 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.v1 또는 overflow.v1에서 콘솔은 REST를
통해 전체 상태를 다시 가져옵니다 — 정확히 위의 계약대로입니다. 자신만의
소비자를 만들고 있다면 그 동작을 그대로 따르세요.