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

# Survey scorecards: queue- and agent-level CSAT/NPS rollups

> Read the cross-cutting post-call survey scorecards — every queue or every agent ranked by response volume — and turn a CSAT dip into a QA review, a coaching plan, and a ledger entry.

# Survey scorecards

The per-survey analytics covered in [post-call CSAT and NPS surveys](/guides/post-call-surveys) tell you how one survey performs. Scorecards answer the next question: *across every queue, or every agent, who got the answers, and were they high?* One endpoint buckets every answered post-call survey response by the queue the call was attributed to or by the handling agent, and returns the same scoring rubric per bucket: satisfaction percentage, average score, and NPS, ranked by response volume.

Read it from a wallboard, a weekly export, or a supervisor's dashboard and you get the ranking the QA review loop and incentive programs need. The endpoint is `GET /api/v1/surveys/scorecards`; the scoring vocabulary matches the voice CSAT analytics exactly, so a number in this guide and a number there never disagree.

## 1. What survey scorecards measure

A scorecard row is one queue (or one agent), summarizing every answered post-call survey response in the window:

| Field              | What it is                                                                                                                  |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------- |
| `key`              | The bucket — queue id with `group_by=queue`, agent user id with `group_by=agent`.                                           |
| `responses`        | Answered responses in the bucket.                                                                                           |
| `satisfied_count`  | Responses at score `4` or `5` (top-two-box) on the CSAT scale.                                                              |
| `satisfaction_pct` | Share of answers at score `4` or `5`, as a whole percentage.                                                                |
| `avg_score`        | Mean answer, two decimals.                                                                                                  |
| `csat_avg_score`   | Mean over CSAT answers only — the CSAT (`1`–`5`) and NPS (`0`–`10`) scales are never blended into a meaningless mixed mean. |
| `nps`              | Promoters (`9`–`10`) minus detractors (`0`–`6`) over NPS answers only, on the −100 to +100 scale.                           |
| `nps_responses`    | How many NPS answers fed that figure.                                                                                       |

That is the whole scoring rubric: the rubric is fixed by the platform, and both groupings — queue and agent — use the same fields, so queue-level and agent-level reads compare like for like. Rows rank by descending `responses`, so a supervisor reads the busiest queue or agent first.

Two handling rules keep the board honest:

* **Only answered responses count.** A bucket appears once it has at least one responded-at answer with a valid score (`1`–`5` CSAT or `0`–`10` NPS); sent-but-unanswered surveys never surface as zero rows.
* **Empty buckets return null, not zero.** A bucket with no answers in the window returns null percentages rather than `0`, so an empty export never reads as "scored zero".

## 2. Aggregation and the time window

The default read covers everything in the account — one row per queue, ranked by volume:

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/surveys/scorecards?group_by=queue" \
  -H "X-API-Key: $ORBIT_API_KEY"
