Reports & QA
Purpose
Section titled “Purpose”Describe the reporting endpoints, scheduled report delivery, CSV export, and the QA (quality assurance) scorecard/evaluation system.
Overview
Section titled “Overview”The control plane exposes five read-only reports under /api/v1/reports, all
requiring supervisor or above, all accepting an optional ?from/?to
RFC3339 window and ?format=csv, and all honoring a platform_admin’s
?tenant_id override:
| Report | Returns |
|---|---|
campaigns |
Per-campaign funnel: attempts, leads dialed, human/machine, sales, abandoned, plus contact/conversion/abandonment rates |
agents |
Per-agent calls, talk time, time-in-state, occupancy, and QA averages |
call-volume |
CDR volume + telephony quality (ASR, ACD, daily trend, top hangup causes) |
compliance |
DNC totals/additions, abandonment-vs-cap breaches, calling-hours coverage |
dispositions |
Tenant-wide disposition breakdown by code |
Configuration
Section titled “Configuration”Key metric formulas (all percentages rounded to 2 decimals, 0 when the denominator is 0):
contact_rate = human / attempts * 100conversion_rate = sales / human * 100 # denominator is live humansabandonment_rate = abandoned / attempts * 100 # breach when > campaign capASR = answered / total_calls * 100occupancy = (busy_secs + wrap_secs) / (available_secs + busy_secs + wrap_secs) * 100Time-in-state and occupancy come from agent_state_intervals (completed
intervals only, windowed on left_at), so an agent’s current ongoing state is
excluded until it ends.
Examples
Section titled “Examples”Scheduled reports (/api/v1/report-schedules, admin+): a schedule emails
a report digest weekly or monthly. Fields: report, cadence,
day_of_week (0–6, weekly) or day_of_month (1–28, monthly), hour_utc,
recipients[], enabled. A 1-minute worker claims due schedules with
FOR UPDATE SKIP LOCKED (at-most-once across replicas) and emails four headline
metrics plus a link to /reports — no CSV is attached.
CSV export: append ?format=csv to any report, or use
GET /api/v1/cdrs/export for raw CDRs. Cells are guarded against
formula-injection (a leading = + - @ is prefixed with ').
QA scoring: a qa_scorecards row has questions (JSONB: scale_1_5 or
yes_no, each weighted). An evaluator scores a recorded call via
POST /api/v1/qa/evaluations; the score is computed server-side (clients
can’t inject one):
score = earned / total_weight * 100 # 0–100, unanswered questions score 0One evaluation per (call_id, evaluator) — re-submitting updates in place.
GET /api/v1/qa/agent-scores rolls evaluations up per agent.
- QA endpoints scope to the caller’s own tenant and do not accept a
?tenant_idoverride (unlike the reports). - The agent report’s QA columns count only
submittedevaluations, while/qa/agent-scoresincludes drafts — the two QA aggregates can differ. - The agent report’s
statecolumn is the current live state, not windowed.