Last Updated: 2026-04-07 Status: Active (v2 — updated for service delegation)
1. Overview
The Chat Engine API is organized into 5 domains. Knowledge and contact management are delegated to AI Brain and Contact Intelligence respectively.
| Domain | Base Path | Description |
|---|---|---|
| Webhook & Widget | /webhooks/*, /chat/widget/* |
Inbound customer messages |
| Config & Persona | /config, /channels |
Bot settings and channel integrations |
| Unified Inbox | /sessions/* |
Agent dashboard for human handoff |
| Analytics | /analytics/* |
Engagement metrics |
| Internal | /internal/* |
Cron triggers, maintenance |
Delegated APIs (NOT in Chat Engine):
- Knowledge base:
POST /brain/knowledge(AI Brain) - Contact memory:
GET /contacts-intel/context/{id}(Contact Intelligence) - Outreach:
POST /contacts-intel/outreach(Contact Intelligence)
2. Authentication
All endpoints (except webhooks) require JWT via the gateway:
Authorization: Bearer {access_token}Webhooks use platform-specific signature verification:
- WhatsApp: HMAC-SHA256 via
X-Hub-Signature-256 - Telegram: Secret token in URL path
- Widget: Widget token validated against
ChannelIntegration.identifier
3. Endpoints
3.1 Webhook Ingress
POST /webhooks/whatsapp/{tenantId}
Accept incoming WhatsApp messages. Must respond 200 within 3 seconds.
Headers: X-Hub-Signature-256 (HMAC verification)
Flow:
- Verify HMAC signature
- Parse webhook → normalize to internal format
- Dedup via
external_message_id - Resolve contact via Contact Intelligence
- Fetch context from CI → generate response via Brain → deliver
Response: 200 OK (immediate ACK, processing is async)
POST /webhooks/telegram/{tenantId}
Same pattern as WhatsApp with Telegram-specific parsing.
POST /chat/widget/message
Website widget message with SSE streaming response.
Body:
{
"session_id": "optional-existing-session",
"message": "How much do your cakes cost?",
"widget_token": "wt_abc123"
}Response: SSE stream
event: token
data: {"text": "Our"}
event: token
data: {"text": " cakes"}
event: done
data: {"session_id": "sess_123", "message_id": "msg_456"}3.2 Bot Configuration
GET /config
Get bot configuration for the tenant.
Response:
{
"config": {
"id": "...",
"name": "Sarah",
"personaPrompt": "You are a friendly bakery assistant...",
"fallbackMessage": "Let me connect you to our team...",
"activeModel": "sonnet",
"creativity": 0.2,
"leadCaptureRules": [...]
}
}PATCH /config
Update bot configuration.
Body: Partial BotConfig fields.
3.3 Channel Management
GET /channels
List channel integrations.
POST /channels
Connect a new channel (WhatsApp OAuth, Telegram bot token, Widget domain).
Body:
{
"platform": "whatsapp",
"identifier": "+919876543210",
"credentials": { "access_token": "..." }
}DELETE /channels/{channelId}
Disconnect a channel.
3.4 Unified Inbox (Agent Dashboard)
GET /sessions
List chat sessions with filters.
Query: status=human_escalated|ai_handled|closed, limit, offset
Response:
{
"sessions": [{
"id": "sess_123",
"contactId": "ci_contact_id",
"contactName": "Arjun Patel",
"channel": "whatsapp",
"status": "human_escalated",
"lastMessage": "I need to speak to a manager",
"messageCount": 12,
"slaBreachAt": "2026-04-07T10:15:00Z",
"lastMessageAt": "2026-04-07T10:00:00Z"
}],
"total": 5
}GET /sessions/{sessionId}/messages
Fetch message thread for a session.
Query: limit=50, before=cursor_msg_id
POST /sessions/{sessionId}/reply
Agent sends a manual reply.
Body:
{
"content": "I'll look into this for you right away.",
"role": "agent"
}POST /sessions/{sessionId}/assign
Assign session to an agent.
Body: { "agent_id": "user_abc" }
PATCH /sessions/{sessionId}/resolve
Close/resolve a session.
Body: { "summary": "Customer asked about pricing, provided quote." }
3.5 Analytics
GET /analytics/overview
Dashboard metrics.
Query: period=7d|30d|90d
Response:
{
"total_sessions": 156,
"ai_resolved": 132,
"human_escalated": 24,
"resolution_rate": 0.846,
"avg_response_time_ms": 1200,
"leads_captured": 18,
"total_messages": 892,
"top_intents": [
{ "intent": "pricing_query", "count": 45 },
{ "intent": "order_status", "count": 32 }
]
}GET /analytics/unanswered
Top questions the AI couldn't answer (low confidence / handoff triggers).
Query: limit=10
3.6 Real-Time Events (SSE)
Dashboard connects via SSE for real-time updates:
GET /events/stream
Authorization: Bearer {token}Events:
| Event | Data | When |
|---|---|---|
chat:new_message |
{ sessionId, message } |
New message in any session |
chat:escalated |
{ sessionId, contactName } |
AI triggers handoff |
chat:assigned |
{ sessionId, agentId } |
Session assigned to agent |
chat:resolved |
{ sessionId } |
Session closed |
chat:sla_breach |
{ sessionId, contactName } |
Escalation exceeded SLA |
3.7 Internal Endpoints
POST /internal/sla/sweep
Cron-triggered SLA breach check (every 1 minute).
POST /internal/sessions/cleanup
Cron-triggered: close idle sessions (24h inactivity).
4. Error Format
{
"error": {
"code": "SESSION_NOT_FOUND",
"message": "Chat session not found",
"status": 404
}
}Standard codes: UNAUTHORIZED, FORBIDDEN, NOT_FOUND, RATE_LIMITED, VALIDATION_ERROR, PROVIDER_ERROR, INTERNAL_ERROR.