# Handoff events

> handoff.requested and handoff.resolved, fired when a visitor wants a person

Source: https://www.hey.support/docs/developer-guide/webhooks/events/handoff

---

Two events follow a request for a person from the moment it is made to the moment it stops being open. The envelope is described in the [overview](/docs/developer-guide/webhooks).

## `handoff.requested`

Fires when a visitor asks for a human, whether they tapped the handoff card or the agent offered it after failing to answer. Every field under `visitor` can be `null`; which fields are collected is configured per agent.

```json
{
  "conversation_id": 8214,
  "chatbot_id": 17,
  "channel": "live_chat",
  "visitor": {
    "visitor_id": "v_9f21…",
    "name": "Ada Lovelace",
    "email": "ada@example.com",
    "phone": null,
    "company": null,
    "message": "I need to change my order"
  },
  "requested_at": "2026-08-26T10:07:00.000Z"
}
```

`channel` is the field that matters:

| `channel`   | Meaning                                                                                                                                        |
| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `live_chat` | Someone is being paged and the visitor is waiting in the widget right now. This is urgent.                                                     |
| `email`     | Nobody is being paged: the workspace is outside its hours, or live chat is not on its plan. The visitor has been told a person will follow up. |

Treat them differently. Routing an `email` handoff to a pager wakes someone for a message that expects a reply tomorrow; treating a `live_chat` one as an email leaves a visitor waiting in an open widget.

## `handoff.resolved`

Fires when a request for a person stops being open: an operator's live chat ends, an operator declines the request, or the conversation is closed while the request is still waiting.

```json
{
  "conversation_id": 8214,
  "chatbot_id": 17,
  "previous_status": "pending_handoff",
  "resolved_at": "2026-08-26T10:31:00.000Z",
  "outcome": "declined"
}
```

`outcome` is present only when nobody joined:

| `outcome`  | Meaning                                                                                                                                                                                                        |
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `declined` | An operator declined the request. The visitor was told that no one is free, and the AI carried on in the same conversation.                                                                                    |
| `closed`   | The conversation was resolved, archived or ended by the visitor while the request was still waiting, so nobody ever picked it up. Fires for waiting requests of every kind, including `channel: "email"` ones. |
| absent     | An operator joined and finished the conversation. `previous_status` is `human_active`.                                                                                                                         |

A rising count of `declined` and `closed` outcomes is a staffing signal, not a success metric.

<Accordions>
  <Accordion title="The five-minute fallback does not fire this event">
    When nobody joins within five minutes, the AI steps back in and tells the visitor so, but the request stays open in the Inbox and someone can still take it over. `handoff.resolved` fires when that request is eventually taken and finished, declined, or closed.
  </Accordion>

  <Accordion title="Ordinary conversations">
    `handoff.resolved` only fires for conversations that asked for a person. An ordinary conversation being resolved fires [`conversation.ended`](/docs/developer-guide/webhooks/events/conversation) alone.
  </Accordion>
</Accordions>

<NextSteps>
  <IconCard icon="webhook" title="Webhooks overview" href="/docs/developer-guide/webhooks" description="The envelope, the headers and every event." />

  <IconCard icon="key-round" title="Verifying signatures" href="/docs/developer-guide/webhooks/signature" description="Check the HMAC before you act on a delivery." />
</NextSteps>
