Example: Answering an incoming call

View as MarkdownOpen in Claude

This example answers an inbound Voximplant call and bridges audio to Deepgram Voice Agent for real-time speech‑to‑speech conversations.

⬇️ Jump to the Full VoxEngine scenario.

Prerequisites

Session setup

The Deepgram Voice Agent session is configured via a settingsOptions object that’s passed directly to Deepgram.createVoiceAgentClient(...).

In the full example, see SETTINGS_OPTIONS.agent:

  • listen: speech-to-text provider (for example type: "deepgram")
  • think: LLM provider + prompt
  • speak: text-to-speech provider
Don’t set audio settings

When using the VoxEngine connector, do not include audio settings in the Deepgram settings object — audio is handled by the connector for optimal telephony quality.

Connect call audio

Once you’ve created the Deepgram.VoiceAgentClient, you need to connect audio both ways between the phone call and the agent.

In the example, this is done with:

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

This bridges media between a Call and a Deepgram.VoiceAgentClient. You can also do the same thing explicitly, one direction at a time, using sendMediaTo:

Equivalent using sendMediaTo
1call.sendMediaTo(voiceAgentClient);
2voiceAgentClient.sendMediaTo(call);

Mid-session updates

After the client is created (see voiceAgentClient in the scenario), you can update the agent mid-call without reconnecting using Deepgram.VoiceAgentClient methods.

These methods are documented in the Voximplant reference:

Mid-session updates
1// Update the agent’s system prompt mid-call (sendUpdatePrompt)
2voiceAgentClient.sendUpdatePrompt({
3 type: "UpdatePrompt",
4 prompt: "You are now a helpful travel assistant. Keep responses to 1 sentence.",
5});
6
7// Change the TTS voice/model mid-call (sendUpdateSpeak)
8voiceAgentClient.sendUpdateSpeak({
9 type: "UpdateSpeak",
10 speak: {
11 provider: {
12 type: "deepgram",
13 model: "aura-2-luna-en",
14 },
15 },
16});
17
18// Inject text messages for deterministic flows (sendInjectUserMessage / sendInjectAgentMessage)
19voiceAgentClient.sendInjectUserMessage({
20 type: "InjectUserMessage",
21 content: "Before we continue, ask the caller for their order number.",
22});
23
24voiceAgentClient.sendInjectAgentMessage({
25 type: "InjectAgentMessage",
26 message: "Sure — what is your order number?",
27});

Barge-in

To keep the conversation interruption-friendly, the example listens for Deepgram.VoiceAgentEvents.UserStartedSpeaking and clears the media buffer so any in-progress TTS audio is canceled when the caller starts talking:

Barge-in
1voiceAgentClient.addEventListener(Deepgram.VoiceAgentEvents.UserStartedSpeaking, () => {
2 voiceAgentClient.clearMediaBuffer();
3});

Events

In the scenario, a focused handler captures the transcript via Deepgram.VoiceAgentEvents.ConversationText, and a second handler logs a set of lifecycle/debug events:

Events (example from the scenario)
1voiceAgentClient.addEventListener(Deepgram.VoiceAgentEvents.ConversationText, (event) => {
2 const { role, text } = event?.data?.payload || {};
3 if (role && text) Logger.write(`${role}: ${text}`);
4});

The client supports both Deepgram Voice Agent events and Deepgram WebSocket media events (see addEventListener / removeEventListener in the VoiceAgentClient reference):

  • Deepgram.VoiceAgentEvents: Welcome, SettingsApplied, AgentThinking, ConversationText, UserStartedSpeaking, AgentAudioDone, FunctionCallRequest, FunctionCallResponse, PromptUpdated, SpeakUpdated, History, HTTPResponse, ConnectorInformation, Warning, Error, WebSocketError, Unknown
  • Deepgram.Events: WebSocketMediaStarted, WebSocketMediaEnded

Notes

See the VoxEngine API Reference for more details.

Full VoxEngine scenario

