Skip to main content
Three routes show what is happening on an agent’s phone line and in its browser conversations right now: the roster of calls in progress, the turns spoken so far on one of them, and a workspace-wide list of active calls. Each answers a snapshot. The stream routes answer one Server-Sent Events frame and close the connection; there is no push, so read again (every few seconds is the pace the App uses) to see a call move. All three need calls:read, any role. Listening in, stopping and taking over a live call are supervisor actions in the Sempera App; there is no /v1 route for them.

The roster

agent_id is required (400 validation_failed without it) and must be an agent the credential can read (404 not_found otherwise). The answer is 200 text/event-stream with one frame:
Each item of live is a call in progress, oldest first: room (its id, the value to pass as room below), client (the agent id), mode, workspace_id, agent_version_id, language, caller and line (numbers masked to their last four digits, null when unknown), channel (phone on a real phone line), started_at (Unix seconds), elapsed_s, participants, recording_indicator (always true), sempera_call_id, engines and the internal correlation identifiers a support request may quote. A room with nobody in it is not a call and is not listed. supervisor_modes says which supervisor actions the App offers and why any is not offered. engines says what the call runs on: llm is the Sempera model id of the call’s language model, or null when that model has none; stt and tts.provider are the speech recognition and voice engines, each named by its Sempera model id when the call uses a published Sempera model, sempera-cloud-speech-recognition or sempera-cloud-voice for an engine a cloud provider hosts for Sempera, and null when there is no Sempera name to give; tts.voice is the voice. When Sempera’s live call service cannot be reached the answer is still 200, with "live": [], "media_server": false and "error": "media server unreachable: <error type>". An empty roster with media_server: true means no call is in progress.

One call’s transcript

room is a room from the roster; it is required, as is agent_id. The frame is:
turns are the turns spoken so far, in order, each with a role (caller or agent) and its text; an agent turn the caller cut off carries "interrupted": true. There is nothing else on a turn, and the list is empty until the first turn is written. The route answers a frame for every outcome, not the standard error envelope (Errors and limits): the frame’s data is {"error": "..."} with status 400 when room is missing, 409 when the room is not a call in progress for this agent (it ended, or belongs to another agent) and 200 when Sempera’s live call service cannot be reached (media server unreachable: <error type>). A missing agent_id, or one the credential cannot read, is refused with the standard envelope as for the roster. A finished call is read with GET /v1/sessions/{id} and GET /v1/calls/{call_id} instead (Sessions and calls).

Active calls across the workspace

GET /v1/calls/active lists the calls in progress on every agent the credential can read; agent_id narrows it to one. It answers {"data": [...], "errors": null}, each item call_id (the room), agent_id, user_id (the workspace id), from (masked), to (the masked line), start_time, status (always IN_PROGRESS) and timestamp (milliseconds since the epoch, as text). objective, pathway_id and international are always null: Sempera keeps none of them for a live call. When Sempera’s live call service cannot be reached the list is empty and errors carries {"error": "media_server_unreachable", "message": "..."}. GET /v1/calls/active/stream sends exactly that answer as one event: snapshot frame.