WebSocket API
Real-time bidirectional communication for live demo sessions. The WebSocket connection handles chat messages, typing indicators, iframe commands, and lead capture events.
Connection
wss://api.iraa.ai/ws/session/:sessionId?token=SESSION_JWTThe sessionId and token are obtained from the POST /api/v1/session endpoint.
All messages are JSON objects with type and payload fields.
JavaScript Example
// After creating a session via POST /api/v1/session
const { sessionId, token } = session;
const ws = new WebSocket(
`wss://api.iraa.ai/ws/session/${sessionId}?token=${token}`
);
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
switch (msg.type) {
case 'agent_response':
console.log('Agent:', msg.payload.text);
console.log('Commands:', msg.payload.iframeCommands);
console.log('Suggestions:', msg.payload.suggestions);
break;
case 'typing_indicator':
console.log('Typing:', msg.payload.isTyping);
break;
case 'lead_form':
console.log('Show lead form:', msg.payload.fields);
break;
case 'error':
console.error('Error:', msg.payload.code, msg.payload.message);
break;
case 'pong':
// Heartbeat response
break;
}
};
// Send a message
ws.send(JSON.stringify({
type: 'visitor_message',
payload: { text: 'Show me the dashboard' }
}));
// Keep alive
setInterval(() => {
ws.send(JSON.stringify({ type: 'heartbeat', payload: {} }));
}, 30000);Client → Server Messages
Client
visitor_messageSend a chat message from the visitor.
{
"type": "visitor_message",
"payload": { "text": "Show me the dashboard" }
}Client
heartbeatKeep the connection alive. Server responds with pong.
{
"type": "heartbeat",
"payload": {}
}Client
iframe_eventReport an event from the demo iframe (click, navigation, etc.) for analytics.
{
"type": "iframe_event",
"payload": {
"event": "click",
"selector": "#btn",
"url": "/dashboard"
}
}Server → Client Messages
Server
agent_responseAgent's reply with text, TTS audio reference, iframe commands, and suggested replies.
{
"type": "agent_response",
"payload": {
"text": "Here's the dashboard! Let me show you the pipeline.",
"speech": "Here's the dashboard. Let me show you the pipeline.",
"iframeCommands": [
{ "action": "navigate", "url": "/dashboard" },
{ "action": "highlight", "selector": "[data-testid='pipeline-chart']" }
],
"suggestions": ["Create a deal", "Show contacts", "Tell me about pricing"],
"agentId": "demo"
}
}Iframe command actions:
navigate— Navigate to a URLclick— Click an elementtype— Type text into an inputhighlight— Visually highlight an elementscroll— Scroll to an elementwait— Wait for a selector to appearselect— Select a dropdown option
Server
typing_indicatorAgent is processing a response.
{
"type": "typing_indicator",
"payload": { "agentId": "demo", "isTyping": true }
}Server
lead_formTrigger the lead capture form in the widget.
{
"type": "lead_form",
"payload": {
"fields": ["email", "company"],
"cta": { "text": "Start Free Trial", "url": "https://example.com/signup" }
}
}Server
errorError occurred during processing.
{
"type": "error",
"payload": {
"code": "SESSION_EXPIRED",
"message": "Session expired"
}
}Error codes:
AUTH_REQUIRED | No token provided |
INVALID_TOKEN | Token is invalid or expired |
SESSION_NOT_FOUND | Session does not exist |
SESSION_EXPIRED | Session has timed out |
INVALID_JSON | Message is not valid JSON |
EMPTY_MESSAGE | Message text is empty |
UNKNOWN_TYPE | Unrecognized message type |
PDP_NOT_FOUND | PDP config not found for session |
Server
pongResponse to heartbeat.
{
"type": "pong",
"payload": { "ts": 1711000000000 }
}Connection Lifecycle
- Create a session via
POST /api/v1/sessionto getsessionIdandtoken - Connect to
wss://api.iraa.ai/ws/session/:sessionId?token=TOKEN - Send
visitor_messageevents to chat with the agent - Receive
typing_indicatorfollowed byagent_response - Execute iframe commands from
agent_response.payload.iframeCommands - Send periodic
heartbeatto keep connection alive (recommended: every 30s) - Handle
lead_formevents to show lead capture UI - End session via
POST /api/v1/session/:sessionId/end
Close Codes
| Code | Reason |
|---|---|
4001 | Authentication failed (missing or invalid token) |
4004 | Session not found |
1000 | Normal closure |