Skip to content

WebSocket API

Real-time communication for live updates and agent interaction.

Connection

URL

wss://your-domain.com/agent/{agentId}

JavaScript Example

javascript
const ws = new WebSocket('wss://your-domain.com/agent/my-agent')

ws.onopen = () => {
  console.log('Connected')
}

ws.onmessage = (event) => {
  const message = JSON.parse(event.data)
  handleMessage(message)
}

ws.onclose = () => {
  console.log('Disconnected')
}

ws.onerror = (error) => {
  console.error('WebSocket error:', error)
}

Message Format

Incoming Messages

json
{
  "type": "state:update",
  "data": {
    "connectedClients": 5,
    "pendingSchedules": []
  },
  "timestamp": 1702648800000
}

Outgoing Messages

json
{
  "type": "action",
  "action": "subscribe",
  "data": {
    "events": ["workflow:status", "message:received"]
  }
}

Message Types

State Updates

json
{
  "type": "state:update",
  "data": {
    "config": {
      "name": "my-agent",
      "model": "@cf/meta/llama-3.1-8b-instruct"
    },
    "connectedClients": 3,
    "mcpServers": [],
    "pendingSchedules": []
  }
}

Client Connected

json
{
  "type": "client:connected",
  "data": {
    "count": 5,
    "clientId": "client-123"
  }
}

Client Disconnected

json
{
  "type": "client:disconnected",
  "data": {
    "count": 4,
    "clientId": "client-123"
  }
}

Workflow Status

json
{
  "type": "workflow:status",
  "data": {
    "workflowId": "workflow-123",
    "executionId": "exec-456",
    "status": "running",
    "currentNode": "email-1"
  }
}

Workflow Complete

json
{
  "type": "workflow:complete",
  "data": {
    "workflowId": "workflow-123",
    "executionId": "exec-456",
    "status": "complete",
    "result": {...}
  }
}

Schedule Executed

json
{
  "type": "schedule:executed",
  "data": {
    "scheduleId": "schedule-123",
    "result": "success",
    "nextRun": "2024-12-16T09:00:00Z"
  }
}

Message Received

json
{
  "type": "message:received",
  "data": {
    "id": 123,
    "role": "user",
    "content": "Hello!",
    "conversationId": "conv-456"
  }
}

Browser Action

json
{
  "type": "browser:action",
  "data": {
    "sessionId": "session-123",
    "action": "navigate",
    "status": "complete"
  }
}

Error

json
{
  "type": "error",
  "data": {
    "code": "RATE_LIMITED",
    "message": "Too many messages"
  }
}

Client Actions

Subscribe to Events

json
{
  "type": "subscribe",
  "events": ["workflow:status", "message:received"]
}

Unsubscribe

json
{
  "type": "unsubscribe",
  "events": ["workflow:status"]
}

Ping

json
{
  "type": "ping"
}

Response:

json
{
  "type": "pong",
  "timestamp": 1702648800000
}

Request State

json
{
  "type": "state:request"
}

Connection Handling

Reconnection

javascript
class WebSocketClient {
  constructor(url) {
    this.url = url
    this.reconnectDelay = 1000
    this.maxReconnectDelay = 30000
  }

  connect() {
    this.ws = new WebSocket(this.url)

    this.ws.onopen = () => {
      this.reconnectDelay = 1000
    }

    this.ws.onclose = () => {
      setTimeout(() => this.connect(), this.reconnectDelay)
      this.reconnectDelay = Math.min(
        this.reconnectDelay * 2,
        this.maxReconnectDelay
      )
    }
  }
}

Heartbeat

javascript
setInterval(() => {
  if (ws.readyState === WebSocket.OPEN) {
    ws.send(JSON.stringify({ type: 'ping' }))
  }
}, 30000)

Authentication

With Cloudflare Access

javascript
const ws = new WebSocket('wss://your-domain.com/agent/my-agent', {
  headers: {
    'CF-Access-JWT-Assertion': jwtToken
  }
})

Via URL Parameter

javascript
const ws = new WebSocket('wss://your-domain.com/agent/my-agent?token=' + token)

Rate Limiting

LimitValue
Connections per IP10
Messages per second10
Max message size64 KB

Example: Chat Interface

javascript
const ws = new WebSocket('wss://your-domain.com/agent/my-agent')

// Subscribe to messages
ws.onopen = () => {
  ws.send(JSON.stringify({
    type: 'subscribe',
    events: ['message:received']
  }))
}

// Handle incoming messages
ws.onmessage = (event) => {
  const msg = JSON.parse(event.data)

  if (msg.type === 'message:received') {
    displayMessage(msg.data)
  }
}

// Send message via REST API, receive via WebSocket
async function sendMessage(content) {
  await fetch('/api/agents/my-agent/chat', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ message: content })
  })
  // Response will come via WebSocket
}

Example: Workflow Monitor

javascript
const ws = new WebSocket('wss://your-domain.com/agent/my-agent')

ws.onopen = () => {
  ws.send(JSON.stringify({
    type: 'subscribe',
    events: ['workflow:status', 'workflow:complete']
  }))
}

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data)

  switch (msg.type) {
    case 'workflow:status':
      updateWorkflowStatus(msg.data)
      break
    case 'workflow:complete':
      showWorkflowResult(msg.data)
      break
  }
}

Errors

CodeDescription
1000Normal closure
1001Going away
1008Policy violation
1011Server error
4000Invalid message
4001Unauthorized
4029Rate limited

Released under the MIT License.