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

# Handoff portal

> An on-demand AI brief for a human taking over a call.

The handoff portal is a single-screen brief that summarizes a caller's most recent conversation so a human agent can take over with full context. It is built on demand from the latest conversation matching a phone number and is never stored — every load generates a fresh analysis.

The portal is backed by `GET /core/agent-assist/{phone_number}`. The page is deep-link only: it has no entry in the sidebar, so you reach it by opening a direct link (for example from a transfer notification or another tool).

## How it works

When you open the portal, the backend finds the most recent conversation whose caller id (`user_id`) matches `phone_number`, ordered by `created_at` descending. It does not require the call to be live — it analyzes whichever conversation is newest for that number. If no conversation matches, the request returns `404` and the page shows a **Not Found** message.

```
GET /core/agent-assist/{phone_number}
        │
        ▼
  latest conversation for user_id == phone_number
  (order by created_at desc, limit 1)
        │
        ├── none found ─────────────► 404 Not Found
        │
        ▼
  build brief from transcript + metadata
        │
        ▼
  AgentAssistPortal (returned, not persisted)
```

<Note>
  The brief is generated fresh on every request and is not saved anywhere. Reloading the page re-runs the analysis, so the result can vary slightly between loads.
</Note>

## What the brief contains

The response is an `AgentAssistPortal` object with seven sections.

| Section                 | Type             | Description                                                      |
| ----------------------- | ---------------- | ---------------------------------------------------------------- |
| `header`                | object           | Caller name, phone number, call duration, and overall sentiment. |
| `transfer_reason`       | string           | A concise explanation of why the call needs a human.             |
| `call_summary`          | array of strings | A short bulleted summary of the conversation (3–5 points).       |
| `information_collected` | array            | Key/value pairs of details gathered during the call.             |
| `suggested_next_steps`  | array            | 1–3 recommended actions, each with a confidence level.           |
| `transcript`            | array            | The full conversation with markers on notable moments.           |
| `compliance_flags`      | array            | Compliance concerns, empty when there are none.                  |

### Header

| Field                   | Type            | Description                                            |
| ----------------------- | --------------- | ------------------------------------------------------ |
| `caller_name`           | string          | The caller's name, or `Unknown Caller` when not found. |
| `phone_number`          | string          | The caller's phone number.                             |
| `call_duration_seconds` | integer or null | Call length in seconds; `null` when unknown.           |
| `sentiment`             | object          | Overall caller sentiment (see below).                  |

`sentiment` has a human-readable `label` and a `level` from a fixed enum:

| `level`               | Meaning                     |
| --------------------- | --------------------------- |
| `calm`                | No frustration detected.    |
| `slightly_frustrated` | Early signs of frustration. |
| `frustrated`          | Clearly frustrated.         |
| `angry`               | Angry.                      |
| `escalated`           | Escalated.                  |

### Information collected

Each item is a `{ key, value }` pair, for example an account number or issue detail. The UI renders these as a two-column table.

### Suggested next steps

Each step has an `action` and a `confidence` of `high`, `medium`, or `low`.

### Annotated transcript

Each transcript entry has a `role` (`user` or `assistant`), the message `content`, and a list of `markers`. A marker has a `type` and a `description` highlighting why that moment matters. Marker types include:

| `type`               | What it flags                              |
| -------------------- | ------------------------------------------ |
| `frustration`        | The caller shows frustration or anger.     |
| `identity_verified`  | The caller's identity was verified.        |
| `ai_commitment`      | The AI made a promise or commitment.       |
| `escalation_trigger` | Something triggered escalation to a human. |
| `key_info`           | Important information was shared.          |
| `sentiment_shift`    | A noticeable change in caller sentiment.   |

### Compliance flags

Each flag has a `type` and a `description`. The list is empty when no concerns are found. Flags cover issues such as sensitive data shared without verification, promises that may not be fulfillable, and unmet regulatory requirements.

## Access

The endpoint requires the `conversations:read_sensitive` scope. Because the brief exposes the full transcript and collected details, it is gated behind sensitive-conversation access rather than ordinary read access.

```bash theme={null}
curl https://api.anyreach.ai/core/agent-assist/+15551234567 \
  -H "Authorization: Bearer <token>" \
  -H "X-Anyreach-Org: <organization_id>"
```

<Note>
  User PATs (`pat_`) also need the `X-Anyreach-Org` header. Org API keys (`ak_`) carry their organization implicitly and omit it.
</Note>

## Related

<CardGroup cols={2}>
  <Card title="Agent Assist overview" icon="headset" href="/agent-assist/overview">
    How Agent Assist fits into live and post-call handoffs.
  </Card>

  <Card title="Conversation detail" icon="message-lines" href="/conversations/conversation-detail">
    The persisted record of a single conversation, including its transcript.
  </Card>
</CardGroup>
