Skip to main content

Payloads

In progress — not available yet

Real-time streaming is not enabled on accounts yet. See the overview for what to do instead.

What lands on each node: incremental chunks, the run status a composer keys off, and the finalized message.

Field naming differs by tree

Two writers feed these nodes, and they do not agree on casing.

  • streaming/… is assembled by hand and is snake_case (run_id, started_at).
  • conversations/… is the protojson encoding of the underlying event, so it is camelCase (runId, eventContext) — the same convention as API responses.

Do not carry a key from one example to the other.

Streaming Chunks

Listen on streaming/{conversationId}/{messageSequence}. Each write replaces the whole node, so you receive the accumulated chunks array plus a meta object every time.

{
"meta": {
"run_id": "64403669-5989-4ec3-ad9c-d84223f9679f",
"status": "streaming", // "streaming" | "complete" | "error"
"started_at": "2026-04-23T22:43:44.700Z"
},
"chunks": [
{ "content": "I can ", "type": "STREAM_CHUNK_TYPE_TEXT", "timestamp": "2026-04-23T22:43:44.712Z" },
{ "content": "help ", "type": "STREAM_CHUNK_TYPE_TEXT", "timestamp": "2026-04-23T22:43:44.809Z" },
{ "content": "with…", "type": "STREAM_CHUNK_TYPE_TEXT", "timestamp": "2026-04-23T22:43:44.907Z" }
]
}

Chunk fields

FieldMeaning
contentThe token text (or reasoning/tool-call fragment) for this chunk
typeSTREAM_CHUNK_TYPE_TEXT, STREAM_CHUNK_TYPE_REASONING, or STREAM_CHUNK_TYPE_TOOL_CALL
timestampServer time the chunk was written
tool_callPresent only on tool-call chunks — see below

A chunk carries no terminal marker of its own: completion lives on meta, never on the chunk. A STREAM_CHUNK_TYPE_TOOL_CALL chunk adds a tool_call object with the fragment of the call assembled so far:

{
"content": "",
"type": "STREAM_CHUNK_TYPE_TOOL_CALL",
"timestamp": "2026-04-23T22:43:45.104Z",
"tool_call": {
"index": 0,
"id": "call_abc123",
"name": "get_weather",
"arguments_delta": "{\"ci"
}
}

arguments_delta is a fragment, not valid JSON on its own — concatenate the deltas for a given index across chunks before parsing.

The chunks array is indexed by position and may contain gaps (nulls) mid-stream as writes arrive out of order — always render by accumulating non-null entries in order, don't assume the array is dense.

Filter chunk types for display: render STREAM_CHUNK_TYPE_TEXT into the message bubble; treat STREAM_CHUNK_TYPE_REASONING and STREAM_CHUNK_TYPE_TOOL_CALL separately (or hide them). When reasoning is enabled, reasoning chunks arrive first, then text chunks.

The meta node

meta is written twice. On the first chunk it carries run_id, status: "streaming" and started_at. When the stream ends it is updated in place:

{
"run_id": "64403669-5989-4ec3-ad9c-d84223f9679f",
"status": "complete", // "error" when finish_reason is "error"
"started_at": "2026-04-23T22:43:44.700Z",
"finished_at": "2026-04-23T22:43:46.219Z",
"finish_reason": "stop", // "stop" | "tool_calls" | "length" | "error"
"usage": {
"prompt_tokens": 812,
"completion_tokens": 47,
"total_tokens": 859
}
}

error_message is added only when finish_reason is "error", and usage only when the provider reported it. Keys that do not apply are absent, not null — read them with a default.

Detecting completion

A stream is done when any of these is true — check meta.status first, it is authoritative:

  1. meta.status == "complete" (or "error"), or
  2. meta.finish_reason is present, or
  3. conversations/{conversationId}/status returns to a non-generating state.

The finalized message landing under conversations/{conversationId}/messages also back-fills meta.status to "complete", so a client that missed the final chunk still converges.

Conversation Status

Listen on conversations/{conversationId}/status for a single last-write-wins node that tracks what the conversation is doing. Use it to drive a busy indicator and to de-duplicate out-of-order writes via seq.

This node is the whole ConversationStatusChangedEvent, protojson-encoded — hence camelCase, and hence the eventContext envelope alongside the fields you care about.

{
"eventContext": { "correlationId": "…", "eventId": "…", "callerKey": "conv_abc" },
"state": "CONVERSATION_ACTIVITY_STATE_GENERATING",
"runId": "64403669-5989-4ec3-ad9c-d84223f9679f",
"seq": "7", // int64 as string
"since": "2026-04-23T22:43:44.712Z"
}
state valueMeaning
CONVERSATION_ACTIVITY_STATE_IDLENothing running — safe to send the next message
CONVERSATION_ACTIVITY_STATE_QUEUEDGeneration accepted, not started yet
CONVERSATION_ACTIVITY_STATE_GENERATINGModel is producing tokens
CONVERSATION_ACTIVITY_STATE_EXECUTING_TOOLSRunning tool calls
CONVERSATION_ACTIVITY_STATE_COMPACTINGCompacting context
CONVERSATION_ACTIVITY_STATE_ERRORLast run failed — see error

error appears only in the ERROR state, as { "code": "…", "message": "…" }.

Finalized Messages

Once a turn settles the full message is written under conversations/{conversationId}/messages, keyed by the message's sequence so a re-delivery overwrites rather than duplicates. This node is protojson-encoded — camelCase:

{
"eventContext": { "correlationId": "…", "eventId": "…", "emittedAt": "…" },
"message": {
"role": "ROLE_ASSISTANT",
"content": [ { "type": "CONTENT_PART_TYPE_TEXT", "content": "I can assist you with…" } ],
"generatedBy": "64403669-5989-4ec3-ad9c-d84223f9679f",
"sequence": "8",
"model": "anthropic/claude-sonnet-4",
"toolCalls": [
{ "id": "call_abc123", "name": "get_weather", "status": "TOOL_EXECUTION_STATUS_SUCCESS",
"argumentsJson": "{\"city\":\"NYC\"}" }
]
}
}

Sibling nodes under the same conversation follow the same encoding:

NodeWritten onContains
conversations/{id}/messagesEvery message appended or upsertedThe full message, keyed by sequence
conversations/{id}/runs/{runId}Generation start and finishrunId, status, loopCount, durationMs, usage, error
conversations/{id}/activityTool call start and finishtoolCall, executionTimeMs
conversations/{id}/statusEvery lifecycle transitionSee above
conversations/{id}/queuePending user queue changespending, the whole queue in order
conversations/{id}/compactionContext compaction lifecycleCompaction progress and outcome