The campaign detail page at /dashboard/campaigns/:id is the monitoring and review surface for a single campaign. It lives in src/pages/CampaignDetail.tsx and embeds CampaignConfigPanel from src/components/campaign/CampaignConfigPanel.tsx.

Data and polling

  • GET /api/v1/campaigns/{id} loads the campaign; GET /api/v1/campaigns/{id}/calls?page=&limit=50 loads paginated calls.
  • While shouldPollCampaignCalls (from src/pages/campaignProgress.ts) returns true, both endpoints re-fetch every 5 seconds.
  • The call table supports callback filters (all, requested, pending, completed, cancelled) when callback_detection is enabled, passed as &callback=.

Header actions

ButtonVisible whenEndpoint
Editdraft or pausednavigates to edit wizard
ClonealwaysPOST /campaigns/{id}/clone
Activity (N)activity_log non-emptyopens activity log modal
Attempt ReportalwaysGET /campaigns/{id}/attempt-report.csv (blob download)
Restartcompleted or failedPOST /campaigns/{id}/restart
Cancel Restartprepared restartPOST /campaigns/{id}/cancel-restart
Start / Resume / Pause / Stopby statusPOST /campaigns/{id}/{action}
Deletefirst-run draft onlyDELETE /campaigns/{id}
A prepared restart (draft, run number > 1, with restart history) shows a notice that the new run is prepared but not started, and surfaces the previous run’s completed time and stats.

Live activity panel

The campaign.live block renders differently depending on status: Running / paused shows a 6-metric grid: Ringing, In Progress, Dials/sec, Connected/hr, Avg Ring Time, and Last Dial, plus pending and retries-queued counts and an ETA. The banner self-classifies as Live Activity, Idle (waiting for retries when no dial in 30s), or Paused — Outside time window (computed against the configured time window). Completed / stopped shows a Campaign Performance grid: average Dials/sec, Connected/hr, Calls/min, and Total Connected. Both render a pass breakdown when live.passes exists — per pass it shows attempted / eligible, connected count and rate, and start/end times with duration.
Avg Ring Time is the time customers take to pick up after dialing (ring duration before answer). It is distinct from AHT, which is conversation length.

Stats and metrics

The stats grid (with hover InfoTips) shows Total, Pending, Connected, Completed, Unanswered, Retries Left, abandons, AMD Machine, and — for v2 stats — Window Closed and Manual Stopped. Schema v2 prefers retry_exhausted and true_abandoned over legacy failed/abandoned. The metrics row shows Answer Rate, Completion Rate, Abandon Rate (regulatory ceiling 3%), and AHT. When viewing a prepared restart, metrics fall back to previous_run_stats. A callback panel appears when callbacks were requested or are pending: requested, pending, completed, and average delay.

Config panel

CampaignConfigPanel renders bot ID, concurrency, time window, number pool summary, max attempts, retry delay, retry-on-system/custom lists, optional config URL, and a collapsible raw setup JSON (buildCampaignSetupSnapshot from campaignSetup.ts).

Call list and attempt trail

The call table shows phone number, status (with a Callback badge when scheduled), attempt count attempt/max_attempts, an Attempt Trail of every attempt (#n, outcome, time, attempt-ID tail, SIP error), Last Result, and flattened CRM variables. formatAttemptResult maps SIP codes to friendly text via SIP_FRIENDLY (for example 408 → No answer (rang out), 486 → Line busy). Pagination appears above 50 records.

Campaign wizard

Create/edit a campaign and its dialler config.

Monitor campaigns

Ops playbook for live monitoring.

Pacing and retries

Predictive pacing, passes, and retry behavior.

AMD screening

Answering-machine detection outcomes.