Skip to content
ttorta docs

API Reference

Server-sent events

The board's live stream, its two frame kinds, and the reasons a nudge carries.


GET /api/events opens the board’s update stream.

The response

Status 200, with:

Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

The first thing written is the reconnect hint:

retry: 2000

The connection is held open until the client closes it or the board shuts down.

The default event: a nudge

A nudge says that something changed. The client’s answer is a fresh GET /api/state.

data: {"at":1755600000000,"reason":{"kind":"decision","ticket":"feature.x.REVIEW.md","decision":"approve"}}

reason is whatever caused it, or null. A burst of filesystem events is coalesced into one frame over a 120ms window.

The reasons the server sends by name:

reason.kind Sent when
decision a decision was resolved, with ticket and decision
created the wizard provisioned, with workspace
engine the pause control was used, with paused
pane a pane was opened or delivered into, with agent
torta a file in .torta/ changed, with file

Queue changes arrive with the reason the watcher produced, and the initial listing is filtered out.

The named event: runtime

The header strip has its own frame, coalesced over 150ms:

event: runtime
data: {"state":{},"sessions":[],"killSwitch":false,"engine":null}
Field Meaning
state what the dispatcher last wrote, or null. It outlives the process that wrote it
sessions one entry per held lock: the lock record plus agent
killSwitch whether .torta/DISPATCH_OFF exists
engine the engine record, probed rather than read, or null

A runtime frame is skipped if the config is mid-write. The next tick sends it.

Consuming it

const stream = new EventSource("/api/events");
stream.onmessage = () => refreshFromApiState();
stream.addEventListener("runtime", (event) => drawStrip(JSON.parse(event.data)));

The stream is same-origin, so it has to be opened from a page the board served.

What is watched

Three sources feed the stream: the queues of every agent, the .torta/ directory, and the dispatcher’s state file. .torta/ is watched as a directory, never by file. There is also a periodic sweep every 4 seconds.