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

# handoff_request

> Escalate the conversation to a human or sibling agent via a configured channel.

# handoff\_request

Escalates the conversation to a human (email, Telegram, Slack, Discord, WhatsApp, owner inbox) or to a sibling agent via one of the agent's configured handoff channels.

The model chooses `channel_id` from the agent's currently-configured handoff channels (also listed in the tool description). The input schema constrains `channel_id` to currently-available ids so the model can't invent one.

After a successful call, the next subscriber turn is *bypassed*: messages route directly to the recipient until the session is released (form submission, `/release` token, sibling-agent `handoff_release`, or 30-minute idle timeout).

## Parameters

| Name                 | Type                                                   | Required | Description                                                       |
| -------------------- | ------------------------------------------------------ | -------- | ----------------------------------------------------------------- |
| `channel_id`         | integer                                                | yes      | Must match one of the agent's configured handoff channels.        |
| `summary`            | string (20-2000)                                       | yes      | What's happening, who the user is, what they need.                |
| `expected_action`    | string (10-1000)                                       | yes      | The concrete next step you want the recipient to take.            |
| `urgency`            | `"low"` \| `"normal"` \| `"high"`                      | no       | Default `"normal"`.                                               |
| `contact_back_email` | string (email)                                         | no       | Defaults to the subscriber's email when known.                    |
| `include_transcript` | boolean                                                | no       | Default `true`. Attaches the recent conversation transcript.      |
| `extra_context`      | record\<string,string>                                 | no       | Up to \~4KB of structured key/value context.                      |
| `expected_return`    | array of [HandoffReturnField](#expected_return-schema) | no       | Structured contract for the data you want filled at release time. |

## `expected_return` schema

A list of up to 20 fields the recipient (human form or sibling agent) is asked to fill before releasing the handoff. Each field:

```json theme={null}
{
  "name": "order_status",
  "type": "enum",
  "enum_values": ["shipped", "delayed", "lost", "not_found"],
  "label": "Order status",
  "description": "Where the order currently is.",
  "required": true,
  "placeholder": "shipped"
}
```

Supported `type` values: `string`, `multiline`, `number`, `boolean`, `enum`, `date`, `url`.

**Validation is best-effort.** Missing `required` fields are logged into the audit trail but do NOT block the release; the originator's LLM sees what came back and what was missing on its next turn.

### How the recipient fills it

* **Human via email / Telegram / Slack / Discord / WhatsApp** — the dispatch body includes a time-limited link to a return form (one input per field, typed per `type`) plus a plain-text preview of the fields. The recipient can forward the link to a colleague.
* **Owner via Inbox** — the same link surfaces as a "Fill return form" button on the active-handoff status strip.
* **Sibling agent** — the schema is rendered into the receiving agent's initial context as an `[EXPECTED RETURN SCHEMA]` block. It calls [`handoff_release`](./handoff_release) with `return_values: { … }`.

### How the values come back to you

After release, the originator's chat gets a `[Bot resumed — …]` system message. When `expected_return` was set, that message includes a `Returned data:` block with the filled values, e.g.:

```
[Bot resumed — the sibling agent has handed control back. Outcome: resolved. Looked up order 1234.]
Returned data:
  • order_status: shipped
  • tracking_url: https://carrier.example/track/abc
  • eta_date: 2026-06-10
```

The originator's LLM reads this on its next turn. Use the values directly — don't paraphrase the field names.

## Returns

On success:

```json theme={null}
{
  "ok": true,
  "action": "handoff_session_started",
  "channel_kind": "email" | "telegram" | "slack" | "discord" | "whatsapp" | "owner_inbox" | "agent",
  "channel_id": 12,
  "channel_label": "Sales support",
  "channel_message_id": "<provider id, if any>",
  "estimated_response": "within 1 business day",
  "handoff_event_id": "...",
  "handoff_session_id": "...",
  "human_notified": true
}
```

On dispatch failure: `{ error, details: { handoff_event_id, hint, ... } }` — the session is marked failed and the bypass is NOT activated.

## Call from your own custom tool

```js theme={null}
export async function handle(input, ctx) {
  return await ctx.tools.handoff_request({
    channel_id: input.channel_id,
    summary: `Visitor needs help with order #${input.order_id}: ${input.issue}`,
    expected_action: 'Look up the order status and reply with shipping/delivery details.',
    urgency: 'high',
    contact_back_email: input.email,
    expected_return: [
      { name: 'order_status', type: 'enum', enum_values: ['shipped','delayed','lost','not_found'], required: true },
      { name: 'tracking_url', type: 'url' },
      { name: 'eta_date',     type: 'date' },
      { name: 'notes',        type: 'multiline' },
    ],
  });
}
```

## Notes

* Only registered when at least one handoff channel is available.
* Each handoff is delivered through the configured channel (email, Telegram, Slack, Discord, WhatsApp, the owner Inbox, or a sibling agent).
* Every attempt (success or failure) is recorded for the audit trail. `human_notified` is `true` only when dispatch succeeded.
* The LLM cannot fake a handoff: success requires the dispatcher to return ok.
