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

# Wallboard: supervisor real-time tiles for TV-mounted displays

> Mount the operations wallboard on a shared display, understand which data source populates each tile, and control the refresh and window it runs on.

# Wallboard: supervisor real-time tiles

The dashboard ships a full-screen **Wallboard** surface at **Voice → Wallboard** (and a cross-channel one at **Wallboard** in the top nav) that is designed to live on a shared display — a TV on the ops floor, an extra monitor at the supervisor desk. It cycles headline KPIs, queue health, live agent states, SLA warnings, and the top-performer leaderboard on a short rotation so nobody has to click anything to see the room.

This guide covers what each tile reads, how to scope the time window, which roles can see it, and how to mount it on a display.

## What the wallboard shows

The headline strip is built from real-time tiles, each colored by a health threshold (healthy / warning / critical, plus a neutral "no data" state when a metric has nothing to render instead of a misleading zero). What a supervisor sees:

* **Voice wallboard** (`/voice/wallboard`) — per-queue live figures: calls waiting, Average Wait, Service Level against your SLA target, Agents Available, Longest Wait, and a by-queue breakdown table. SLA-warning banners layer on top when a queue crosses its target, and predicted-CSAT escalation banners flag live calls trending toward escalation.
* **Omnichannel wallboard** (`/wallboard`) — message-level tiles (Messages Sent, Delivery Rate, Queue Depth, Active Agents, SLA Breaches, API/Messages volume) plus the unified cross-channel queue panel.
* Both surfaces also embed the **Top performers** leaderboard, sortable by calls handled, handle time, or CSAT.

## Data provenance — which feed fills each chip

Each chip is populated from a specific supervisor feed, so when a number looks off you know where to drill:

| Chip                                  | Source                                                                                                                       |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| Calls waiting / waits / service level | Live ACD queue state across every queue                                                                                      |
| Agents available / agent grid         | Live agent-state stream                                                                                                      |
| SLA warnings                          | The wallboard SLA warning feed on the on-call scheduler, which re-fires a warning while the breach condition persists        |
| Service Level target                  | The queue's configured SLA target (set per queue in **Voice → Queues**)                                                      |
| Top performers CSAT column            | Aggregate `AVG(csat_score)` over completed calls in the window — the same CSAT aggregate that feeds the supervisor scorecard |
| Latest evaluations                    | The quality evaluations feed — the same review pipeline a supervisor drills into from the leaderboard                        |

CSAT rows that have no score yet render as an explicit "—" rather than a fabricated 0, and the leaderboard row stays addressable so the supervisor can still click through.

## Time window

