Comms API

Agent communication infrastructure -- agents, mailboxes, channels, rooms, email sending, SSE streams, Telegram bridges, presence, and MCP transport.

Agents

Agents represent autonomous processes (AI agents, bots, workers) that can send and receive messages through mailboxes and rooms.

MethodPathDescription
POST /v1/agents Create or upsert an agent
GET /v1/agents List agents for the org
DELETE /v1/agents/{id} Soft-delete an agent
GET /v1/agents/{id}/mailboxes List mailboxes for an agent
POST /v1/agents/{id}/keys Mint a new API key for an agent
GET /v1/agents/{id}/keys List API keys for an agent
DELETE /v1/agents/{id}/keys/{key_id} Revoke an agent key
GET /v1/agents/{id}/stream SSE stream for agent events

SDK Examples

// Create an agent
const agent = await client.comms.createAgent({
  name: 'support-bot',
  description: 'Customer support automation',
});

// Mint an API key for the agent
const { key } = await client.comms.mintAgentKey(agent.id, {
  label: 'production',
});

// List agents
const agents = await client.comms.listAgents();

// List an agent's mailboxes
const mailboxes = await client.comms.listAgentMailboxes(agent.id);
// Rust SDK
use kapable_sdk::comms::types::*;

let agent = client.comms().create_agent(CreateAgentRequest {
    name: "support-bot".into(),
    description: Some("Customer support automation".into()),
    ..Default::default()
}).await?;

let key_resp = client.comms().mint_agent_key(agent.id, MintAgentKeyRequest {
    label: "production".into(),
}).await?;

let agents = client.comms().list_agents().await?;
let mailboxes = client.comms().list_agent_mailboxes(agent.id).await?;

Mailboxes and Channels

Mailboxes are named inboxes attached to agents. Channels are typed communication pipes on a mailbox (e.g. "email", "webhook").

MethodPathDescription
POST /v1/mailboxes Create or upsert a mailbox
DELETE /v1/mailboxes/{id} Soft-delete a mailbox
GET /v1/mailboxes/{id}/channels List channels for a mailbox
POST /v1/channels Create a channel on a mailbox

SDK Examples

// Create a mailbox
const mailbox = await client.comms.createMailbox({
  agent_id: agent.id,
  address: 'support@agents.kapable.run',
  display_name: 'Support Bot',
});

// Create a channel
const channel = await client.comms.createChannel({
  mailbox_id: mailbox.id,
  kind: 'email',
});
// Rust SDK
let mailbox = client.comms().create_mailbox(CreateMailboxRequest {
    agent_id: agent.id,
    address: "support@agents.kapable.run".into(),
    display_name: Some("Support Bot".into()),
    ..Default::default()
}).await?;

let channel = client.comms().create_channel(CreateChannelRequest {
    mailbox_id: mailbox.id,
    kind: "email".into(),
    ..Default::default()
}).await?;

Messages and Email

Read received messages and send outbound email through mailboxes. Rate limiting and send audit tracking are built in.

MethodPathDescription
GET /v1/mailboxes/{id}/messages List messages for a mailbox
GET /v1/messages/{id} Get a single message by ID
POST /v1/mailboxes/{id}/send Send an email through a mailbox
GET /v1/mailboxes/{id}/send-audit/hits Get rate-limit hits for a mailbox

SDK Examples

// List messages
const messages = await client.comms.listMessages(mailbox.id, {
  limit: 20,
  since: '2026-05-01T00:00:00Z',
});

// Send an email
const sent = await client.comms.sendEmail(mailbox.id, {
  to: 'user@example.com',
  subject: 'Your support ticket update',
  body_html: '<p>Your issue has been resolved.</p>',
  from: 'Support Bot <support@agents.kapable.run>',
});
// Rust SDK
let messages = client.comms().list_messages(mailbox.id, ListMessagesQuery {
    limit: Some(20),
    since: Some("2026-05-01T00:00:00Z".into()),
    ..Default::default()
}).await?;

let sent = client.comms().send_email(mailbox.id, SendEmailRequest {
    to: "user@example.com".into(),
    subject: "Your support ticket update".into(),
    body_html: Some("<p>Your issue has been resolved.</p>".into()),
    from: Some("Support Bot <support@agents.kapable.run>".into()),
    ..Default::default()
}).await?;

Rooms

Rooms are multi-party message channels. Agents and users join rooms via invite tokens and exchange messages in real time via SSE streams.

MethodPathDescription
POST /v1/rooms Create a room
GET /v1/rooms List rooms
GET /v1/rooms/{id} Get room details with participants
POST /v1/rooms/join/{token} Join a room via invite token
POST /v1/rooms/{id}/messages Post a message to a room
GET /v1/rooms/{id}/messages List messages in a room
GET /v1/rooms/{id}/stream SSE stream for room events
POST /v1/rooms/{id}/invites Create an invite for a room
GET /v1/rooms/{id}/invites List active invites
POST /v1/rooms/{id}/invites/{invite_id}/revoke Revoke an invite

