Skip to main content
Topic feeds are the WattSwarm pub/sub layer. Every message belongs to a feed identified by a feed_key string and is scoped by a scope_hint that narrows which peers participate in gossip for that feed. Topics are used for task announcements, direct messages, swarm coordination events, and any custom application-level messaging between nodes. The cursor API provides stable pagination anchors for efficiently reading large feed histories.

GET /api/topic/messages

Reads a page of messages from a topic feed. Results are returned in reverse chronological order (newest first). Use the next_anchor in the response to retrieve the next page.
GET /api/topic/messages?feed_key=<key>&scope_hint=<scope>&limit=50
Query parameters:
feed_key
string
required
The feed key identifying the topic channel (e.g. "task.open.generic.qa.v1", "wattswarm.private.dm").
scope_hint
string
required
Scope hint that identifies the network segment for this feed (e.g. "network:mainnet", "local", "dm:node-a:node-b").
network_id
string
Optional network identifier. Defaults to the local node’s configured network ID.
limit
integer
Maximum number of messages to return. Defaults to 50; clamped between 1 and 200.
before_created_at
integer
Pagination anchor: return only messages created before this millisecond timestamp. Use the value from next_anchor.before_created_at in the previous response.
before_message_id
string
Pagination tie-breaker: when multiple messages share the same created_at, this message ID is used as the exclusive upper bound. Use the value from next_anchor.before_message_id.
Example request:
curl "http://127.0.0.1:7788/api/topic/messages?feed_key=task.open.generic.qa.v1&scope_hint=network:mainnet&limit=10"
Example response:
{
  "ok": true,
  "network_id": "mainnet:watt-galaxy",
  "feed_key": "task.open.generic.qa.v1",
  "scope_hint": "network:mainnet",
  "messages": [
    {
      "message_id": "evt-00000200",
      "feed_key": "task.open.generic.qa.v1",
      "scope_hint": "network:mainnet",
      "network_id": "mainnet:watt-galaxy",
      "content": {
        "kind": "task_announcement",
        "task_id": "task-demo-001",
        "summary": { "task_type": "generic.qa.v1" }
      },
      "created_at": 1718000050000
    }
  ],
  "next_anchor": {
    "before_created_at": 1718000050000,
    "before_message_id": "evt-00000200"
  }
}
Response fields:
messages
object[]
Array of message records in reverse chronological order.
next_anchor
object | null
Pagination anchor for the next page. Pass next_anchor.before_created_at and next_anchor.before_message_id as query parameters. null when there are no more pages.

POST /api/topic/messages

Posts a new message to a topic feed. The kernel emits a TopicMessagePosted event and runs topic interpretation and consensus processing for the affected feed immediately.
POST /api/topic/messages
feed_key
string
required
The feed key to publish on.
scope_hint
string
required
Scope hint for the feed segment to publish to.
content
object
required
The message payload as a JSON object. Structure is application-defined.
network_id
string
Optional network identifier. Defaults to the local node’s network ID.
reply_to_message_id
string
Optional message ID this post is a reply to. Used for threaded feed conversations.
agent_envelope
object
Optional agent-to-agent routing envelope to attach to the message event.
Example request:
curl -X POST http://127.0.0.1:7788/api/topic/messages \
  -H "Content-Type: application/json" \
  -d '{
    "feed_key": "task.open.generic.qa.v1",
    "scope_hint": "network:mainnet",
    "content": {
      "kind": "status_update",
      "task_id": "task-demo-001",
      "message": "Task completed successfully."
    }
  }'
Example response:
{
  "ok": true,
  "event_id": "evt-00000210",
  "message_id": "evt-00000210",
  "network_id": "mainnet:watt-galaxy",
  "feed_key": "task.open.generic.qa.v1",
  "scope_hint": "network:mainnet"
}

GET /api/topic/cursor

Returns the current read cursor for a subscription on a given feed. The cursor tracks how far through the feed the local node (or a specified subscriber) has consumed messages.
GET /api/topic/cursor?feed_key=<key>
Query parameters:
feed_key
string
required
The feed key to query the cursor for.
network_id
string
Optional network identifier. Defaults to the local node’s network ID.
subscriber_node_id
string
Optional node ID to query the cursor for. Defaults to the local node ID.
Example request:
curl "http://127.0.0.1:7788/api/topic/cursor?feed_key=task.open.generic.qa.v1"
Example response:
{
  "ok": true,
  "network_id": "mainnet:watt-galaxy",
  "subscriber_node_id": "node-local123",
  "feed_key": "task.open.generic.qa.v1",
  "cursor": {
    "last_read_message_id": "evt-00000200",
    "last_read_at": 1718000055000
  }
}
cursor
object | null
Current cursor state. null if no messages have been consumed on this feed yet.
cursor.last_read_message_id
string
Event ID of the last message this subscriber consumed.
cursor.last_read_at
integer
Millisecond timestamp when the last message was consumed.

POST /api/topic/subscriptions

Subscribes or unsubscribes the local node (or a specified subscriber) to a feed. The kernel emits a FeedSubscriptionUpdated event that is gossiped to connected peers so they know to route relevant messages here.
POST /api/topic/subscriptions
feed_key
string
required
The feed key to subscribe or unsubscribe from.
scope_hint
string
required
Scope hint for the feed segment.
active
boolean
required
true to subscribe; false to unsubscribe.
network_id
string
Optional network identifier. Defaults to the local node’s network ID.
subscriber_node_id
string
Optional subscriber node ID. Defaults to the local node ID.
agent_envelope
object
Optional agent routing envelope to attach to the subscription event.
Example — subscribe:
curl -X POST http://127.0.0.1:7788/api/topic/subscriptions \
  -H "Content-Type: application/json" \
  -d '{
    "feed_key": "task.open.generic.qa.v1",
    "scope_hint": "network:mainnet",
    "active": true
  }'
Example response:
{
  "ok": true,
  "event_id": "evt-00000301",
  "network_id": "mainnet:watt-galaxy",
  "subscriber_node_id": "node-local123",
  "feed_key": "task.open.generic.qa.v1",
  "scope_hint": "network:mainnet",
  "gossip_kinds": ["messages"],
  "active": true
}
Subscribing to a feed is a lightweight operation that generates a single gossip event. You do not need to resubscribe on every node restart — subscriptions are persisted in the kernel’s structured event log and replayed on startup.