Live board
The floor right now: the extensions in the campaign by state, calls in flight, answered callers still waiting for an extension, and the recent answer rate. Needs dialer.supervise (an owner or admin on a session): it names the people on the floor. Read it on connect and after a reconnect of .../events; the stream is not a replay.
Authorization
bearerAuth Long-lived ES256 JWT minted from the dashboard (https://app.sautikit.com/developers/api-keys). Signed by the
platform keyring. Carries workspace_id and scopes claims;
revoked via the platform deny-list.
In: header
Path Parameters
uuidResponse Body
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/v1/dialer/campaigns/497f6eca-6276-4993-bfeb-53cbbbba6f08/live"{ "sessions": [ { "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "extension_id": "string", "user_name": "string", "state": "ready", "since": "2019-08-24T14:15:22Z" } ], "in_flight": 0, "waiting": [ { "attempt_id": "7a838dca-3ea8-4a7c-8133-ba2c86aeb22d", "contact_name": "string", "phone": "string", "since": "2019-08-24T14:15:22Z", "step": "hold", "ai_requested": true } ], "answer_rate": 0, "mode": "drip", "ratio": 0, "ratio_max": 0, "abandon_rate_pct": 0, "abandon_target_pct": 0}{ "error": { "code": "validation.bad_request", "message": "string", "request_id": "string", "details": [ "string" ], "resolution": "string", "reason": "invalid_characters", "suggested_e164": "+254727524723" }}{ "error": { "code": "validation.bad_request", "message": "string", "request_id": "string", "details": [ "string" ], "resolution": "string", "reason": "invalid_characters", "suggested_e164": "+254727524723" }}{ "error": { "code": "validation.bad_request", "message": "string", "request_id": "string", "details": [ "string" ], "resolution": "string", "reason": "invalid_characters", "suggested_e164": "+254727524723" }}Leave the campaign POST
Closes the session from any state and returns the extension to inbound ringing. Repeating it returns the closed session.
Stream campaign events GET
Opens a `text/event-stream` (SSE) connection that pushes the campaign's events as they happen. Every frame has an `event:` line and carries its kind inside the JSON as well: `data:` is `{"kind": "...", "event": "...", "data": {...}}` where `data` is the payload. Kinds: `dialer.call.started`, `dialer.call.answered`, `dialer.call.waiting` (also `contact_name`, `phone`, `step`), `dialer.call.connected`, `dialer.call.handed_to_ai`, `dialer.call.abandoned`, `dialer.call.completed`, `dialer.callback.scheduled`, `dialer.campaign.paused`, `dialer.campaign.completed`, `dialer.campaign.ratio_changed`, `dialer.budget.warning` (the webhook payloads), `dialer.session.state` (`id`, `extension_id`, `user_name`, `state`, `since`), `dialer.session.removed` (`id`), `dialer.stats` (`in_flight`, `answer_rate`, `ratio`, `abandon_rate_pct`; at most every 5 seconds) and `dialer.access_removed` (the last frame: the supervisor lost the role). Frames that come from an event carry `id:` (the event id; drop repeats). The stream ends after 30 minutes and is re-authorised while open, so reconnect and reload `.../live`. Delivery is best effort: events during a disconnect are not replayed. Needs `dialer.supervise`.