Socket.IO WebSocket Realtime API

Socket.IO WebSocket Realtime API

This API uses Socket.IO for real-time bidirectional communication over WebSocket connections. Unlike the REST endpoints, Socket.IO is event-based rather than request/response-based.

This is a documentation-only endpoint. The actual WebSocket connection is established at the Socket.IO namespace `/api/stream-chat`.

Connection

Connection URL: wss://api.agent700.ai
Namespace: /api/stream-chat
Transport: WebSocket (with automatic fallback to polling if needed)
Authentication: JWT token passed in the Authorization field of event payloads

Connection Lifecycle

  1. Client connects to the Socket.IO namespace /api/stream-chat
  2. Client emits send_chat_message event with chat request and JWT token
  3. Server processes the request and emits streaming response events
  4. Server automatically disconnects the client after processing completes
  5. Connection is closed (one message per connection pattern)
The server automatically disconnects clients after processing each message to prevent connection abuse. Each chat request requires a new connection.

Client → Server Events

send_chat_message

Client sends a chat completion request to the server.

Payload Schema: See WebSocketChatRequest schema below.

The payload structure matches the REST /api/chat endpoint's ChatRequest, but includes an additional Authorization field containing the JWT bearer token:

{
  "Authorization": "Bearer <your_jwt_token>",
  "agentId": "e2f5206e-5bfc-4d5c-a7a2-31a18bfc8bd6",
  "messages": [
    {
      "role": "user",
      "content": "Hello, how are you?"
    }
  ]
}
```json { "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "agentId": "e2f5206e-5bfc-4d5c-a7a2-31a18bfc8bd6", "messages": [ { "role": "system", "content": "You are a helpful assistant." }, { "role": "user", "content": "What is the weather today?" } ], "temperature": 0.7, "maxTokens": 1000, } ```

Server → Client Events

The server emits the following events during chat processing:

chat_message_response

Streaming content chunks and metadata from the LLM response.

Payload Schema: See WebSocketChatMessageResponse schema below.

This event is emitted multiple times during streaming:

  • Content chunks: {"content": "partial text", "stream_id": "..."}
  • Citations: {"citations": [...], "stream_id": "..."}
  • Completion: {"finish_reason": "stop", "safety_ratings": {...}, "stream_id": "..."}

mcp_tool_message

MCP (Model Context Protocol) tool execution messages.

Payload Schema: See WebSocketMCPToolMessage schema below.

Emitted when MCP tools are invoked during chat processing.

mcp_tool_complete_in_content

Notification that an MCP tool execution has completed and the result is included in the content.

Payload Schema: See WebSocketMCPToolComplete schema below.

scrubbed_message

Notification that message content was scrubbed for PII (Personally Identifiable Information).

Payload Schema: See WebSocketScrubbedMessage schema below.

error

Error events indicating processing failures, authentication errors, or validation issues.

Payload Schema: See WebSocketErrorEvent schema below.

Common error scenarios:

  • Authentication failure: Invalid or missing JWT token
  • Payment validation: Agent owner does not have valid paid account
  • Access denied: User lacks permission to use the agent
  • Processing error: Internal error during LLM processing

Code Examples

```javascript import { io } from 'socket.io-client';

// Connect to the Socket.IO namespace const socket = io('https://api.agent700.ai/api/stream-chat', { transports: ['websocket', 'polling'], reconnection: false // One message per connection });

// Listen for connection socket.on('connect', () => { console.log('Connected:', socket.id);

// Send chat message socket.emit('send_chat_message', { Authorization: 'Bearer YOUR_JWT_TOKEN', agentId: 'e2f5206e-5bfc-4d5c-a7a2-31a18bfc8bd6', messages: [ { role: 'user', content: 'Hello, how are you?' } ] }); });

// Listen for streaming responses socket.on('chat_message_response', (data) => { if (data.content) { // Append content chunk console.log('Content chunk:', data.content); } if (data.citations) { // Handle citations console.log('Citations:', data.citations); } if (data.finish_reason) { // Stream complete console.log('Finished:', data.finish_reason); console.log('Safety ratings:', data.safety_ratings); } });

// Listen for MCP tool messages socket.on('mcp_tool_message', (data) => { console.log('MCP tool message:', data.message); });

// Listen for errors socket.on('error', (data) => { console.error('Error:', data.error, 'Code:', data.code); });

// Handle disconnection socket.on('disconnect', () => { console.log('Disconnected'); });

</Tab>
<Tab title="Python">
```python
import socketio

