Subscribe to a session's live event stream
Server-Sent Events. Every scan (`/scan`, `/rag/*`, `/agent/*`) that carries the same `session_id` publishes a compact decision summary here the moment it's made (no scanned text, tool arguments, or redacted content ever appears on this stream, only the decision itself). This is what the SDK's `subscribe()` connects to. Three event shapes appear as `data:` frames, distinguished by `stage`: - A decision (`stage`: `prompt`, `rag`, `tool`, or `response`): `action`, `risk` (0-100), `latency` (ms), the policy directives that fired, a `job_id`, and a `pii` summary when any was found. `action` is the engine's label (lowercase, so `review` appears here). `needs_review` (boolean) and `enforced_action` (`allow` or `block`, the action the gateway enforced after applying your app's `reviewCollapse` setting) are added from the `review_flag` release onward. `tool`/`rag` stages also carry `phase` (`call`/`output` or `chunk`/`context`) and, for `tool`, the tool name. - `{"stage": "audit", "id": "<job_id>"}`: sent once that job's decision has been durably persisted, always after that job's decision event. - `{"stage": "_meta", "dropped": <n>}`: this connection fell behind and missed `n` events; never sent silently. The connection is long-lived: it stays open with periodic keep-alive comments until the caller disconnects. Capped at 40 concurrent connections per organization.
Server-Sent Events. Every scan (/scan, /rag/*, /agent/*) that carries the same session_id publishes a compact decision summary here the moment it's made (no scanned text, tool arguments, or redacted content ever appears on this stream, only the decision itself). This is what the SDK's subscribe() connects to.
Three event shapes appear as data: frames, distinguished by stage:
-
A decision (
stage:prompt,rag,tool, orresponse):action,risk(0-100),latency(ms), the policy directives that fired, ajob_id, and apiisummary when any was found.actionis the engine's label (lowercase, soreviewappears here).needs_review(boolean) andenforced_action(alloworblock, the action the gateway enforced after applying your app'sreviewCollapsesetting) are added from thereview_flagrelease onward.tool/ragstages also carryphase(call/outputorchunk/context) and, fortool, the tool name. -
{"stage": "audit", "id": "<job_id>"}: sent once that job's decision has been durably persisted, always after that job's decision event. -
{"stage": "_meta", "dropped": <n>}: this connection fell behind and missednevents; never sent silently.
The connection is long-lived: it stays open with periodic keep-alive comments until the caller disconnects. Capped at 40 concurrent connections per organization.
Your API key as a bearer token.
In: header
Path Parameters
The same session_id passed to the scan calls to correlate (1-128 characters; letters, digits, -, and _ only).
Response Body
text/event-stream
application/json
application/json
application/json
curl -X GET "https://example.com/events/string""data: {\"stage\":\"prompt\",\"action\":\"allow\",\"needs_review\":false,\"enforced_action\":\"allow\",\"risk\":4,\"latency\":38,\"policy_directives\":[],\"job_id\":\"job_01hz3q\"}\n\ndata: {\"stage\":\"tool\",\"phase\":\"call\",\"tool\":\"refundCustomer\",\"action\":\"review\",\"needs_review\":true,\"enforced_action\":\"block\",\"risk\":47,\"latency\":41,\"policy_directives\":[],\"job_id\":\"job_01hz3r\"}\n\ndata: {\"stage\":\"audit\",\"id\":\"job_01hz3q\"}\n"{
"error": "Invalid API key",
"code": "INVALID_API_KEY",
"retryAfter": 0
}{
"error": "Invalid API key",
"code": "INVALID_API_KEY",
"retryAfter": 0
}{
"error": "Invalid API key",
"code": "INVALID_API_KEY",
"retryAfter": 0
}