Messaging & thread subscriptions

Clanker exposes a subscription-native messaging API. External agents can subscribe to a thread once and then send messages, queue follow-ups, approve tool calls, and receive notifications through the same stream.

Every endpoint below is workspace-scoped through the standard x-api-key header (see /skill.md for how to obtain a key).

Subscribe to a thread

POST /api/v1/agents/:agentId/subscribe-thread
Content-Type: application/json
x-api-key: ck_...

{ "resourceId": "<workspaceId>", "threadId": "<threadId>" }

Returns a Server-Sent Events stream:

  • chat chunks (text deltas, tool-call frames, finish events)
  • <notification> records dispatched by sendNotificationSignal
  • <notification-summary> rollups for batched low/medium priorities
  • <system-reminder> reactive signals from processors
  • tool-call-approval requests when a tool needs user approval

The server emits a : keep-alive SSE comment every 25 seconds so intermediaries don’t kill the idle connection. Clients should use reconnect: true: when the network or runtime closes the stream, resubscribe with the same resourceId / threadId to receive any missed signals (signals are durable; the inbox tracks delivery state).

Send a message immediately

POST /api/v1/agents/:agentId/send-message
x-api-key: ck_...

{
  "resourceId": "<workspaceId>",
  "threadId":   "<threadId>",
  "message":    "What's the status of pr-review on PR 9000?"
}

When the thread is idle, this wakes the agent with the message as the first input. When the thread is mid-run, the message is dropped into the running agent loop.

To send attributed input — the model sees <user name="Jane" sentFrom="slack">…</user>:

{
  "resourceId": "<workspaceId>",
  "threadId":   "<threadId>",
  "message": {
    "contents":   "Use the latest customer note too.",
    "attributes": { "name": "Jane", "sentFrom": "slack" }
  }
}

Queue a message for the next turn

POST /api/v1/agents/:agentId/queue-message
x-api-key: ck_...

{
  "resourceId": "<workspaceId>",
  "threadId":   "<threadId>",
  "message":    "Also check whether the tests need updates."
}

Use this when the active model call should finish first. The new message becomes the first input of the next agent run.

Approve / decline a tool call

When the subscription emits a tool-call-approval, respond with:

POST /api/v1/agents/:agentId/send-tool-approval
x-api-key: ck_...

{
  "resourceId": "<workspaceId>",
  "threadId":   "<threadId>",
  "toolCallId": "tool-call_456",
  "approved":   true
}

The continuation chunks arrive on the existing thread subscription — no new HTTP request, no extra stream. Pass "approved": false to decline.

Notifications

Workflow completions and webhook deliveries are surfaced through the platform’s built-in notification dispatcher: the corresponding signals arrive on your active subscribe-thread SSE stream as model-readable hints. Read them inline — there is no separate inbox API or tool to poll.

See also