# Create Socket.IO client
sio = socketio.Client()

@sio.event
def connect():
    print('Connected:', sio.sid)
    
    # Send chat message
    sio.emit('send_chat_message', {
        'Authorization': 'Bearer YOUR_JWT_TOKEN',
        'agentId': 'e2f5206e-5bfc-4d5c-a7a2-31a18bfc8bd6',
        'messages': [
            {'role': 'user', 'content': 'Hello, how are you?'}
        ]
    })

@sio.on('chat_message_response')
def on_chat_response(data):
    if 'content' in data:
        print('Content chunk:', data['content'])
    if 'citations' in data:
        print('Citations:', data['citations'])
    if 'finish_reason' in data:
        print('Finished:', data['finish_reason'])
        print('Safety ratings:', data.get('safety_ratings'))

@sio.on('mcp_tool_message')
def on_mcp_tool(data):
    print('MCP tool message:', data['message'])

@sio.on('error')
def on_error(data):
    print('Error:', data.get('error'), 'Code:', data.get('code'))

@sio.event
def disconnect():
    print('Disconnected')

# Connect to namespace
sio.connect('https://api.agent700.ai', namespaces=['/api/stream-chat'])
```bash # Note: cURL cannot directly connect to Socket.IO WebSocket # Use a WebSocket client library instead # This example shows the connection URL structure

WebSocket URL (Socket.IO handles the path):

wss://api.agent700.ai/socket.io/?EIO=4&transport=websocket

Namespace connection:

wss://api.agent700.ai/socket.io/?EIO=4&transport=websocket&namespace=/api/stream-chat

</Tab>
</Tabs>

## Error Handling

### Connection Errors

- **Connection refused**: Server may be down or firewall blocking
- **Timeout**: Network connectivity issues
- **Namespace not found**: Invalid namespace path

### Authentication Errors

The server emits an `error` event with:
```json
{
  "error": "Unauthorized",
  "code": 401,
  "timestamp": 1234567890.123
}

Payment Validation Errors

If the agent owner does not have a valid paid account:

{
  "error": "Payment required",
  "code": 402,
  "timestamp": 1234567890.123
}

Processing Errors

Internal errors during LLM processing:

{
  "error": "An error occurred processing your request",
  "timestamp": 1234567890.123
}

Comparison with SSE Streaming

The /api/chat endpoint with streamingEnabled: true provides Server-Sent Events (SSE) as an alternative to WebSocket:

FeatureWebSocket (Socket.IO)SSE
TransportBidirectional WebSocketUnidirectional HTTP
ConnectionOne message per connectionPersistent connection
EventsCustom event namesStandard SSE format
ReconnectionManual (new connection)Automatic by browser
Client LibrariesSocket.IO client requiredNative EventSource API

Choose WebSocket when you need bidirectional communication or custom event handling. Choose SSE for simpler integration with standard browser APIs.

Security Considerations

  • JWT tokens must be included in each send_chat_message event payload
  • Connections are automatically closed after processing to prevent abuse
  • All events are logged for security monitoring
  • Payment validation is enforced for agent access
  • Rate limiting may apply (check with support for details)

Socket.IO WebSocket Realtime API

Get real-time responses from your AI agents using Socket.IO WebSockets! This API provides bidirectional communication that's perfect for building interactive chat applications.

New to WebSockets? Think of it like having a phone conversation with your AI agent instead of sending letters back and forth. You get instant responses as the AI thinks and responds in real-time.

Quick Start

Want to jump right in? Here's the minimal setup to get started:

import { io } from 'socket.io-client';

// 1. Connect to Agent700
const socket = io('https://api.agent700.ai/api/stream-chat');