```

Bound the window and narrow the set with query params:

| Query param                    | Effect                                                                                                                                                                |
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `group_by=queue\|agent`        | Bucket dimension (default `queue`).                                                                                                                                   |
| `survey_type=csat\|nps\|all`   | Restrict the rollup to one scale (default `all`). When filtering to `csat`, NPS fields go null; `nps` likewise nulls the CSAT average on buckets with no NPS answers. |
| `queue_id=` / `agent_user_id=` | Narrow to a single bucket; only meaningful alongside the matching `group_by`.                                                                                         |
| `from=` / `to=`                | ISO timestamp bounds on the response time. `from` is inclusive, `to` is exclusive; omitting both means "all time".                                                    |
| `limit=` / `offset=`           | Page the bucket list (1–200 per page, default 50).                                                                                                                    |

Malformed values never 5xx the read: an invalid filter degrades back to the unfiltered scorecard, and a queue or agent id from outside your account returns an empty list rather than an error. That makes the endpoint safe to poll on a timer from a wallboard or a scheduled export script.

Unlike a weekly job, the rollup computes on read: open it with a `from=` of last Monday and the board reflects the data you actually have, not a snapshot that stopped updating at midnight.

## 3. Connecting surveys to scorecards for a QA review loop

Scorecards sit downstream of the post-call survey and upstream of quality review. The link is attribution: each answered response records the survey id, the call id, and — when the platform resolves it — the handling agent. The queue grouping joins through the call's queue stamp, the agent grouping reads the response's agent stamp directly.

The review loop works against either grouping:

1. **Scorecards flag the bucket.** A queue's `satisfaction_pct` falls, or an agent's `avg_score` trails the team.
2. **Evaluate the calls behind the number.** Queue the low-scoring calls into QA evaluation — [QA workload management](/guides/qa-workload-management) assigns specific calls to specific evaluators so the review is not left up for grabs, while the continuous sampler and CSAT-triggered reviews cover the routine flow. A detractor answer against a known agent already queues a QA evaluation on that exact interaction; scorecards tell you where the pattern is before individual triggers fire.
3. **Coaching closes it.** [Voice coaching plans](/guides/voice-coaching-plans) turn the reviewed pattern into a plan for the agent, and the very-low band can assign a plan automatically.

Because both the QS evaluation trigger and the scorecard rollup key on the same agent attribution stamp, a dip you spot on the agent scorecard names someone the QA pipeline can already reach.

## 4. Queue-level vs agent-level

Pick the grouping to match the question:

* **Queue-level** (`group_by=queue`) answers "which team/product line carries the dip?" — the rollup groups on the queue the answered call was attributed to, and queues with no answered responses drop out of the list entirely.
* **Agent-level** (`group_by=agent`) answers "who inside that queue needs attention?" — the rollup groups on the handling agent recorded at answer time; responses the platform could not attribute to an agent never enter the board.

An agent with calls but no survey answers still appears on the per-queue leaderboard view (null average rather than dropping out, per the per-queue analytics in [post-call surveys](/guides/post-call-surveys)); the cross-cutting scorecard endpoint deliberately shows only buckets that have answers. Read the two together: leaderboard for "who has un-surveyed volume", scorecard for "among the surveyed, who scored".

## 5. Feeding scorecards into incentives and coaching

A scorecard row is a stable, API-readable figure, which makes it the input that reward and coaching programs repeat against:

* **Incentives.** The [incentives ledger](/guides/incentives-ledger) mints one-off rewards and audits their lifecycle; supervisors typically gate a "CSAT champion" recognition on the scorecard ranking, then issue the reward from the console. Because the scorecard returns nulls for empty buckets, an agent with zero answered surveys never receives a reward minted on a zero-average misread.
* **Coaching.** Pair the scorecard dip with the per-agent drill-down (`?agent_user_id=` on the same endpoint, or the `agent-leaderboard` endpoint scoped to one queue) to pick the calls that drive a [coaching plan](/guides/voice-coaching-plans). Track the same agent-level scorecard across coaching windows to see the plan land — a rising `satisfaction_pct` on the same window bounds the review.

Keep the rubric consistent: if your incentive rule says "top-two-box at 85%", use the scorecard's `satisfaction_pct` rather than recomputing from raw responses, so the audit trail and the payout read the same number.

## 6. Worked example: a queue's CSAT dip to a coaching plan

A supervisor polls the queue scorecard every Monday for the support queue's window:

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/surveys/scorecards?group_by=queue&queue_id=$SUPPORT_QUEUE_ID&from=2026-08-24T00:00:00Z&to=2026-08-31T00:00:00Z" \
  -H "X-API-Key: $ORBIT_API_KEY"
```

```json theme={null}
{
  "data": {
    "group_by": "queue",
    "survey_type": "all",
    "scorecards": [
      {
        "key": "q_support",
        "responses": 86,
        "satisfied_count": 51,
        "satisfaction_pct": 59,
        "avg_score": 3.4,
        "csat_avg_score": 3.4,
        "nps": -8,
        "nps_responses": 34
      }
    ],
    "pagination": { "limit": 50, "offset": 0 }
  }
}
```

Fifty-nine percent here, and the comparison view across all queues shows the support queue trailing its 82% baseline — a real dip, not a zero-sample artifact. The supervisor drills to agent level:

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/surveys/scorecards?group_by=agent&from=2026-08-24T00:00:00Z&to=2026-08-31T00:00:00Z" \
  -H "X-API-Key: $ORBIT_API_KEY"
```

Two agents carry the dip: `satisfaction_pct` of 41% and 48% against a team median of 78%. The supervisor assigns their low-scoring calls to evaluators through the workload flow, the QA review tags a missed-verification pattern, and a coaching plan opens for each agent. Four weeks into the plan the same agent-level read shows both agents back above the team median, and the queue scorecard returns to baseline. The incentive rule pays the "back above baseline" recognition from the ledger with the scorecard row quoted as the source figure.

## Endpoints

| Method | Path                         | Purpose                                                          |
| ------ | ---------------------------- | ---------------------------------------------------------------- |
| `GET`  | `/api/v1/surveys/scorecards` | Queue- or agent-level CSAT/NPS rollup, ranked by response volume |

## See also

* [Post-call CSAT and NPS surveys](/guides/post-call-surveys) — survey capture, per-survey analytics, and the per-queue leaderboard these scorecards extend
* [QA workload management](/guides/qa-workload-management) — assign the calls behind a dip to evaluators with quotas and due dates
* [Voice coaching plans](/guides/voice-coaching-plans) — turn a reviewed pattern into an agent-facing plan
* [Run the incentives ledger](/guides/incentives-ledger) — issue recognition rewards against the scorecard ranking
