Skip to main content
POST
/
event
curl -X POST "http://localhost:5001/event" \
  -H "Content-Type: application/json" \
  -d '{
    "client_msg_no": "msg_001_stream_start",
    "channel_id": "group_ai_chat",
    "channel_type": 2,
    "from_uid": "ai_assistant",
    "event": {
      "type": "___TextMessageStart",
      "data": "{\"type\":1,\"content\":\"Starting AI response...\"}"
    }
  }'
{
  "status": "ok"
}

Overview

Send various types of events to channels, including streaming text messages and custom events. Supports AG-UI protocol events for real-time streaming communication.

Query Parameters

force
string
default:"0"
Force end existing streams in the channel before starting a new one
  • 0 - Do not force end
  • 1 - Force end existing streams

Request Body

Required Parameters

client_msg_no
string
required
Client message number - must be unique and not repeated. Used to identify and track the message/stream. For streaming messages, all events in the same stream should use the same client_msg_no. UUID format is recommended.
channel_id
string
required
Target channel ID where the event will be sent. For person channels, this should be the target user ID. For group channels, this should be the group ID.
channel_type
integer
required
Channel type
  • 1 - Person channel
  • 2 - Group channel
event
object
required
Event object

Optional Parameters

from_uid
string
Sender user ID. If not provided or empty, defaults to the system UID. This identifies who is sending the event.
curl -X POST "http://localhost:5001/event" \
  -H "Content-Type: application/json" \
  -d '{
    "client_msg_no": "msg_001_stream_start",
    "channel_id": "group_ai_chat",
    "channel_type": 2,
    "from_uid": "ai_assistant",
    "event": {
      "type": "___TextMessageStart",
      "data": "{\"type\":1,\"content\":\"Starting AI response...\"}"
    }
  }'
{
  "status": "ok"
}

Response Fields

status
string
required
Operation status, returns "ok" on success

Status Codes

Status CodeDescription
200Event sent successfully
400Bad request - invalid parameters or event data
500Internal server error

Streaming Message Flow

Streaming Message Process

  1. Start Stream: Send ___TextMessageStart event to initiate a stream
  2. Send Content: Send multiple ___TextMessageContent events with message chunks
  3. End Stream: Send ___TextMessageEnd event to close the stream

Important Notes

  • The same client_msg_no must be used for all events in a streaming session
  • Only one stream can be active per channel unless force=1 is used
  • For person channels, the system automatically handles fake channel ID generation
  • Events are automatically routed to the appropriate cluster node

Event Types

AG-UI Protocol Events

AG-UI protocol events enable real-time streaming communication for AI applications:
Event TypePurposeData Format
___TextMessageStartInitiates a streaming text message sessionInitial content or metadata
___TextMessageContentSends content chunks during streamingText chunk content
___TextMessageEndTerminates a streaming text message sessionCompletion marker
___ToolCallStartBegins a tool/function call eventTool name or metadata
___ToolCallArgsSends arguments for tool callsJSON formatted arguments
___ToolCallEndEnds a tool call eventCompletion status
___ToolCallResultReturns results from tool executionJSON formatted results

Custom Events

Any event type not starting with ___ is treated as a custom event, useful for:
  • User status updates
  • System notifications
  • Business logic events
  • Application-specific interactions

Use Cases

AI Chatbot

# Simulate AI typing effect
curl -X POST "/event" -d '{
  "client_msg_no": "ai_response_001",
  "channel_id": "user_123",
  "channel_type": 1,
  "from_uid": "ai_bot",
  "event": {
    "type": "___TextMessageStart",
    "data": "Thinking..."
  }
}'

# Gradually send response content
curl -X POST "/event" -d '{
  "client_msg_no": "ai_response_001",
  "channel_id": "user_123", 
  "channel_type": 1,
  "from_uid": "ai_bot",
  "event": {
    "type": "___TextMessageContent",
    "data": "Based on your question, I recommend..."
  }
}'

Real-time Collaboration

# Document editing status
curl -X POST "/event" -d '{
  "client_msg_no": "doc_edit_001",
  "channel_id": "doc_room_456",
  "channel_type": 2,
  "from_uid": "user_789",
  "event": {
    "type": "document_editing",
    "data": "{\"action\": \"start_edit\", \"section\": \"paragraph_1\"}"
  }
}'

System Notifications

# User online notification
curl -X POST "/event" -d '{
  "client_msg_no": "status_update_001",
  "channel_id": "group_general",
  "channel_type": 2,
  "from_uid": "system",
  "event": {
    "type": "user_online",
    "timestamp": 1640995200000,
    "data": "{\"user_id\": \"user_123\", \"status\": \"online\"}"
  }
}'

Best Practices

  1. Unique Identification: Use UUID format for client_msg_no to ensure uniqueness
  2. Stream Management: Close unused streams promptly to avoid resource waste
  3. Error Handling: Handle stream conflicts and send failures
  4. Permission Verification: Ensure sender has channel send permissions
  5. Data Format: Use JSON format strings for complex data
  6. Performance Optimization: Control streaming message send frequency reasonably

Error Handling

Common Errors

ErrorCauseSolution
Event type cannot be emptyNo event.type providedEnsure valid event type is provided
Stream already running in channelTrying to start new stream when one is activeUse force=1 or wait for existing stream to end
Stream does not existTrying to send content to non-existent streamCheck if stream was created correctly
Stream is already closedSending content to closed streamStart a new stream

Retry Mechanism

For temporary errors, implement exponential backoff retry mechanism:
async function sendEventWithRetry(eventData, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch('/event', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(eventData)
      });
      
      if (response.ok) return await response.json();
      
      if (response.status >= 400 && response.status < 500) {
        // Client error, don't retry
        throw new Error(`Client error: ${response.status}`);
      }
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000));
    }
  }
}