Events (kletso.events/v1)

The envelope every server message uses, the complete list of event types with their payload fields, and the app.notify payload.

Envelope

{ "id": "evt_01J8EVENT00042", "seq": 42, "type": "message.delta",
  "ts": "2026-09-28T12:00:00.123Z", "conversationId": "conv_01J8DEMO000001",
  "turnId": "trn_01J8TURN000007",
  "data": { "messageId": "msg_01J8MSG0000013", "text": "Hel" } }
FieldNotes
idevt_…, unique; dedupe key
seqinteger ≥ 1, contiguous per conversation; replay cursor
typedotted lowercase name
tsISO-8601 UTC
conversationIdconv_…
turnIdtrn_…, groups the events of one assistant turn (optional)
datatype-specific payload

Event types

TypePayloadEmitted when
conversation.createdconversation {id, agentId, title, status, createdAt, updatedAt, lastSeq}A conversation starts
conversation.updatedsameTitle, status (open, handoff, closed) changes
message.createdmessageId, role user·assistant·system·tool, text?, value?, clientId?A message starts (user echo or assistant)
message.deltamessageId, text (append)Streaming text
message.completedmessageId, text, usage {in, out, cachedIn, reasoning}, costMicros, latencyMs, finishReason stop·length·tool_calls·error·cancelledThe turn’s message is final
agent.typing{}The turn started; clients show dots with their own TTL
tool.startedtoolCallId, name, argsA tool call begins
tool.completedtoolCallId, name, durationMs, result?Success
tool.failedtoolCallId, name, durationMs, error {code, message}Failure (including invalid_args)
tool.confirmation_requiredtoolCallId, name, args, surfaceThe turn paused for approval; the surface holds the confirm block
ui.pendingtoolCallId, surfaceId?, components [{id, type}]A render_ui call is streaming: what it will contain so far, repeated as more components appear (show loaders)
ui.rendersurface, toolCallId?A surface to display; replaces the ui.pending with the same toolCallId
ui.patchsurfaceId, data?, components?Change to an existing surface (applied by the SDK; not emitted by the runtime yet)
ui.actionsurfaceId, componentId, actionId, value?Echo of a user interaction to all clients
app.commandname, args, closeChatThe agent asks the app to run a local action
app.notifysee belowA notification for the user
trigger.firedtriggerId, kind manual·event·screen·time, nameA rule matched
handoff.startedtarget, agentName?The assistant handed off
handoff.completedsameReserved
workflow.started / .completed / .failedrunId, output?, error?Reserved for live workflow dispatch
errorcode, message, retryableA turn-level error

Events marked reserved are in the schema and handled by the SDK but not produced by the current runtime.

User-level events (conversation.created, conversation.updated, trigger.fired, app.notify, app.command) are also delivered to sockets that are attached to the user but not to a specific conversation, so a launcher-only connection still receives notifications.

app.notify payload

{ "notificationId": "ntf_01J8NTF00001",
  "title": "Order ORD-2201 shipped",
  "body": "Arrives tomorrow. Track it live or ask me anything.",
  "channel": "system",
  "openChat": true,
  "ttlSeconds": 30,
  "action": { "id": "tap", "kind": "local", "name": "open_orders", "args": {}, "label": "View" },
  "surface": { "schema": "kletso.ui/v1", "surfaceId": "sfc_…", "root": "…", "components": {}, "fallbackText": "…" },
  "imageUrl": "https://cdn.acme.com/ship.png",
  "data": { "orderId": "ORD-2201" } }
FieldNotes
notificationIdrequired; clients dedupe on it
titlerequired, 1–120 chars
body≤ 1000 chars
channelbanner (default), toast, alert, system, silent
openChatopen the chat on tap; immediately for silent
actiona local, url or agent action run on tap
surfaceinline surface shown in banners and alerts
ttlSeconds1–86400; auto-dismiss for banner and toast
imageUrl, dataoptional decoration and opaque host data

Last updated 2026-09-28 · Report an issue with this page