Stream campaign events
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.
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
text/event-stream
application/json
application/json
application/json
curl -X GET "https://example.com/v1/dialer/campaigns/497f6eca-6276-4993-bfeb-53cbbbba6f08/events""string"{ "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" }}Live board GET
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.
Send a waiting caller to an AI agent POST
Sends an answered caller who has no extension yet to a published AI agent. It works once per caller and only while the caller is still held (hold, hold line or callback offer): a caller already connected to a person, already with an AI, or who has hung up returns `409 dialer.invalid_state`, and no second AI leg is ever started. `202` means the request is recorded; the call moves within one hold step (a few seconds), or at once when the phone system supports redirect (`via: redirect`). The AI minutes are billed to the workspace wallet as `dialer_overflow`. If the agent cannot take the call, the caller carries on down the overflow ladder (callback offer, then apology), never into silence. Needs `dialer.supervise`.