Molecule AI
API Reference

Real-time & Observability API

Canvas, traces, audit ledger, events, terminal, WebSocket, and Server-Sent Events endpoints.

Canvas

Canvas viewport persistence (cosmetic only).

MethodPathAuthDescription
GET/canvas/viewportNoneGet the saved canvas viewport (zoom, pan position). Open endpoint for bootstrap-friendliness.
PUT/canvas/viewportCanvasOrBearerSave the canvas viewport. Accepts bearer OR matching Origin header. Worst case on forgery: viewport corruption, recovered by page refresh.

Traces

LLM trace retrieval from Langfuse.

MethodPathAuthDescription
GET/workspaces/:id/tracesWorkspaceAuthList LLM traces for a workspace from Langfuse.

Audit Ledger

HMAC-SHA256-chained immutable agent event log for compliance record-keeping (EU AI Act Art. 12 / Art. 13). Each event is cryptographically chained to the previous one — tampering with any record breaks all subsequent HMACs.

AUDIT_LEDGER_SALT required. The platform and workspace containers must share the same AUDIT_LEDGER_SALT environment variable to compute and verify event HMACs. Set it in both your platform env and workspace container env. If the variable is absent, chain_valid returns null (not false) — no records are lost, verification is simply unavailable.

Query

MethodPathAuthDescription
GET/workspaces/:id/auditWorkspaceAuthQuery the audit ledger for a workspace. Returns events in descending chronological order with inline chain verification.

Query parameters:

ParameterTypeDescription
agent_idstringFilter to a specific agent.
session_idstringFilter to a specific session.
fromRFC 3339Start of time range (e.g. 2026-04-01T00:00:00Z).
toRFC 3339End of time range.
limitintMax records to return. Capped at 500.
offsetintPagination offset.

Response shape:

{
  "events": [
    {
      "id": "uuid",
      "workspace_id": "uuid",
      "agent_id": "my-researcher",
      "session_id": "sess_abc123",
      "event_type": "tool_call",
      "payload": { "tool": "bash", "input": "ls /workspace" },
      "hmac": "sha256hex...",
      "prev_hmac": "sha256hex...",
      "created_at": "2026-04-17T12:00:00Z"
    }
  ],
  "chain_valid": true
}

chain_valid values:

  • true — all HMACs verified; ledger is intact.
  • false — at least one HMAC mismatch; possible tampering.
  • nullAUDIT_LEDGER_SALT is absent from the platform env; verification skipped.

Workspace-side: recording events

In your workspace template, wire LedgerHooks into the agent pipeline:

from molecule_audit.hooks import LedgerHooks

hooks = LedgerHooks(agent_id="my-researcher", session_id=session_id)

async with hooks:
    # hooks.on_task_start / on_llm_call / on_tool_call / on_task_end
    # fire automatically at each pipeline stage
    result = await agent.run(task)

LedgerHooks is exception-safe — a failed ledger write never aborts the agent task.

CLI chain verification

# Verify the full chain for an agent; exit 0 = intact
python -m molecule_audit.verify --agent-id my-researcher

# Custom DB URL
python -m molecule_audit.verify --agent-id my-researcher --db postgresql://user:pass@host/db

Exit codes: 0 = chain valid · 1 = broken chain · 2 = AUDIT_LEDGER_SALT missing · 3 = DB error.


Events

Append-only event log for structure changes.

MethodPathAuthDescription
GET/eventsAdminAuthList all structure events across all workspaces.
GET/events/:workspaceIdAdminAuthList structure events for a specific workspace.

Terminal

WebSocket-based terminal access to workspace containers.

MethodPathAuthDescription
WS/workspaces/:id/terminalWorkspaceAuthOpen a WebSocket terminal session to the workspace container. Provides interactive shell access.

WebSocket

Real-time event streaming for Canvas clients.

MethodPathAuthDescription
WS/wsNoneConnect to the WebSocket hub. Receives all structure events (WORKSPACE_ONLINE, WORKSPACE_OFFLINE, HEARTBEAT, CONFIG_UPDATED, A2A_RESPONSE, AGENT_MESSAGE, etc.). Canvas clients connect here for real-time updates.

Server-Sent Events (AG-UI)

Per-workspace SSE stream compatible with the AG-UI protocol. Use this endpoint to consume structured agent events from a web client or external tool without a WebSocket library.

MethodPathAuthDescription
GET/workspaces/:id/events/streamWorkspaceAuthOpen an SSE stream for the workspace. Returns Content-Type: text/event-stream. Sends an initial : ping comment on connect, then delivers every event emitted by the workspace in AG-UI envelope format. Events from other workspaces are filtered out. Returns 404 if the workspace does not exist.

Event envelope format

Each event is delivered as an SSE data: line containing a JSON object:

{
  "type": "AGENT_MESSAGE",
  "timestamp": 1713398400000,
  "data": { ... }
}
  • type — event type string (e.g. AGENT_MESSAGE, A2A_RESPONSE, TASK_UPDATED)
  • timestamp — Unix milliseconds at time of broadcast
  • data — event-specific payload (same payload as the WebSocket hub delivers)

Event types streamed

All event types emitted by RecordAndBroadcast and BroadcastOnly reach the SSE stream. The BroadcastOnly path is important: events like AGENT_MESSAGE, A2A_RESPONSE, and TASK_UPDATED skip Redis and would be invisible to a Redis-only subscriber — the in-process SSE layer catches them.

Example: connect with curl

curl -N \
  -H "Authorization: Bearer <workspace-token>" \
  http://localhost:8080/workspaces/<id>/events/stream
: ping

data: {"type":"AGENT_MESSAGE","timestamp":1713398401234,"data":{"text":"Starting task..."}}

data: {"type":"TASK_UPDATED","timestamp":1713398405678,"data":{"status":"running"}}

Example: connect from JavaScript

const es = new EventSource(
  `/workspaces/${workspaceId}/events/stream`,
  { headers: { Authorization: `Bearer ${token}` } }
);

es.onmessage = (e) => {
  const event = JSON.parse(e.data);
  console.log(event.type, event.data);
};

The SSE endpoint uses WorkspaceAuth — the bearer token must be bound to the :id in the path. A token for workspace A cannot open a stream for workspace B.


On this page