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
- Client connects to the Socket.IO namespace
/api/stream-chat - Client emits
send_chat_messageevent with chat request and JWT token - Server processes the request and emits streaming response events
- Server automatically disconnects the client after processing completes
- Connection is closed (one message per connection pattern)
Client → Server Events
send_chat_message
send_chat_messageClient 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
chat_message_responseStreaming 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_tool_messageMCP (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
mcp_tool_complete_in_contentNotification that an MCP tool execution has completed and the result is included in the content.
Payload Schema: See WebSocketMCPToolComplete schema below.
scrubbed_message
scrubbed_messageNotification that message content was scrubbed for PII (Personally Identifiable Information).
Payload Schema: See WebSocketScrubbedMessage schema below.
error
errorError 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:
| Feature | WebSocket (Socket.IO) | SSE |
|---|---|---|
| Transport | Bidirectional WebSocket | Unidirectional HTTP |
| Connection | One message per connection | Persistent connection |
| Events | Custom event names | Standard SSE format |
| Reconnection | Manual (new connection) | Automatic by browser |
| Client Libraries | Socket.IO client required | Native 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_messageevent 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:
- Connect → Your app connects to our WebSocket server
- Send → You send a chat message with your request
- Stream → We stream back the AI's response in real-time chunks
- 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
| Setting | Value |
|---|---|
| URL | wss://api.agent700.ai |
| Namespace | /api/stream-chat |
| Transport | WebSocket (auto-fallback to polling) |
| Reconnection | Disabled (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
chat_message_responseThe 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
mcp_tool_messageWhen 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
scrubbed_messageWhen 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
errorWhen 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:
| Feature | WebSocket (This API) | SSE (/api/chat/stream) |
|---|---|---|
| Best for | Interactive apps, real-time chat | Simple streaming, read-only |
| Setup complexity | Medium (requires Socket.IO) | Low (native browser support) |
| Connection type | Bidirectional | Unidirectional |
| Browser support | Excellent (with Socket.IO) | Native in modern browsers |
| Reconnection | Manual (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
- 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);
}
});- Use connection timeouts:
const socket = io(url, {
timeout: 10000, // 10 second timeout
reconnection: false
});- Clean up resources:
// Always disconnect when done
socket.disconnect();- 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_messageevent - 🔒 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!