// 2. Send a message when connected
socket.on('connect', () => {
  socket.emit('send_chat_message', {
    Authorization: 'Bearer YOUR_JWT_TOKEN',
    messages: [{ role: 'user', content: 'Hello!' }]
  });
});

// 3. Listen for the response
socket.on('chat_message_response', (data) => {
  if (data.content) {
    console.log('AI says:', data.content);
  }
});

How It Works

Connection Lifecycle

The Socket.IO API follows a simple pattern:

  1. Connect → Your app connects to our WebSocket server
  2. Send → You send a chat message with your request
  3. Stream → We stream back the AI's response in real-time chunks
  4. Disconnect → We automatically close the connection when done

One Message Per Connection: Each connection handles exactly one chat request. For multiple messages, create new connections. This prevents connection abuse and ensures optimal performance.

Authentication

Every message must include your JWT token:

{
  "Authorization": "Bearer YOUR_JWT_TOKEN",
  // ... rest of your message
}

Get your JWT token from any of these login endpoints:

  • /api/auth/login (email/password)
  • /api/auth/googleauth (Google OAuth)
  • /api/auth/app-login (app password)

Connection Details

SettingValue
URLwss://api.agent700.ai
Namespace/api/stream-chat
TransportWebSocket (auto-fallback to polling)
ReconnectionDisabled (one message per connection)

Sending Messages

Basic Message Format

socket.emit('send_chat_message', {
  Authorization: 'Bearer YOUR_JWT_TOKEN',
  messages: [
    { role: 'user', content: 'Your question here' }
  ]
})

With Specific Agent

socket.emit('send_chat_message', {
  Authorization: 'Bearer YOUR_JWT_TOKEN',
  agentId: 'e2f5206e-5bfc-4d5c-a7a2-31a18bfc8bd6',
  messages: [
    { role: 'user', content: 'Hello, how are you?' }
  ]
})

Advanced Options

View all available options
socket.emit('send_chat_message', {
  Authorization: 'Bearer YOUR_JWT_TOKEN',
  agentId: 'e2f5206e-5bfc-4d5c-a7a2-31a18bfc8bd6',
  messages: [
    { role: 'system', content: 'You are a helpful assistant.' },
    { role: 'user', content: 'What is the weather today?' }
  ],
  temperature: 0.7,        // Creativity level (0-1)
  maxTokens: 1000,         // Response length limit
  streamResponses: true,   // Enable streaming
  model: 'gpt-4',         // Specific model to use
  scrubPii: true,         // Remove personal info
  piiThreshold: 0.8       // PII detection sensitivity
})

Receiving Responses

The server sends several types of events during processing:

📝 chat_message_response

The main event containing your AI's response, sent in chunks:

socket.on('chat_message_response', (data) => {
  // Content chunks (multiple events)
  if (data.content) {
    console.log('New chunk:', data.content);
    // Append to your chat interface
  }
  
  // Citations (if available)
  if (data.citations) {
    console.log('Sources:', data.citations);
  }
  
  // Completion signal (final event)
  if (data.finish_reason) {
    console.log('Done! Reason:', data.finish_reason);
  }
});

🔧 mcp_tool_message

When the AI uses tools (MCP - Model Context Protocol):

socket.on('mcp_tool_message', (data) => {
  console.log('AI is using tool:', data.message);
  // Show "AI is searching..." or similar UI
});

🛡️ scrubbed_message

When we remove personal information from messages:

socket.on('scrubbed_message', (data) => {
  console.log('Cleaned message:', data.content);
  // Original: "My email is [email protected]"
  // Scrubbed: "My email is [REDACTED]"
});

error

When something goes wrong:

socket.on('error', (data) => {
  console.error('Error:', data.error);
  if (data.code === 401) {
    // Handle authentication error
  }
});

Complete Examples

React Chat Component

Full React example with hooks
import { useState, useEffect } from 'react';
import { io } from 'socket.io-client';

