These events cover the transition moments in the support flow — when the AI agent determines a human is needed, when the human actually takes over, and when a conversation is transferred between agents. Use them to track handoff time, measure AI triage quality, and monitor support queues.
Event list
| Event | When it fires |
|---|
agent.handoff_started | The AI agent signals it wants to hand control to a human |
agent.handoff_completed | A human agent effectively takes over the conversation |
agent.transferred | The conversation is transferred from one agent to another |
agent.handoff_started
When it fires
The AI agent detects the situation requires human intervention — this can be triggered by a configured transfer rule (e.g., customer requesting a human, a keyword detected, maximum resolution attempts reached) or by an autonomous model decision.
At this point, the conversation enters a waiting queue for an agent, but the AI agent is still in control.
Payload
{
"event": "agent.handoff_started",
"event_id": "evt_01HX6A1K9MFQR4YZDNV7P9WCE",
"timestamp": "2026-04-19T14:45:00Z",
"workspace_id": "ws_abc123",
"data": {
"conversation_id": "conv_01HX3B2K",
"contact_id": "cont_456",
"channel_id": "chan_789",
"channel_type": "whatsapp",
"agent_id": "agt_101",
"handoff_reason": "user_requested",
"handoff_note": "Cliente pediu explicitamente para falar com atendente",
"queue_id": "queue_sales",
"started_at": "2026-04-19T14:45:00Z"
}
}
Key fields
| Field | Type | Description |
|---|
agent_id | string | ID of the AI agent that initiated the handoff |
handoff_reason | enum | user_requested, rule_triggered, max_attempts, sentiment_negative, autonomous |
handoff_note | string | null | Context generated by the agent about the reason |
queue_id | string | null | ID of the support queue where the conversation was enqueued |
started_at | string | ISO 8601 timestamp of handoff start |
Usage example
Use handoff_started with handoff_reason to measure handoff volume by reason. A high number of autonomous handoffs may indicate the agent is not sufficiently trained for a particular topic.
agent.handoff_completed
When it fires
A human agent accepts (or is assigned to) a conversation that was in handoff. From this point on, the AI agent stops responding automatically and the human agent is in control.
Payload
{
"event": "agent.handoff_completed",
"event_id": "evt_01HX6B3M2PGTS6YADOV8Q1XDF",
"timestamp": "2026-04-19T14:47:30Z",
"workspace_id": "ws_abc123",
"data": {
"conversation_id": "conv_01HX3B2K",
"contact_id": "cont_456",
"channel_id": "chan_789",
"channel_type": "whatsapp",
"agent_id": "agt_101",
"attendant_id": "usr_321",
"handoff_wait_seconds": 150,
"handoff_note": "Cliente pediu explicitamente para falar com atendente",
"completed_at": "2026-04-19T14:47:30Z"
}
}
Key fields
| Field | Type | Description |
|---|
agent_id | string | ID of the AI agent that initiated the handoff |
attendant_id | string | ID of the human agent who took over |
handoff_wait_seconds | integer | Time in seconds between handoff_started and handoff_completed |
handoff_note | string | null | Context passed by the agent to the attendant |
completed_at | string | ISO 8601 timestamp of handoff completion |
Usage example
Calculate the handoff SLA with handoff_wait_seconds. If this value is high during peak hours, consider expanding the team or adjusting queue routing rules.
agent.transferred
When it fires
A conversation already with a human agent is transferred to another agent. This can be a manual transfer (the agent chooses to pass it on) or an automatic one triggered by a department rule.
Payload
{
"event": "agent.transferred",
"event_id": "evt_01HX6C5P4RHTW7ZBEPV9S2YEG",
"timestamp": "2026-04-19T15:05:00Z",
"workspace_id": "ws_abc123",
"data": {
"conversation_id": "conv_01HX3B2K",
"contact_id": "cont_456",
"channel_id": "chan_789",
"channel_type": "whatsapp",
"from_attendant_id": "usr_321",
"to_attendant_id": "usr_654",
"transfer_reason": "manual",
"transfer_note": "Encaminhando para o time financeiro",
"transferred_at": "2026-04-19T15:05:00Z"
}
}
Key fields
| Field | Type | Description |
|---|
from_attendant_id | string | ID of the agent who transferred |
to_attendant_id | string | ID of the agent who received |
transfer_reason | enum | manual, rule, api |
transfer_note | string | null | Agent’s note about the reason for the transfer |
transferred_at | string | ISO 8601 timestamp of the transfer |
Usage example
Track agent.transferred to identify bottlenecks. If the same agent always transfers to the same colleague, the routing queue may need to be adjusted to direct those contacts correctly from the start.
Transitions from AI agent to human generate handoff_started + handoff_completed. Human-to-human transfers generate only agent.transferred. Do not confuse the two flows when building reports.