Example: Answering an incoming call

View as Markdown

For the complete documentation index, see llms.txt.

This example answers an inbound Voximplant call and bridges audio to Ultravox’s WebSocket API for real‑time speech‑to‑speech conversations.

⬇️ Jump to the Full VoxEngine scenario.

Prerequisites

Session setup

Ultravox uses a WebSocket API client created via Ultravox.createWebSocketAPIClient(...). The key inputs are:

  • endpoint: use Ultravox.HTTPEndpoint.CREATE_CALL (or CREATE_AGENT_CALL for an existing Ultravox agent).
  • authorizations: include X-API-Key with your Ultravox API key.
  • body: provide systemPrompt, model, and voice.

Connect call audio

Once the client is created, bridge audio both ways between the call and Ultravox:

Connect call audio
1VoxEngine.sendMediaBetween(call, voiceAIClient);

Barge-in

Ultravox supports barge-in by providing a PlaybackClearBuffer event. If you want to interrupt the agent speech, listen for this event and clear the media buffer with clearMediaBuffer():

Barge-in
1voiceAIClient.addEventListener(Ultravox.WebSocketAPIEvents.PlaybackClearBuffer, (event) => {
2 Logger.write("===PLAYBACK_CLEAR_BUFFER===");
3 voiceAIClient.clearMediaBuffer();
4});

The Ultravox server may also request a buffer clear via PlaybackClearBuffer — this example handles both cases.

Events

The client supports both WebSocket API events and media events. Key events used in the example:

  • Ultravox.WebSocketAPIEvents: Transcript, HTTPResponse, State, Debug, WebSocketError, ConnectorInformation, Unknown, PlaybackClearBuffer
  • Ultravox.Events: WebSocketMediaStarted, WebSocketMediaEnded

Full VoxEngine scenario

voxeengine-ultravox-answer-incoming-call.js
1/**
2 * Voximplant + Ultravox WebSocket API connector demo
3 * Scenario: answer an incoming call and bridge it to Ultravox.
4 */
5
6require(Modules.Ultravox);
7require(Modules.ApplicationStorage);
8
9const SYSTEM_PROMPT = `You are Voxi, a helpful voice assistant for phone callers.
10Keep responses short and telephony-friendly (usually 1-2 sentences).`;
11
12// -------------------- Ultravox WebSocket API settings --------------------
13const AGENT_CONFIG = {
14 systemPrompt: SYSTEM_PROMPT,
15 model: "ultravox-v0.7",
16 voice: "Mark",
17};
18
19VoxEngine.addEventListener(AppEvents.CallAlerting, async ({call}) => {
20 let voiceAIClient;
21
22 // Termination functions - add cleanup and logging as needed
23 call.addEventListener(CallEvents.Disconnected, ()=>VoxEngine.terminate());
24 call.addEventListener(CallEvents.Failed, ()=>VoxEngine.terminate());
25
26 try {
27 call.answer();
28 // call.record({ hd_audio: true, stereo: true }); // Optional: record the call
29
30 // Create client and wire media
31 voiceAIClient = await Ultravox.createWebSocketAPIClient(
32 {
33 endpoint: Ultravox.HTTPEndpoint.CREATE_CALL,
34 authorizations: {"X-API-Key": (await ApplicationStorage.get("ULTRAVOX_API_KEY")).value},
35 body: AGENT_CONFIG,
36 onWebSocketClose: (event) => {
37 Logger.write("===ULTRAVOX_WEBSOCKET_CLOSED===");
38 if (event) Logger.write(JSON.stringify(event));
39 VoxEngine.terminate();
40 },
41 },
42 );
43 VoxEngine.sendMediaBetween(call, voiceAIClient);
44
45 // ---------------------- Event handlers -----------------------
46 // Barge-in: keep conversation responsive and capture transcript
47 voiceAIClient.addEventListener(Ultravox.WebSocketAPIEvents.Transcript, (event) => {
48 const payload = event?.data?.payload || event?.data || {};
49 const role = payload.role;
50 const text = payload.text || payload.delta;
51
52 if (role && text) Logger.write(`===TRANSCRIPT=== ${role}: ${text}`);
53 });
54
55 voiceAIClient.addEventListener(Ultravox.WebSocketAPIEvents.PlaybackClearBuffer, (event) => {
56 Logger.write("===PLAYBACK_CLEAR_BUFFER===");
57 voiceAIClient.clearMediaBuffer();
58 });
59
60 // Consolidated "log-only" handlers - key Ultravox/VoxEngine debugging events
61 [
62 Ultravox.WebSocketAPIEvents.ConnectorInformation,
63 Ultravox.WebSocketAPIEvents.HTTPResponse,
64 Ultravox.WebSocketAPIEvents.State,
65 Ultravox.WebSocketAPIEvents.Debug,
66 Ultravox.WebSocketAPIEvents.WebSocketError,
67 Ultravox.WebSocketAPIEvents.Unknown,
68 Ultravox.Events.WebSocketMediaStarted,
69 Ultravox.Events.WebSocketMediaEnded,
70 ].forEach((eventName) => {
71 voiceAIClient.addEventListener(eventName, (event) => {
72 Logger.write(`===${event.name}===`);
73 Logger.write(JSON.stringify(event));
74 });
75 });
76 } catch (error) {
77 Logger.write("===SOMETHING_WENT_WRONG===");
78 Logger.write(error);
79 voiceAIClient?.close();
80 VoxEngine.terminate();
81 }
82});