Human Escalation & Inbox
When the AI cannot resolve a customer issue, it escalates to your human team. You can then take over the conversation, reply directly, and resume AI handling.
List Escalations
Retrieve all escalated conversations in your inbox.
GET /api/tenants/me/escalations?status=open&limit=20
Query Parameters
| Param | Type | Default | Notes |
|---|---|---|---|
status | enum | all | open, resolved, in_progress |
limit | number | 20 | Page size |
Response
{
"data": [
{
"id": "esc_ulid",
"conversationId": "conv_ulid",
"customerId": "cust_ulid",
"customerName": "Nguyen Van A",
"reason": "3× gate failure",
"status": "open",
"createdAt": "2026-03-12T10:05:00Z",
"lastMessageAt": "2026-03-12T10:05:00Z"
}
]
}
Get Escalation Details
Retrieve a single escalation with full conversation history.
GET /api/tenants/me/escalations/:escalationId
Response
{
"id": "esc_ulid",
"conversationId": "conv_ulid",
"customerId": "cust_ulid",
"customerName": "Nguyen Van A",
"reason": "3× gate failure: repeated phrases + unverified claims",
"status": "open",
"takenOverBy": null,
"messages": [
{
"role": "customer",
"content": "Tôi muốn khiếu nại...",
"timestamp": "2026-03-12T10:00:00Z"
},
{
"role": "assistant",
"content": "Mình sẽ chuyển bạn đến đội hỗ trợ nhé!",
"timestamp": "2026-03-12T10:05:00Z"
}
],
"createdAt": "2026-03-12T10:05:00Z"
}
Take Over Conversation
Pause AI and enter human-takeover mode.
POST /api/tenants/me/escalations/:escalationId/takeover
Request
{
"agentName": "Minh"
}
Response
{
"status": "taken_over",
"takenOverBy": "Minh",
"timestamp": "2026-03-12T10:06:00Z"
}
Effect: The AI stops responding to this conversation. All future messages wait for your reply.
Send Human Reply
Reply to the customer as a human agent.
POST /api/tenants/me/escalations/:escalationId/send
Request
{
"content": "Chào bạn, mình là quản lý Minh. Mình đã kiểm tra đơn hàng và sẽ xử lý ngay cho bạn.",
"mediaUrl": null
}
Response
{
"success": true,
"messageId": "msg_ulid",
"sentAt": "2026-03-12T10:07:00Z",
"sentVia": "pancake"
}
Note: Message is sent via Pancake API with your agent name as the sender.
Release Back to AI
Resume AI handling after human takeover.
POST /api/tenants/me/escalations/:escalationId/release
Response
{
"status": "released",
"releasedAt": "2026-03-12T10:10:00Z"
}
Effect: The AI resumes handling this conversation. Future customer messages are processed normally.
Mark Escalation Resolved
Close an escalation.
POST /api/tenants/me/escalations/:escalationId/resolve
Request
{
"resolution": "customer_satisfied"
}
Response
{
"status": "resolved",
"resolvedAt": "2026-03-12T10:15:00Z"
}
Escalation Reasons
When an escalation is created, the reason field explains why:
| Reason | Meaning |
|---|---|
3× gate failure | AI retried 3× and all gates failed |
escalation_trigger | Customer message contained escalation keyword |
manual | Manually escalated by customer or staff |
rate_limit | Too many messages, queue overloaded |
Inbox Workflow
Typical Flow
- Customer sends message → AI processes → gates pass → reply sent ✓
- Customer sends problematic message → AI processes → gates fail → retry → still fail → escalate
- Escalation appears in your inbox with reason and conversation history
- You review the conversation and customer context
- You take over → AI pauses
- You reply → message sent via Pancake
- You resolve → escalation closed, or release → AI resumes
Real-Time Inbox
The dashboard inbox polls every 5 seconds for new escalations. Each escalation shows:
- Customer name and photo
- Last message preview
- Time since escalation
- Unread indicator
Click to open the full conversation thread.
Customer Context in Escalation
When you take over, you see:
- 4-layer memory — Customer identity, history, mood, preferences
- Conversation history — All messages in this conversation
- Gate audit trail — Why gates failed (if applicable)
- Tool calls — Any tools the AI tried to use
- Previous escalations — History of this customer's escalations
Use this context to provide personalized, informed replies.
Multi-Agent Handoff
If you want to hand off to a colleague:
- Note in escalation — "Handing off to Linh for technical support"
- Mention in reply — "Linh sẽ tư vấn cho bạn tại đây..."
- Release to AI — If ready, release back to AI
Or coordinate outside the dashboard and manually update the takenOverBy field.
Error Responses
| Error | HTTP | Cause |
|---|---|---|
NOT_FOUND | 404 | Escalation does not exist |
CONFLICT | 409 | Already taken over by another agent |
INTERNAL_ERROR | 500 | Server error |