The Call Event Stream API allows you to subscribe to real-time events from all active calls in your voicetyped deployment. This is the primary observability and integration API — use it to build dashboards, log call activity, trigger external workflows, or implement custom call handling logic.
Endpoints
| Method | Path | Description |
|---|
GET | /v1/calls/events | Server-Sent Events stream for real-time call events |
GET | /v1/calls/{id} | Get a specific call’s status |
GET | /v1/calls | List active calls |
Subscribe to Call Events
GET /v1/calls/events
Opens a Server-Sent Events (SSE) stream that delivers call events in real-time.
Query Parameters
| Parameter | Type | Description |
|---|
event_types | string | Comma-separated list of event types to filter (empty = all events) |
session_id | string | Filter events by call session ID (empty = all calls) |
dialog_name | string | Filter events by dialog name (empty = all dialogs) |
include_history | bool | Include historical events from active calls (default false) |
Response
The response is a text/event-stream with event and data fields. Each data field contains a JSON object.
event: call_started
data: {"event_id":"evt-001","session_id":"call-abc-123","type":"call_started","timestamp":"2025-06-14T18:30:00Z","caller_id":"+15551234567","called_number":"+18001234567","dialog_name":"helpdesk","sip_headers":{}}
event: speech_final
data: {"event_id":"evt-002","session_id":"call-abc-123","type":"speech_final","timestamp":"2025-06-14T18:30:04Z","transcript":"I need a password reset","confidence":0.94,"language":"en","duration_ms":2100,"segments":[{"text":"I","start_ms":0,"end_ms":180,"confidence":0.97},{"text":"need","start_ms":200,"end_ms":420,"confidence":0.96},{"text":"a","start_ms":440,"end_ms":520,"confidence":0.99},{"text":"password","start_ms":540,"end_ms":900,"confidence":0.93},{"text":"reset","start_ms":920,"end_ms":1200,"confidence":0.91}]}
event: call_terminated
data: {"event_id":"evt-003","session_id":"call-abc-123","type":"call_terminated","timestamp":"2025-06-14T18:32:15Z","reason":"normal","duration_seconds":135,"state_transitions":4,"final_state":"goodbye"}
Event Types
| Event Type | Description |
|---|
call_started | A new call has connected |
call_terminated | A call has ended |
speech_partial | Interim (non-final) transcript available |
speech_final | Final transcript available |
dtmf_received | A DTMF digit was received |
state_transition | The dialog FSM changed states |
action_executed | A dialog action was executed |
hook_result | A dialog hook returned a result |
hook_error | A dialog hook returned an error |
tts_started | Text-to-speech playback began |
tts_completed | Text-to-speech playback finished |
error | A system error occurred |
Event Payloads
call_started
Emitted when a new call is connected:
{
"event_id": "evt-001",
"session_id": "call-abc-123",
"type": "call_started",
"timestamp": "2025-06-14T18:30:00Z",
"caller_id": "+15551234567",
"called_number": "+18001234567",
"dialog_name": "helpdesk",
"sip_headers": {
"X-Custom-Header": "value"
}
}
| Field | Type | Description |
|---|
event_id | string | Unique event identifier |
session_id | string | Call session ID |
type | string | "call_started" |
timestamp | string | ISO 8601 timestamp |
caller_id | string | Caller phone number |
called_number | string | Dialed number |
dialog_name | string | Matched dialog |
sip_headers | object | Custom SIP headers (key-value pairs) |
call_terminated
Emitted when a call ends:
{
"event_id": "evt-003",
"session_id": "call-abc-123",
"type": "call_terminated",
"timestamp": "2025-06-14T18:32:15Z",
"reason": "normal",
"duration_seconds": 135,
"state_transitions": 4,
"final_state": "goodbye"
}
| Field | Type | Description |
|---|
event_id | string | Unique event identifier |
session_id | string | Call session ID |
type | string | "call_terminated" |
timestamp | string | ISO 8601 timestamp |
reason | string | Termination reason (see below) |
duration_seconds | integer | Call duration |
state_transitions | integer | Number of FSM transitions |
final_state | string | Last state before termination |
Termination reasons:
| Reason | Description |
|---|
normal | Normal hangup |
caller_hangup | Caller hung up |
system_hangup | Dialog reached hangup action |
transfer | Call was transferred |
error | System error |
timeout | Max duration exceeded |
speech_final / speech_partial
Emitted for final and partial transcripts:
{
"event_id": "evt-002",
"session_id": "call-abc-123",
"type": "speech_final",
"timestamp": "2025-06-14T18:30:04Z",
"transcript": "I need a password reset",
"confidence": 0.94,
"language": "en",
"duration_ms": 2100,
"segments": [
{ "text": "I", "start_ms": 0, "end_ms": 180, "confidence": 0.97 },
{ "text": "need", "start_ms": 200, "end_ms": 420, "confidence": 0.96 },
{ "text": "a", "start_ms": 440, "end_ms": 520, "confidence": 0.99 },
{ "text": "password", "start_ms": 540, "end_ms": 900, "confidence": 0.93 },
{ "text": "reset", "start_ms": 920, "end_ms": 1200, "confidence": 0.91 }
]
}
| Field | Type | Description |
|---|
event_id | string | Unique event identifier |
session_id | string | Call session ID |
type | string | "speech_final" or "speech_partial" |
timestamp | string | ISO 8601 timestamp |
transcript | string | Transcript text |
confidence | float | Confidence score (0.0–1.0) |
language | string | Detected language code |
duration_ms | integer | Speech duration in milliseconds |
segments | array | Word-level timing (final only) |
Each segment object:
| Field | Type | Description |
|---|
text | string | Word text |
start_ms | integer | Start time in milliseconds |
end_ms | integer | End time in milliseconds |
confidence | float | Word-level confidence score |
dtmf_received
{
"event_id": "evt-010",
"session_id": "call-abc-123",
"type": "dtmf_received",
"timestamp": "2025-06-14T18:30:10Z",
"digit": "5",
"duration_ms": 120
}
| Field | Type | Description |
|---|
digit | string | "0"–"9", "*", "#" |
duration_ms | integer | Tone duration in milliseconds |
state_transition
{
"event_id": "evt-015",
"session_id": "call-abc-123",
"type": "state_transition",
"timestamp": "2025-06-14T18:30:12Z",
"from_state": "greeting",
"to_state": "collect_info",
"trigger_event": "speech_final",
"dialog_name": "helpdesk"
}
| Field | Type | Description |
|---|
from_state | string | Previous state |
to_state | string | New state |
trigger_event | string | What caused the transition |
dialog_name | string | Dialog name |
Usage Examples
curl
# Subscribe to real-time call events (SSE)
curl -N "http://localhost:8080/v1/calls/events?event_types=call_started,speech_final,call_terminated"
# Filter events for a specific session
curl -N "http://localhost:8080/v1/calls/events?session_id=call-abc-123"
# Filter events for a specific dialog
curl -N "http://localhost:8080/v1/calls/events?dialog_name=helpdesk&include_history=true"
# Get a specific call
curl "http://localhost:8080/v1/calls/call-abc-123"
# List active calls
curl "http://localhost:8080/v1/calls?page_size=50"
# List active calls filtered by dialog
curl "http://localhost:8080/v1/calls?dialog_name=helpdesk&page_size=25"
JavaScript (EventSource)
const params = new URLSearchParams({
event_types: "call_started,speech_final,call_terminated",
});
const source = new EventSource(`http://localhost:8080/v1/calls/events?${params}`);
source.addEventListener("call_started", (e) => {
const data = JSON.parse(e.data);
console.log(`Call started: ${data.session_id} from ${data.caller_id}`);
});
source.addEventListener("speech_final", (e) => {
const data = JSON.parse(e.data);
console.log(`[${data.session_id}] ${data.transcript} (${Math.round(data.confidence * 100)}%)`);
});
source.addEventListener("call_terminated", (e) => {
const data = JSON.parse(e.data);
console.log(`Call ended: ${data.session_id} (${data.reason}, ${data.duration_seconds}s)`);
});
source.onerror = (err) => {
console.error("SSE connection error:", err);
source.close();
};
Get Call
GET /v1/calls/{id}
Retrieve the current status of a specific call.
Response
{
"session_id": "call-abc-123",
"caller_id": "+15551234567",
"called_number": "+18001234567",
"dialog_name": "helpdesk",
"current_state": "collect_info",
"start_time": "2025-06-14T18:30:00Z",
"duration_seconds": 45,
"status": "active",
"variables": {
"customer_name": "Jane",
"intent": "password_reset"
}
}
| Field | Type | Description |
|---|
session_id | string | Call session ID |
caller_id | string | Caller phone number |
called_number | string | Dialed number |
dialog_name | string | Matched dialog |
current_state | string | Current FSM state |
start_time | string | ISO 8601 call start time |
duration_seconds | integer | Elapsed time since call start |
status | string | Call status (see below) |
variables | object | Dialog variables (key-value pairs) |
Call status values:
| Status | Description |
|---|
active | Call is in progress |
on_hold | Call is on hold |
transferring | Call is being transferred |
terminated | Call has ended |
Error Responses
| Status Code | Description |
|---|
404 Not Found | Call with the given ID does not exist |
401 Unauthorized | Missing or invalid authentication |
500 Internal Server Error | Server error |
List Calls
GET /v1/calls
List all active calls.
Query Parameters
| Parameter | Type | Default | Description |
|---|
dialog_name | string | | Filter by dialog name |
page_size | integer | 50 | Maximum number of results |
page_token | string | | Pagination token from a previous response |
Response
{
"calls": [
{
"session_id": "call-abc-123",
"caller_id": "+15551234567",
"called_number": "+18001234567",
"dialog_name": "helpdesk",
"current_state": "collect_info",
"start_time": "2025-06-14T18:30:00Z",
"duration_seconds": 45,
"status": "active",
"variables": {}
}
],
"next_page_token": "eyJvZmZzZXQiOjUwfQ==",
"total_count": 127
}
| Field | Type | Description |
|---|
calls | array | List of call objects (same schema as Get Call) |
next_page_token | string | Token for the next page (empty if no more results) |
total_count | integer | Total number of matching calls |
Error Responses
| Status Code | Description |
|---|
400 Bad Request | Invalid query parameter value |
401 Unauthorized | Missing or invalid authentication |
500 Internal Server Error | Server error |
Connection Details
| Parameter | Default | Description |
|---|
| Host | localhost | API server host |
| Port | 8080 | REST API port |
| TLS | false | Enable HTTPS (recommended for production) |
| Auth | None | mTLS or API key (see Security) |
Next Steps