function ChatWidget({ jwtToken, agentId }) {
  const [messages, setMessages] = useState([]);
  const [input, setInput] = useState('');
  const [isLoading, setIsLoading] = useState(false);

  const sendMessage = () => {
    if (!input.trim() || isLoading) return;
    
    const userMessage = { role: 'user', content: input };
    setMessages(prev => [...prev, userMessage]);
    setInput('');
    setIsLoading(true);

    // Create new socket connection
    const socket = io('https://api.agent700.ai/api/stream-chat', {
      transports: ['websocket', 'polling'],
      reconnection: false
    });

    let aiResponse = { role: 'assistant', content: '' };
    setMessages(prev => [...prev, aiResponse]);

    socket.on('connect', () => {
      socket.emit('send_chat_message', {
        Authorization: `Bearer ${jwtToken}`,
        agentId: agentId,
        messages: [...messages, userMessage]
      });
    });

    socket.on('chat_message_response', (data) => {
      if (data.content) {
        // Update the AI response with new content
        setMessages(prev => {
          const newMessages = [...prev];
          newMessages[newMessages.length - 1].content += data.content;
          return newMessages;
        });
      }
      
      if (data.finish_reason) {
        setIsLoading(false);
        socket.disconnect();
      }
    });

    socket.on('error', (data) => {
      console.error('Socket error:', data);
      setIsLoading(false);
      socket.disconnect();
    });
  };

  return (
    <div className="chat-widget">
      <div className="messages">
        {messages.map((msg, i) => (
          <div key={i} className={`message ${msg.role}`}>
            {msg.content}
          </div>
        ))}
      </div>
      
      <div className="input-area">
        <input
          value={input}
          onChange={(e) => setInput(e.target.value)}
          onKeyPress={(e) => e.key === 'Enter' && sendMessage()}
          placeholder="Type your message..."
          disabled={isLoading}
        />
        <button onClick={sendMessage} disabled={isLoading}>
          {isLoading ? 'Thinking...' : 'Send'}
        </button>
      </div>
    </div>
  );
}

Python CLI Chat

Python command-line chat bot
import socketio
import json
import sys

class Agent700Chat:
    def __init__(self, jwt_token, agent_id=None):
        self.jwt_token = jwt_token
        self.agent_id = agent_id
        self.messages = []
        
    def chat(self, user_input):
        # Add user message
        self.messages.append({
            'role': 'user', 
            'content': user_input
        })
        
        # Create socket connection
        sio = socketio.Client()
        response_content = []
        
        @sio.event
        def connect():
            print("🔗 Connected to Agent700")
            payload = {
                'Authorization': f'Bearer {self.jwt_token}',
                'messages': self.messages
            }
            if self.agent_id:
                payload['agentId'] = self.agent_id
                
            sio.emit('send_chat_message', payload)
        
        @sio.on('chat_message_response')
        def on_response(data):
            if 'content' in data:
                content = data['content']
                response_content.append(content)
                print(content, end='', flush=True)
            
            if 'finish_reason' in data:
                print("\n")  # New line after response
                full_response = ''.join(response_content)
                self.messages.append({
                    'role': 'assistant',
                    'content': full_response
                })
                sio.disconnect()
        
        @sio.on('error')
        def on_error(data):
            print(f"❌ Error: {data.get('error')}")
            sio.disconnect()
        
        # Connect and wait
        sio.connect('https://api.agent700.ai', 
                   namespaces=['/api/stream-chat'])
        sio.wait()

# Usage
if __name__ == "__main__":
    JWT_TOKEN = "your_jwt_token_here"
    AGENT_ID = "your_agent_id_here"  # Optional
    
    chat = Agent700Chat(JWT_TOKEN, AGENT_ID)
    
    print("💬 Agent700 Chat (type 'quit' to exit)")
    while True:
        user_input = input("\nYou: ")
        if user_input.lower() in ['quit', 'exit']:
            break
        
        print("🤖 AI: ", end='')
        chat.chat(user_input)

Error Handling & Troubleshooting

Common Issues and Solutions

❌ Connection Failed

Problem: Can't connect to the WebSocket server

Solutions:

  • Check your internet connection
  • Verify the URL: https://api.agent700.ai/api/stream-chat
  • Try with polling transport: { transports: ['polling'] }
  • Check if your firewall blocks WebSocket connections
