Live Conversation WebSocket (Preview)

The Live Conversation WebSocket provides real-time updates about an active conversation’s state. It is a server-to-client only connection — the client does not send any messages after connecting.

Endpoint

wss://api.phonic.co/v1/conversations/{conversation_id}/live/ws
ParameterLocationDescription
conversation_idPathThe ID of the conversation to observe

Authentication

This endpoint supports the same authentication methods as the STS WebSocket:

  • API Key: Authorization: Bearer PHONIC_API_KEY header
  • Session Token: ?session_token=ph_session_... query parameter

Connection flow

  1. Connect to the WebSocket with valid credentials
  2. Receive an initial conversation-updated message with the current conversation state
  3. Continue receiving conversation-updated messages as the conversation progresses
  4. Receive a conversation-ended message when the conversation finishes

Server-to-client messages

conversation-updated

Sent whenever the conversation state changes. Contains the full conversation object.

The conversation object has the same shape as the Conversation returned by the REST API, with is_live always set to true.

1{
2 "type": "conversation-updated",
3 "conversation": {
4 "id": "conv_12cf6e88-c254-4d3e-a149-ddf1bdd2254c",
5 "agent": {
6 "id": "agent_12cf6e88-c254-4d3e-a149-a7f1bdd22783",
7 "name": "support-agent",
8 "is_deleted": false
9 },
10 "org_id": "org_01K1WB8NT3EJJ4ZRKJ6BQZPZPS",
11 "project_id": "proj_ad0334f1-2487-4155-9df3-abd8129b29ad",
12 "external_id": "call-123",
13 "origin": "inbound",
14 "generate_welcome_message": false,
15 "welcome_message": "Hello! How can I help you today?",
16 "template_variables": {},
17 "input_format": "mulaw_8000",
18 "output_format": "mulaw_8000",
19 "background_noise_level": 0,
20 "background_noise": null,
21 "intelligence_level": "default",
22 "text": "Hello! How can I help you today?\nHi, I need help with booking an appointment.\nOf course! I'd be happy to help.",
23 "duration_ms": 12500,
24 "summary": null,
25 "boosted_keywords": [],
26 "languages": ["en"],
27 "no_input_poke_sec": 30,
28 "generate_no_input_poke_text": false,
29 "no_input_poke_text": "Are you still there?",
30 "no_input_end_conversation_sec": 180,
31 "storage_key": null,
32 "started_at": "2025-07-30T23:45:00.000Z",
33 "ended_at": null,
34 "task_results": null,
35 "timezone": "America/Los_Angeles",
36 "system_prompt": "You are a helpful support assistant.",
37 "is_test": false,
38 "is_live": true,
39 "call_provider": "twilio_inbound_user",
40 "from_phone_number": "+15551234567",
41 "to_phone_number": "+15559876543",
42 "twilio_call_sid": null,
43 "created_by": null,
44 "vad_min_silence_duration_ms": null,
45 "assistant_end_conversation_signal_at": null,
46 "retranscribed_text": null,
47 "end_reason": null,
48 "vad_info": { "events": [] },
49 "annotations": {},
50 "items": [
51 {
52 "id": "conv_12cf6e88-c254-4d3e-a149-ddf1bdd2254c-0",
53 "item_idx": 0,
54 "role": "assistant",
55 "text": "Hello! How can I help you today?",
56 "retranscribed_text": null,
57 "duration_ms": 1800,
58 "audio_speed": 1,
59 "voice": null,
60 "tool_call_ids": [],
61 "transcript_corrections": [],
62 "naturalness_report": null,
63 "hallucination_report": null,
64 "started_at": "2025-07-30T23:45:00.500Z",
65 "assistant_chose_not_to_respond": false,
66 "timings": {
67 "phonic_api_output_to_modal_input": 120,
68 "model_generation_time": 450,
69 "phonic_api_output_to_first_audio_chunk": 570
70 }
71 },
72 {
73 "id": "conv_12cf6e88-c254-4d3e-a149-ddf1bdd2254c-1",
74 "item_idx": 1,
75 "role": "user",
76 "text": "Hi, I need help with booking an appointment.",
77 "retranscribed_text": null,
78 "duration_ms": 2500,
79 "audio_speed": null,
80 "voice": null,
81 "tool_call_ids": [],
82 "transcript_corrections": [],
83 "naturalness_report": null,
84 "hallucination_report": null,
85 "started_at": "2025-07-30T23:45:03.000Z",
86 "assistant_chose_not_to_respond": false
87 },
88 {
89 "id": "conv_12cf6e88-c254-4d3e-a149-ddf1bdd2254c-2",
90 "item_idx": 2,
91 "role": "assistant",
92 "text": "Of course! I'd be happy to help.",
93 "retranscribed_text": null,
94 "duration_ms": 2100,
95 "audio_speed": 1,
96 "voice": null,
97 "tool_call_ids": [],
98 "transcript_corrections": [],
99 "naturalness_report": null,
100 "hallucination_report": null,
101 "started_at": "2025-07-30T23:45:06.200Z",
102 "assistant_chose_not_to_respond": false,
103 "timings": {
104 "phonic_api_output_to_modal_input": 95,
105 "model_generation_time": 380,
106 "phonic_api_output_to_first_audio_chunk": 475
107 }
108 }
109 ]
110 }
111}

conversation-ended

Sent when the conversation has ended. The client should close the WebSocket after receiving this.

1{
2 "type": "conversation-ended"
3}

error

Sent on authentication failure, authorization failure, or other errors. The error may appear in error.message or the top-level message field.

1{
2 "type": "error",
3 "error": {
4 "message": "Invalid token"
5 }
6}
1{
2 "type": "error",
3 "message": "Unauthorized access to conversation"
4}

Close codes

CodeDescription
1000Normal closure (conversation ended)
1008Authentication or authorization error

Example usage

1const apiKey = "ph_...";
2const conversationId = "conv_12cf6e88-c254-4d3e-a149-ddf1bdd2254c";
3
4const ws = new WebSocket(
5 `wss://api.phonic.co/v1/conversations/${conversationId}/live/ws`,
6 { headers: { Authorization: `Bearer ${apiKey}` } }
7);
8
9ws.onmessage = (event) => {
10 const data = JSON.parse(event.data);
11
12 switch (data.type) {
13 case "conversation-updated":
14 console.log(`Conversation updated. (${data.conversation.items.length} turns)`)
15 break;
16
17 case "conversation-ended":
18 console.log("Conversation ended");
19 ws.close();
20 break;
21
22 case "error":
23 console.error("Error:", data.error?.message ?? data.message);
24 ws.close();
25 break;
26 }
27};