---
title: Channels
description: Learn about publishing messages to channels for remote function calling in conversational AI and more.
category: Channels
index: 1
source:
  - pages/api/v1/channel/[channelId]/publish.js
  - pages/api/v1/channel/[channelId]/subscribe.js
---

## Primary Use Case

While this endpoint can be used generically by ChatBotKit customers for
pub/sub messaging, its primary purpose is to support **remote function calling**
in conversational AI workflows.

## How Remote Function Calling Works

1. **Setup**: When calling the `/complete` routes with function definitions,
   you can specify a `channel` name in the result configuration.

2. **Function Invocation**: If the AI model decides to call one of the defined
   functions, it returns a message item containing:
   - The function name
   - The function arguments
   - The channel name that was specified in the `/complete` request

3. **Result Publishing**: The caller then executes the function locally and
   pushes the result back to the model by publishing to this endpoint using
   the channel name provided by the model.

## Publishing a Message

To publish a message to a channel, send a POST request with the `message`
payload as a JSON object:

```http
POST /api/v1/channel/{channelId}/publish
Content-Type: application/json

{
  "message": { "temperature": 72, "conditions": "sunny" }
}
```

## Workflow Example

```javascript
// Step 1: Call /complete with function definitions and channel
POST /v1/conversation/complete
{
  "model": "...",
  "messages": [...],
  "functions": [
    {
      "name": "get_weather",
      "parameters": {...},
      "result": {
        "channel": "my-function-channel-abc123"
      }
    }
  ]
}

// Step 2: Model responds with function call
// Response includes: function="get_weather", args={city: "NYC"}, channel="my-function-channel-abc123"

// Step 3: Execute function locally
const result = await getWeather("NYC")

// Step 4: Publish result back via this endpoint
POST /v1/channel/my-function-channel-abc123/publish
{
  "message": { "temperature": result.temperature, "conditions": result.conditions }
}
```

## Important Notes

- **Channel ID Requirements**: Channel IDs must be at least 16 characters
  long for security and collision avoidance.

- **Channel ID Namespace**: Channel IDs are scoped to your session, so they
  cannot conflict across different ChatBotKit sessions.

- **Message Format**: The `message` field accepts any JSON object. For
  function results, pass the result data directly as a JSON object.

- **Real-time Delivery**: Messages are delivered in real-time to active
  subscribers. If no subscriber is listening at the time of publish, the
  message is not delivered to late-joining subscribers unless those
  subscribers use the `historyLength` option to request history replay.

- **Message History**: In system-managed workflows (such as dispatch-based
  function calling), messages are persisted in a Redis Stream for up to one
  hour. Subscribers can replay these stored messages by passing `historyLength`
  to the subscribe endpoint. This allows subscribers to catch up on messages
  published before the connection was established.

## Subscribing to Channel Messages

Channel subscription enables real-time message streaming, allowing you to
receive messages as they are published to a channel. This creates a
persistent connection that continuously delivers events, making it ideal
for building real-time applications, live dashboards, and responsive
integrations.

To subscribe to a channel, establish a streaming connection using the
subscribe endpoint with the channel ID you wish to monitor:

```http
POST /api/v1/channel/{channelId}/subscribe
Content-Type: application/json

{}
```

The channel ID must be at least 16 characters long to ensure uniqueness
and security. Once connected, the endpoint returns a streaming response
that remains open, continuously sending message events as they occur.

## Replaying Historical Messages with historyLength

When subscribing to a channel, you can request that the server first replay
recent messages that were published before your connection was established.
This is useful in dispatch-style workflows where messages may have been
published during the brief window between initiating a request and
establishing the subscription connection.

To enable history replay, include `historyLength` in the request body with
the maximum number of past messages you want to receive:

```http
POST /api/v1/channel/{channelId}/subscribe
Content-Type: application/json

{ "historyLength": 100 }
```

When `historyLength` is set, the server will:

1. First deliver up to that many recent historical messages in chronological
   order (oldest to newest), each as a `message` event in the stream.
2. Then continue streaming new live messages as they are published.

The `historyLength` value must be an integer between 0 and 10000. History is
stored for up to one hour (3600 seconds) by default, so very old messages
may no longer be available. If fewer historical messages are available than
requested, only the available messages are replayed before live streaming
begins.

## Understanding the Streaming Response

The subscription endpoint uses streaming, returning JSON Lines (JSONL)
format where each line represents a separate event. Each message event
includes:

```json
{"type":"message","data":"your message content here"}
```

The streaming connection remains active until either:

- The client closes the connection
- A network error or timeout occurs
- The server terminates the connection due to inactivity

## Real-Time Communication Pattern

Channels provide a pub-sub pattern where publishers send messages and
subscribers receive them in real-time. This enables:

- **Live updates**: Receive immediate notifications when events occur
- **Remote function calling**: Trigger actions in response to published messages
- **Multi-subscriber support**: Multiple clients can subscribe to the same channel
- **Decoupled communication**: Publishers and subscribers don't need direct connections

The subscription endpoint works seamlessly with the channel publish endpoint,
creating a complete real-time messaging system. When a message is published
to a channel, all active subscribers immediately receive the event through
their streaming connections.

## Implementation Example

Here's how to implement a channel subscriber in JavaScript, including
replaying the last 50 historical messages before receiving live events:

```javascript
const response = await fetch('/api/v1/channel/my-channel-id-12345/subscribe', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_API_TOKEN'
  },
  body: JSON.stringify({ historyLength: 50 })
});

const reader = response.body.getReader();
const decoder = new TextDecoder();

while (true) {
  const { value, done } = await reader.read();
  if (done) break;

  const chunk = decoder.decode(value);
  const lines = chunk.split('\n');

  for (const line of lines) {
    if (line.trim()) {
      const event = JSON.parse(line);
      if (event.type === 'message') {
        console.log('Received:', event.data);
        // Handle the message
      }
    }
  }
}
```

**Important:** Channel IDs should be treated as secure identifiers. Only
share channel IDs with authorized clients that should receive the messages.
Consider using randomly generated channel IDs for sensitive communications.
