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

# Supervisor live monitoring for voice calls: listen, whisper, barge

> Give supervisors real-time controls over active phone calls — listen silently, coach the agent with whisper, join with barge or a three-way conference — plus a read-back API that answers who is monitoring which call right now.

# Live monitoring for voice calls

Post-call scorecards tell you how an agent handled a call after it ended. Live monitoring gives the supervisor control while the caller is still on the line. On voice there are five actions, each with a distinct audit action so compliance can tell them apart:

* **Listen** — the supervisor hears agent and caller; nobody hears the supervisor. This is silent monitoring.
* **Whisper** — the supervisor speaks to the handling agent only. The caller never hears the coaching.
* **Barge** — the supervisor speaks to both parties. Use it for a short, transient escalation.
* **Conference join** — a three-way call. The supervisor stays as an audible third participant for the rest of the call (the "consult and conference" pattern), typically after a barge that needs a longer presence.
* **Unlisten** — end the supervisor's session on the call.

Every start and stop is written to a per-tenant audit ledger with the supervisor, the agent, the call, the action, and timestamps — so "who listened to call X and when" is always answerable, and the same ledger powers the "currently being monitored" badge in your dashboards.

## Prerequisites

* The caller is owner, admin, or supervisor in the workspace. Any other role gets `403`.
* The supervisor has an open softphone session — the monitoring actions redirect the supervisor's existing call leg into the call's bridge. Post the supervisor's softphone call id as `supervisorCallControlId`.
* The target call is live. Monitoring a finished call returns an error rather than a stale bridge.

## Listen (silent monitoring)

```bash theme={null}
curl -X POST https://orbit.devotel.io/api/v1/voice/calls/call_123/listen \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"supervisorCallControlId": "sup_call_9"}'
```

The supervisor leg joins the call muted. Neither party is notified — listening is the only action with no audio exposure to the caller, so no announcement plays. For a per-call, first-class silent-monitor action that shows up separately in compliance reports (labour-relations or two-party-consent ledgers often distinguish passive observation from coaching), use the dedicated surface:

```bash theme={null}
curl -X POST https://orbit.devotel.io/api/v1/voice/supervisor/calls/call_123/monitor \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"supervisorCallControlId": "sup_call_9", "mode": "listen"}'
```

For random QA sampling across a team without picking a specific call in advance, `POST /api/v1/voice/supervisor/team-monitor` selects one active call from the team's agents and opens a listen session on it.

## Whisper (coach the agent only)

```bash theme={null}
curl -X POST https://orbit.devotel.io/api/v1/voice/calls/call_123/whisper \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"supervisorCallControlId": "sup_call_9"}'
```

The supervisor's audio routes to the agent only. Whisper requires the call to have an identified agent leg — when the platform cannot resolve one, the request returns `422 INVALID_STATE` instead of silently degrading to an audible join.

## Barge (speak to both parties)

```bash theme={null}
curl -X POST https://orbit.devotel.io/api/v1/voice/calls/call_123/barge \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "supervisorCallControlId": "sup_call_9",
    "disclosure": { "enabled": true }
  }'
```

Because the supervisor becomes audible to the caller, barge supports an explicit audible disclosure. With `disclosure.enabled: true`, an announcement plays on the supervisor's leg before the join and on the agent's leg after the join, so the caller hears the disclosure through the call audio. Pass `disclosure.text` to use your own wording (bounded to 240 characters); omit it and a neutral default is used: *"Please note: a supervisor has joined this call for quality and support purposes."* Listening never triggers a disclosure; whisper and barge only play one when you set `disclosure.enabled`, so existing integrations that post just the supervisor call id keep their current behaviour.

## Conference join (three-way, persistent)

```bash theme={null}
curl -X POST https://orbit.devotel.io/api/v1/voice/calls/call_123/conference-join \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"supervisorCallControlId": "sup_call_9"}'
```

The supervisor joins as a third audible participant and stays. Because this exposes the supervisor's audio to the caller for the whole conversation, the disclosure announcement is always played for a conference join — unlike barge, it is not opt-in.

## Stop monitoring

```bash theme={null}
curl -X POST https://orbit.devotel.io/api/v1/voice/calls/call_123/unlisten \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"supervisorCallControlId": "sup_call_9"}'
```

The supervisor leg is dropped. Stopping is idempotent — if the leg is already gone the stop still records a closing entry, so the ledger never shows a session that appears to run forever.

## Read back who is monitoring

The read side of the ledger is a single endpoint:

```bash theme={null}
curl https://orbit.devotel.io/api/v1/voice/supervisor/monitor-sessions?open_only=1 \
  -H "X-API-Key: dv_live_sk_your_key_here"
```

```json theme={null}
{
  "items": [
    {
      "id": "9271c5c4-9d6b-4d0d-8cf2-3f0e2a1c4f20",
      "call_id": "call_123",
      "supervisor_user_id": "user_2xSup",
      "agent_user_id": "user_7qAgent",
      "action": "whisper",
      "details": { "disclosure": true },
      "started_at": "2026-08-25T14:03:11.000000+00:00",
      "ended_at": null,
      "open": true
    }
  ],
  "next_cursor": null,
  "limit": 50
}
```

All filters are optional and compose:

| Query param          | Effect                                                                                            |
| -------------------- | ------------------------------------------------------------------------------------------------- |
| `open_only=1`        | Only sessions in progress right now (`ended_at` is empty) — the input for a "monitored NOW" badge |
| `call_id`            | Every supervisor action on one call, newest first                                                 |
| `supervisor_user_id` | Sessions by one supervisor                                                                        |
| `agent_user_id`      | Sessions targeting one agent                                                                      |
| `action`             | One of `listen`, `whisper`, `barge`, `coach`, `monitor`, `unlisten`                               |
| `limit`              | Page size, 1–200 (default 50)                                                                     |
| `cursor`             | Opaque page cursor from a previous `next_cursor`                                                  |

Each row carries the pre-computed `open` boolean (`true` while `ended_at` is empty) so dashboards never re-derive the live state. A page that returns `next_cursor` has more rows; pass the cursor back as `?cursor=` to continue. An empty result is `200` with `items: []` — a workspace with no monitoring is a valid answer, not an error.

Access is limited to owner, admin, and supervisor roles, and every query is scoped to your own workspace — a supervisor can never read across tenants.

## Common failure codes

| Status | Code                           | What it means                                              |
| ------ | ------------------------------ | ---------------------------------------------------------- |
| 422    | `INVALID_STATE`                | Whisper requested but the call has no resolvable agent leg |
| 403    | —                              | Caller is not owner, admin, or supervisor                  |
| 404    | `NOT_FOUND`                    | The call id does not exist in this workspace               |
| 500    | `MONITOR_SESSIONS_LIST_FAILED` | Read-back of the ledger failed; retry                      |
