osmTalk Docs
Campaigns

Live Monitoring

Pause, resume, and inspect campaigns as they run.

Dashboard live view

The Campaigns → [campaign name] page polls every few seconds and shows:

  • A status banner (running / paused / completed)
  • Aggregate counts: pending, dialing, completed, qualified, failed, DNC-blocked
  • A per-lead table with the current status, attempts, last call link, and outcome JSON expander
  • Pause / Resume / Stop controls

API: get campaign + counts

curl https://api.osmtalk.com/api/campaigns/{id}/report

Response:

{
  "campaign": { "id": "cmp_xxx", "status": "running", "totalLeads": 5000, "qualifiedLeads": 412, ... },
  "counts": {
    "byStatus": {
      "pending": 1980,
      "dialing": 5,
      "completed": 2810,
      "no_answer": 110,
      "voicemail": 78,
      "dnc_blocked": 12,
      "failed": 5
    },
    "byDisposition": {
      "qualified": 412,
      "not_interested": 1830,
      "callback": 78,
      "completed": 490
    }
  }
}

API: paginate leads

curl "https://api.osmtalk.com/api/campaigns/{id}/leads?status=qualified&limit=100&offset=0"

Filters:

ParamNotes
statusOne of pending / queued / dialing / completed / voicemail / no_answer / busy / failed / dnc_blocked
limit1 – 1000 (default 200)
offsetFor paging

Pause / resume / stop

# Halt new dials — in-flight calls finish naturally
curl -X POST .../api/campaigns/{id}/pause

# Resume — picks up at next 15s tick
curl -X POST .../api/campaigns/{id}/resume

# Permanent stop — campaign moves to "completed"
curl -X POST .../api/campaigns/{id}/stop

Transitions are validated server-side: you'll get a 400 if the campaign isn't in a state where the transition is allowed.

Auto-completion

The dialer marks the campaign completed automatically when every lead has reached a terminal status (completed, failed, dnc_blocked, voicemail-after-max-attempts). No manual stop needed for organic completion.

Logs

Each campaign tick logs:

INFO: Internal cron: job completed — job: campaign-dialer, ms: 234, result: { campaignsProcessed: 3, callsStarted: 7 }

Watch via:

docker compose -f docker-compose.prod.yml logs -f api | grep "campaign-dialer"

Per-lead spawn errors log at WARN/ERROR level with campaignId and leadId for easy filtering.

Troubleshooting

"Campaign is running but nothing dials"

Possible causes:

  1. Outside dialing window — check schedule.timezone + windowStart/windowEnd. The dialer is intentionally silent during banned hours.
  2. At org capacityGET /api/jobs/reconcile-capacity and look at active call counts. If 15/15 are in flight, new calls queue.
  3. No phoneNumberId on the campaign — required for outbound; fix via PUT.
  4. Phone number has no SIP outbound trunk — check /api/phone-numbers/{id}; missing trunk means we can't dial out.

"All my leads end as failed"

Either the bot is crashing, the SIP trunk is dropping, or the destination numbers are unreachable. Inspect a few lastCallId values and look at:

  • Call transcript — is the bot connecting at all?
  • Bot logs — docker compose ... logs bot | grep <callId>
  • osmTalk voice-transport logs — SIP failure reasons appear here

"Voicemail is being counted as completed instead of voicemail"

Enable voicemail detection on the agent (Advanced → Voicemail Detection). Without it, voicemail looks like a completed call to the dispositioner.