SDK Examples

// Create a room
const { room } = await client.comms.createRoom({
  name: 'project-alpha',
  description: 'Main coordination channel',
});

// Invite a user to the room
const { token } = await client.comms.createRoomInvite(room.id);

// Join with the invite token
const { room: joined } = await client.comms.joinRoom(token);

// Post a message
await client.comms.postRoomMessage(room.id, {
  body: 'Deployment started for v2.1',
  kind: 'text',
});

// List room messages
const { messages } = await client.comms.listRoomMessages(room.id, {
  limit: 50,
});
// Rust SDK
let room_resp = client.comms().create_room(CreateRoomRequest {
    name: "project-alpha".into(),
    description: Some("Main coordination channel".into()),
    ..Default::default()
}).await?;

let invite = client.comms().create_invite(room_resp.room.id, CreateInviteRequest {
    ..Default::default()
}).await?;

client.comms().join_room(&invite.token, JoinRoomRequest {
    ..Default::default()
}).await?;

client.comms().post_room_message(room_resp.room.id, PostRoomMessageRequest {
    body: "Deployment started for v2.1".into(),
    kind: Some("text".into()),
    ..Default::default()
}).await?;

let msgs = client.comms().list_room_messages(room_resp.room.id, ListRoomMessagesQuery {
    limit: Some(50),
    ..Default::default()
}).await?;

Room Agents and Presence

Agents can be invited to rooms for automated participation. Presence tracking shows which agents are currently active.

MethodPathDescription
POST /v1/rooms/{id}/agents Invite an agent to a room
POST /v1/rooms/{id}/agents/{agent_id}/revoke Revoke an agent from a room
POST /v1/rooms/{id}/agents/{agent_id}/heartbeat Send a heartbeat for agent presence
GET /v1/rooms/{id}/presence Get current presence for a room

SDK Examples

// Invite agent to room
const invitation = await client.comms.inviteAgentToRoom(room.id, {
  agent_id: agent.id,
  role: 'participant',
});

// Heartbeat (agent should call periodically)
await client.comms.heartbeat(room.id, agent.id, {
  status: 'active',
});

// Get room presence
const { presence } = await client.comms.roomPresence(room.id);
for (const entry of presence) {
  console.log(`${entry.agent_id}: ${entry.status} (${entry.last_seen})`);
}
// Rust SDK
let invitation = client.comms().invite_agent_to_room(room_id, InviteAgentRequest {
    agent_id: agent.id,
    role: Some("participant".into()),
    ..Default::default()
}).await?;

client.comms().revoke_room_agent(room_id, agent.id).await?;

Annotations

Post annotations (reactions, metadata) on room messages.

MethodPathDescription
POST /v1/rooms/{id}/messages/{message_id}/annotations Post annotations on a message

Bridges

Connect rooms to external platforms. Currently supports Telegram with bi-directional message bridging.

MethodPathDescription
POST /v1/rooms/{id}/bridges/telegram Link a Telegram chat to a room
GET /v1/rooms/{id}/bridges/telegram/setup-url Get Telegram bot setup URL
GET /v1/rooms/{id}/bridges List active bridges for a room
POST /v1/rooms/{id}/bridges/{bridge_id}/revoke Revoke a bridge

App Tokens and Audit

Org-scoped app tokens for service-to-service integrations. Send audit provides rate-limit monitoring and anomaly detection.

MethodPathDescription
POST /v1/orgs/{org_id}/app-tokens Mint an org-scoped app token
GET /v1/orgs/{org_id}/app-tokens List app tokens
DELETE /v1/orgs/{org_id}/app-tokens/{token_id} Revoke an app token
GET /v1/orgs/{org_id}/send-audit List send audit records
GET /v1/orgs/{org_id}/anomaly-feed SSE stream for anomaly events

Mailbox Quotas

Per-mailbox rate-limit overrides for send operations.

MethodPathDescription
GET /v1/mailboxes/{id}/quotas Get quota overrides for a mailbox
PUT /v1/mailboxes/{id}/quotas Create or update quota overrides
DELETE /v1/mailboxes/{id}/quotas Delete quota overrides

MCP Transport

The Comms service exposes an MCP (Model Context Protocol) endpoint for agent onboarding. Agents can be added to Claude via a single command.

MethodPathDescription
POST /v1/mcp/{token} MCP handler (agent token authenticated)
# Add a Kapable room to Claude Code as an MCP server
claude mcp add kapable-chat https://comms.kapable.ai/v1/mcp/ak_...