const socket = io('https://api.agent700.ai/api/stream-chat', {
  transports: ['polling', 'websocket'], // Try polling first
  timeout: 10000 // 10 second timeout
});
🔐 Authentication Errors (401)

Problem: "Unauthorized" error

Solutions:

  • Check your JWT token is valid and not expired
  • Ensure you include "Bearer " prefix
  • Verify the token has proper permissions
// ✅ Correct format
Authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'

// ❌ Wrong format
Authorization: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
💳 Payment Required (402)

Problem: "Payment required" error

Solution: The agent owner needs a valid paid account. Contact support or upgrade your plan.

🚫 Access Denied (403)

Problem: Can't access the specified agent

Solutions:

  • Verify the agent ID is correct
  • Ensure the agent is shared with you or you own it
  • Check if the agent allows public sharing

Error Event Handling

Always handle errors gracefully:

socket.on('error', (data) => {
  const { error, code, timestamp } = data;
  
  switch (code) {
    case 401:
      showError('Please log in again');
      redirectToLogin();
      break;
    case 402:
      showError('Upgrade required for this agent');
      break;
    case 403:
      showError('You don\'t have access to this agent');
      break;
    default:
      showError(`Something went wrong: ${error}`);
  }
  
  socket.disconnect();
});

WebSocket vs Server-Sent Events (SSE)

Choosing between WebSocket and SSE? Here's when to use each:

FeatureWebSocket (This API)SSE (/api/chat/stream)
Best forInteractive apps, real-time chatSimple streaming, read-only
Setup complexityMedium (requires Socket.IO)Low (native browser support)
Connection typeBidirectionalUnidirectional
Browser supportExcellent (with Socket.IO)Native in modern browsers
ReconnectionManual (new connection each time)Automatic
Custom events✅ Yes (chat_message_response, error, etc.)❌ No (standard SSE format)

Choose WebSocket when:

  • Building interactive chat interfaces
  • Need custom event handling
  • Want real-time bidirectional communication

Choose SSE when:

  • Simple streaming responses
  • Minimal setup requirements
  • Using native browser EventSource API

Rate Limits & Best Practices

Connection Limits

  • Concurrent connections: Limited per user (check with support)
  • Message rate: Reasonable usage expected
  • Connection lifetime: Auto-disconnect after response

Best Practices

  1. Handle disconnections gracefully:
socket.on('disconnect', (reason) => {
  if (reason === 'io server disconnect') {
    // Server disconnected (normal after response)
    console.log('Chat completed');
  } else {
    // Network issue - show error to user
    console.log('Connection lost:', reason);
  }
});
  1. Use connection timeouts:
const socket = io(url, {
  timeout: 10000, // 10 second timeout
  reconnection: false
});
  1. Clean up resources:
// Always disconnect when done
socket.disconnect();
  1. Implement retry logic:
function connectWithRetry(maxRetries = 3) {
  let attempts = 0;
  
  function tryConnect() {
    const socket = io(url);
    
    socket.on('connect_error', (error) => {
      attempts++;
      if (attempts < maxRetries) {
        setTimeout(tryConnect, 1000 * attempts); // Exponential backoff
      } else {
        console.error('Max retries reached');
      }
    });
    
    return socket;
  }
  
  return tryConnect();
}

Security Notes

  • 🔐 JWT tokens: Include in every send_chat_message event
  • 🔒 HTTPS only: All connections use secure WebSocket (wss://)
  • 📝 Logging: All events are logged for security monitoring
  • ⏱️ Auto-disconnect: Connections close automatically to prevent abuse
  • 🛡️ Rate limiting: Applied to prevent API abuse

Need Help?

  • 📖 API Reference: Full technical details in the OpenAPI schema
  • 💬 Support: Contact [email protected]
  • 🐛 Issues: Report bugs through your dashboard
  • 📚 Examples: More examples in our GitHub repository

Ready to build something amazing with real-time AI? Start with the Quick Start section above!

Language
Credentials
Bearer
JWT
Click Try It! to start a request and see the response here!