Bots & AI Hooks

A bot is an app-scoped identity whose "client" is your own backend, typically an AI service. Instead of running the SDK over a WebSocket, a bot receives messages through the ai.message_received hook and replies through a REST endpoint. This is the turn-taking loop for building an AI assistant into a conversation.

The loop

  1. You register a bot with POST /api/bots - it becomes an addressable user id.
  2. A user sends a message to the bot. The platform fires ai.message_received to your webhook (and records it in the event log).
  3. Your backend runs its model and replies with POST /api/bots/{botId}/send-message. The reply is relayed to the user as a normal message from the bot.

Bot modes

  • CLEARTEXT, the hook carries the message text; the bot replies with text. Simplest to integrate.
  • E2EE, the bot is a real encrypted participant. Publish the bot's public key in your key directory like any user; the hook carries ciphertext devicePayloads. Your backend (holding the bot's private key) decrypts, runs the model, encrypts the reply, and posts the device payloads. The relay never sees plaintext.

REST API

HMAC-authenticated, the same scheme as token exchange.

POST   /api/bots                       // register: {botId, displayName, mode, capabilities}
GET    /api/bots                       // list bots
GET    /api/bots/{botId}               // get one
DELETE /api/bots/{botId}               // delete
POST   /api/bots/{botId}/send-message  // the bot replies

// send-message body, CLEARTEXT bot
{ "toUserId": "alice", "text": "Here is your summary..." }

// send-message body, E2EE bot (pre-encrypted by your backend)
{ "toUserId": "alice", "devicePayloads": [ { "deviceId", "encryptedPayload", "senderPublicKey" } ] }

The ai.message_received hook

{
  "event": "ai.message_received",
  "data": {
    "botId": "assistant", "fromUserId": "alice", "messageId": "...",
    "encryptionType": "CLEARTEXT", "text": "what's on my calendar?"
    // E2EE bots receive "devicePayloads" instead of "text"
  }
}

v1 fires the hook for 1-to-1 messages addressed to a bot. Verify support via GET /api/info, the features array includes "bot_identity".

AI lifecycle events

The platform runs no model and has no media plane, so it cannot transcribe or summarize. When your own AI pipeline produces something, e.g. a transcript of a recording in your storage, it posts an event back and the platform fans it out through webhooks and the event log, so the rest of your systems are notified uniformly.

POST /v1/ai/events          // HMAC-authenticated
{
  "type": "ai.call_transcription_ready",   // must be in the ai.* namespace
  "data": { "callId": "...", "transcriptUrl": "s3://my-bucket/..." }
}

The data shape is yours, the platform just relays it. Common types: ai.call_transcription_ready, ai.meeting_summary_available.