By default the leaderboard and the aggregate KPIs run over **today** (the local calendar day, resolved in the viewer's own timezone so "today" does not drift for a team split across timezones). You can pin a custom window:

* Leaderboard window picker: **today / 7d / 30d**. The server caps the range at 31 days; a wider request is shortened to 31 days, and an inverted range falls back to the last 24 hours.
* Over the API the window is `from` / `to` ISO timestamps on `GET /api/v1/voice/supervisor/agent-leaderboard`, so an ops screen can pin a specific shift or a rolling window instead of the picker defaults.

The wallboard streams updates over the live event channel and only polls as a fallback while that channel is down — a TV-mounted tab stays current without constant network hammering.

## Mounting it on a display

The page is built for a shared screen, and everything you need lives in the header:

* **Fullscreen** — press `F` or the fullscreen button to strip the browser chrome for TV mounting.
* **Cycle tiles** — the KPI strip auto-rotates through paginated tiles every 10 seconds, so every metric gets screen time without input.
* **Pause cycle** — press `Space` (or the pause button) to hold one page while reviewing. The paused state persists across refreshes on that display, so a TV tab does not silently resume cycling.
* **Navigate pages** — arrow keys step through tile pages manually.
* **Live clock** — a local-time clock in the header makes the page safe to leave on display (no stale "last updated" confusion).

Recommended mounting: a dedicated browser profile signed into a supervisor-level account on the TV or extra-large display, opened at the wallboard URL. Untrusted input (pressing Space in a search box, for example) is ignored, so casual keyboard use doesn't interrupt the board.

## Drill-down from a tile

Every number is a surface, not a dead end. From the leaderboard row, click through to the agent; from a SLA warning, to the queue; from a CSAT chip, to the underlying quality feed where the evaluations behind the aggregate live. The "peek is too shallow" problem is solved by always keeping the latest evaluations list one click away rather than trying to compress it into the chip.

## Permissions: who sees it

The wallboard surfaces are supervisor-scoped:

* Owner / admin / supervisor roles see the full org-wide view, including every queue and every agent row.
* A lower-privilege agent role sees a restricted view — on the leaderboard, only their own row; the response fails closed rather than leaking other agents' figures.

Sign the TV-mounted display into a supervisor-level account; the display then continues to render the full view even while shared.

## Endpoints

| Method | Path                                             | Purpose                                              |
| ------ | ------------------------------------------------ | ---------------------------------------------------- |
| `GET`  | `/api/v1/voice/supervisor/agent-leaderboard`     | Windowed top performers (calls / handle time / CSAT) |
| `GET`  | `/api/v1/voice/supervisor/omnichannel-wallboard` | Cross-channel unified queue state                    |
| `GET`  | `/api/v1/quality/evaluations/...`                | Latest evaluations feeding the CSAT drill-down       |

## Worked API examples

The two supervisor feeds that power the wallboard are plain GET endpoints under the same API key as the rest of the platform. The examples below use the Node SDK (`@devotel-orbit/node`); raw curl equivalents follow each one. They call the SDK's generic `request()` escape hatch rather than a typed helper, because these supervisor feeds ship ahead of the typed SDK surface.

### Agent leaderboard

Query parameters (all optional):

* `from` / `to` — ISO 8601 timestamps. Omit both for the default window (last 24 hours). The server shortens any window over 31 days to 31 days, and an inverted range falls back to the last 24 hours.
* `sort` — one of `calls_handled` (default), `avg_handle_seconds`, `avg_csat`.
* `limit` — 1–50, default 10.

```ts theme={null}
import { Orbit } from "@devotel-orbit/node";

const orbit = new Orbit({ apiKey: process.env.ORBIT_API_KEY! });

// Every request carries auth; the envelope { data, meta } is returned.
// Supervisor-level API keys see every agent. A key whose role is an
// agent (non-supervisor) fails closed: the server still returns 200,
// but rows contains only that agent's own entry — other agents'
// figures are never leaked.
const { data } = await orbit.request<LeaderboardResponse>(
  "GET",
  "/api/v1/voice/supervisor/agent-leaderboard?from=2026-08-22T00:00:00Z&to=2026-08-23T00:00:00Z&sort=calls_handled&limit=10",
);

for (const row of data.rows) {
  console.log(row.rank, row.display_name, row.calls_handled, row.avg_handle_seconds, row.avg_csat);
}
```

curl:

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/voice/supervisor/agent-leaderboard?from=2026-08-22T00:00:00Z&to=2026-08-23T00:00:00Z&sort=calls_handled&limit=10" \
  -H "X-API-Key: $ORBIT_API_KEY"
```

`200 OK` body (window pinned as the worked `from`/`to` above):

```json theme={null}
{
  "data": {
    "from": "2026-08-22T00:00:00.000Z",
    "to": "2026-08-23T00:00:00.000Z",
    "sort": "calls_handled",
    "rows": [
      {
        "rank": 1,
        "agent_id": "user_2kQ8x...",
        "display_name": "Amelia Okafor",
        "display_name_resolved": true,
        "avatar_url": "https://cdn.example/u/user_2kQ8x.png",
        "email": "amelia@example.com",
        "calls_handled": 47,
        "total_talk_seconds": 19832,
        "avg_handle_seconds": 422,
        "avg_csat": 4.81,
        "csat_response_count": 21
      },
      {
        "rank": 2,
        "agent_id": "user_3hTm4...",
        "display_name": "Jonas Weber",
        "display_name_resolved": true,
        "avatar_url": null,
        "email": "jonas@example.com",
        "calls_handled": 41,
        "total_talk_seconds": 16755,
        "avg_handle_seconds": 408,
        "avg_csat": null,
        "csat_response_count": 0
      }
    ],
    "metric_definitions": {
      "aht_seconds": {
        "key": "aht_seconds",
        "label": "Average Handle Time (talk-only)",
        "unit": "seconds",
        "formula": "total_talk_seconds / calls_handled",
        "description": "Mean talk time per call handled by this agent. Hold and wrap time are aggregated per queue interval, not per agent, so they are not included at this grain."
      }
    }
  },
  "meta": { "request_id": "req_01H...", "timestamp": "2026-08-23T08:11:12Z" }
}
```

`avg_csat` is `null` when an agent has no CSAT responses in the window — render "—", not 0. `avg_handle_seconds` counts talk time only, matching the per-queue leaderboard the CSAT/value columns aggregate.

### Omnichannel wallboard

One live snapshot; no query parameters.

```ts theme={null}
const { data } = await orbit.request<WallboardResponse>(
  "GET",
  "/api/v1/voice/supervisor/omnichannel-wallboard",
);

console.log(data.voice.active_calls, data.totals.live_interactions);
```

curl:

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/voice/supervisor/omnichannel-wallboard" \
  -H "X-API-Key: $ORBIT_API_KEY"
```

`200 OK` body:

```json theme={null}
{
  "data": {
    "digital_channels": [
      {
        "channel": "chat",
        "live": 35,
        "unassigned": 4,
        "assigned": 31,
        "awaiting_response": 6,
        "waiting": 8,
        "longest_wait_seconds": 421
      },
      {
        "channel": "whatsapp",
        "live": 12,
        "unassigned": 2,
        "assigned": 10,
        "awaiting_response": 2,
        "waiting": 3,
        "longest_wait_seconds": 240
      }
    ],
    "voice": {
      "agents_available": 12,
      "agents_on_call": 8,
      "agents_wrap_up": 1,
      "agents_online": 24,
      "active_calls": 9
    },
    "totals": {
      "live_interactions": 56,
      "agents_online": 24,
      "unassigned": 6,
      "longest_wait_seconds": 421
    },
    "generated_at": "2026-08-23T08:11:12.000Z"
  },
  "meta": { "request_id": "req_01H...", "timestamp": "2026-08-23T08:11:12Z" }
}
```

Per channel, `unassigned + assigned` always equals `live`. `awaiting_response` counts only threads already assigned to an agent that are still waiting for that agent's first reply, so the breakdown never sums to more than `live`; `longest_wait_seconds` is the oldest genuinely waiting thread — assigned or not. Poll on a short cadence (the wallboard page itself worsens to a 5s+ poll only when the live event channel is unavailable).

## See also

* [Voice](/voice) — queues, SLA targets, and the live agent grid the wallboard reads
* [Quality](/api-reference/quality) — the scorecard and evaluation pipeline the CSAT chips aggregate
* [QA workload management](/guides/qa-workload-management) — workload quotas and due dates for the evaluations surfaced here
* [On-call alerting](/guides/oncall-alerting) — the on-call warning feed the SLA banners ride on