voxeengine-deepgram-answer-incoming-call.js
1/**
2 * Voximplant + Deepgram Voice Agent connector demo
3 * Scenario: answer an incoming call and bridge it to Deepgram Voice Agent.
4 */
5
6require(Modules.Deepgram);
7require(Modules.ApplicationStorage);
8
9const SYSTEM_PROMPT = `You are a helpful English-speaking voice assistant for phone callers. Keep your turns short and telephony-friendly (usually 1–2 sentences).`;
10
11// -------------------- Deepgram Voice Agent settings --------------------
12const SETTINGS_OPTIONS = {
13 tags: ["voximplant", "deepgram", "voice_agent_connector", "incoming_call_demo"],
14 agent: {
15 language: "en",
16 greeting: "Hi! I'm Voxi. How can I help today?",
17 listen: {
18 provider: {
19 type: "deepgram",
20 model: "flux-general-en",
21 // ... additional provider options
22 },
23 },
24 think: {
25 provider: {
26 type: "open_ai",
27 model: "gpt-4o-mini",
28 // ... additional provider options
29
30 },
31 prompt: SYSTEM_PROMPT,
32 // ... additional think options: context_length, functions, endpoint
33
34 },
35 speak: {
36 provider: {
37 type: "deepgram",
38 model: "aura-2-cordelia-en",
39 // Examples for other providers:
40 // "type": "open_ai", "model": "tts-1", "voice": "alloy"
41 // "type": "eleven_labs", "model_id": "eleven_monolingual_v1", "language_code": "en-US"
42 // "type": "cartesia", "model_id": "sonic-2", "voice": {"mode": "id", "id": "voice-id"}, "language": "en"
43 // "type": "aws_polly", "voice": "Matthew", "language_code": "en-US", "engine": "standard", "credentials": {...}
44 },
45 // ... additional speak options: endpoint (required for non-deepgram providers)
46 },
47 // ... additional agent options: context, greeting
48 },
49};
50
51VoxEngine.addEventListener(AppEvents.CallAlerting, async ({call}) => {
52 let voiceAIClient;
53
54 // Termination functions - add cleanup and logging as needed
55 call.addEventListener(CallEvents.Disconnected, ()=>VoxEngine.terminate());
56 call.addEventListener(CallEvents.Failed, ()=>VoxEngine.terminate());
57
58
59 try {
60 call.answer();
61 // call.record({ hd_audio: true, stereo: true }); // Optional: record the call
62
63 // Create client and wire media
64 voiceAIClient = await Deepgram.createVoiceAgentClient({
65 apiKey: (await ApplicationStorage.get("DEEPGRAM_API_KEY")).value, // Add your Deepgram API key secret value or save it to storage
66 settingsOptions: SETTINGS_OPTIONS,
67 });
68 VoxEngine.sendMediaBetween(call, voiceAIClient);
69
70
71 // ---------------------- Event handlers -----------------------
72 // Barge-in: keep conversation responsive
73 voiceAIClient.addEventListener(Deepgram.VoiceAgentEvents.UserStartedSpeaking, () => {
74 Logger.write("===BARGE-IN: Deepgram.VoiceAgentEvents.UserStartedSpeaking===");
75 voiceAIClient.clearMediaBuffer();
76 });
77
78 // Capture transcript
79 voiceAIClient.addEventListener(Deepgram.VoiceAgentEvents.ConversationText, (event) => {
80 const {role, text} = event?.data?.payload || {};
81 if (role && text) {
82 Logger.write(`===TRANSCRIPT=== ${role}: ${text}`);
83 }
84 });
85
86 // Consolidated "log-only" handlers - key Deepgram/VoxEngine debugging events
87 [
88 Deepgram.VoiceAgentEvents.Welcome,
89 Deepgram.VoiceAgentEvents.SettingsApplied,
90 Deepgram.VoiceAgentEvents.AgentThinking,
91 Deepgram.VoiceAgentEvents.AgentAudioDone,
92 Deepgram.VoiceAgentEvents.ConnectorInformation,
93 Deepgram.VoiceAgentEvents.HTTPResponse,
94 Deepgram.VoiceAgentEvents.Warning,
95 Deepgram.VoiceAgentEvents.Error,
96 Deepgram.VoiceAgentEvents.Unknown,
97 Deepgram.Events.WebSocketMediaStarted,
98 Deepgram.Events.WebSocketMediaEnded,
99 ].forEach((eventName) => {
100 voiceAIClient.addEventListener(eventName, (event) => {
101 Logger.write(`===${event.name}===`);
102 Logger.write(JSON.stringify(event));
103 });
104 });
105 } catch (e) {
106 Logger.write("===UNHANDLED_ERROR===");
107 Logger.write(e);
108 voiceAIClient?.close();
109 VoxEngine.terminate();
110 }
111});