> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rovax.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent events

> Triggered during control transitions between AI agent and human agent, and on transfers between agents

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

```json theme={null}
{
  "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

<Note>
  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.
</Note>

***

## `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

```json theme={null}
{
  "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

<Tip>
  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.
</Tip>

***

## `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

```json theme={null}
{
  "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

<Note>
  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.
</Note>

<Warning>
  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.
</Warning>
