> For a complete documentation index, fetch https://docs.voximplant.ai/llms.txt

# Example: Answering an incoming call

> For the complete documentation index, see [llms.txt](/llms.txt).

## Overview

This example answers an inbound call and connects it to Qwen Cloud with a short prompt, an English voice, and barge-in.

**⬇️ Jump to the [Full VoxEngine scenario](#full-voxengine-scenario).**

## Prerequisites

* Set up an inbound entrypoint for the caller:
  * [Phone number](/platform/voxengine/phone-numbers)
  * [WhatsApp](/getting-started/network-options/whatsapp)
  * [SIP user / SIP registration](/getting-started/network-options/sip)
  * [App user](/platform/voxengine/users)
* Create a [routing rule](/platform/voxengine/routing-rules) that points the destination to this scenario.
* Store your Qwen Cloud API key in Voximplant [Secrets](/platform/voxengine/secrets) under `QWEN_API_KEY`.

## Architecture

```mermaid
graph LR
  Caller[PSTN/SIP/WhatsApp/App users/WebRTC] --> VoxEngine[VoxEngine Scenario]
  VoxEngine -->|WebSocket Media| Qwen[Qwen Cloud Realtime]
  Qwen --> VoxEngine
  VoxEngine --> Caller
```

## Usage highlights

* Create a `VoiceAgentAPIClient` with `QwenCloud.createVoiceAgentAPIClient`.
* The example pins `model` to `qwen-audio-3.1-realtime-plus`.
* On `SessionCreated`, send `sessionUpdate` with `voice`, `instructions`, languages, and `turn_detection`.
* On `SessionUpdated`, bridge audio with `VoxEngine.sendMediaBetween(call, client)` and ask Qwen to greet the caller.
* On `InputAudioBufferSpeechStarted`, call `clearMediaBuffer` so the caller can interrupt playback.

> **Media bridge**
>
> `QwenCloud.VoiceAgentAPIClient` is not in `VoxMediaUnitMap` yet. `sendMediaBetween` matches the other realtime connectors. See [Overview](overview) for the typings gap.

### Turn detection and barge-in

```js
voiceAIClient.addEventListener(
  QwenCloud.VoiceAgentAPIEvents.InputAudioBufferSpeechStarted,
  () => voiceAIClient.clearMediaBuffer()
);
```

## Configure before you run

* Set `QWEN_API_KEY` in Voximplant [Secrets](/platform/voxengine/secrets).
* Change `voice` if you want another Qwen system voice or a cloned voice id. `beth_v3.1` is an English 3.1 voice. The provider default is `longanqian_v3.1`.
* Adjust `SYSTEM_PROMPT` for your brand voice and guardrails.

## Try it

Suggested test prompts:

* "Hello"
* "What can you help me with?"
* "Goodbye."

## Notes

[See the VoxEngine API Reference for more details](/api-reference/voxengine/qwen-cloud).

## Full VoxEngine scenario

```javascript title={"voxeengine-qwen-answer-incoming-call.js"} maxLines={0}
require(Modules.QwenCloud);

const QWEN_MODEL = "qwen-audio-3.1-realtime-plus";
const SYSTEM_PROMPT = `
  You are Voxi, a concise phone agent for Voximplant callers.
  Voximplant is pronounced VOX-im-plant.
  Reply in English. Keep answers brief and helpful.
  If you do not know, say so and offer to connect them to a human.
`;

const SESSION_PARAMETERS = {
    session: {
        modalities: ["text", "audio"],
        voice: "beth_v3.1",
        instructions: SYSTEM_PROMPT,
        input_audio_transcription: {language: "en"},
        output_audio: {language: "en"},
        turn_detection: {type: "server_vad"},
    },
};

VoxEngine.addEventListener(AppEvents.CallAlerting, async ({call}) => {
    let voiceAIClient;

    const terminate = (event) => {
        if (event) Logger.write(JSON.stringify(event));
        voiceAIClient?.close();
        VoxEngine.terminate();
    };

    call.addEventListener(CallEvents.Disconnected, terminate);
    call.addEventListener(CallEvents.Failed, terminate);

    call.answer();
    // call.record({hd_audio: true, stereo: true});

    try {
        const providerApiKey = VoxEngine.getSecretValue("QWEN_API_KEY");
        if (!providerApiKey) throw new Error("Set QWEN_API_KEY in Voximplant Secrets");

        voiceAIClient = await QwenCloud.createVoiceAgentAPIClient({
            apiKey: providerApiKey,
            model: QWEN_MODEL,
            onWebSocketClose: terminate,
        });

        voiceAIClient.addEventListener(QwenCloud.VoiceAgentAPIEvents.SessionCreated, (event) => {
            Logger.write(`===${event.name}===>${JSON.stringify(event.data)}`);
            voiceAIClient.sessionUpdate(SESSION_PARAMETERS);
        });

        voiceAIClient.addEventListener(QwenCloud.VoiceAgentAPIEvents.SessionUpdated, (event) => {
            Logger.write(`===${event.name}===>${JSON.stringify(event.data)}`);
            VoxEngine.sendMediaBetween(call, voiceAIClient);
            voiceAIClient.conversationItemCreate({
                item: {
                    type: "message",
                    role: "user",
                    content: [{
                        type: "input_text",
                        text: "The call just connected. Greet the caller in one short sentence.",
                    }],
                },
            });
            voiceAIClient.responseCreate({});
        });

        voiceAIClient.addEventListener(QwenCloud.VoiceAgentAPIEvents.InputAudioBufferSpeechStarted, (event) => {
            Logger.write(`===${event.name}===>${JSON.stringify(event.data)}`);
            voiceAIClient.clearMediaBuffer();
        });

        [
            QwenCloud.Events.WebSocketMediaStarted,
            QwenCloud.Events.WebSocketMediaEnded,
            QwenCloud.VoiceAgentAPIEvents.ConnectorInformation,
            QwenCloud.VoiceAgentAPIEvents.ResponseCreated,
            QwenCloud.VoiceAgentAPIEvents.ResponseOutputItemAdded,
            QwenCloud.VoiceAgentAPIEvents.ResponseOutputItemDone,
            QwenCloud.VoiceAgentAPIEvents.ResponseAudioTranscriptDelta,
            QwenCloud.VoiceAgentAPIEvents.ResponseAudioTranscriptDone,
            QwenCloud.VoiceAgentAPIEvents.ResponseAudioDone,
            QwenCloud.VoiceAgentAPIEvents.ResponseDone,
            QwenCloud.VoiceAgentAPIEvents.InputAudioBufferSpeechStopped,
            QwenCloud.VoiceAgentAPIEvents.InputAudioBufferCommitted,
            QwenCloud.VoiceAgentAPIEvents.ConversationItemCreated,
            QwenCloud.VoiceAgentAPIEvents.ConversationItemInputAudioTranscriptionCompleted,
            QwenCloud.VoiceAgentAPIEvents.Error,
            QwenCloud.VoiceAgentAPIEvents.WebSocketError,
            QwenCloud.VoiceAgentAPIEvents.Unknown,
        ].forEach((evtName) => {
            voiceAIClient.addEventListener(evtName, (e) => {
                Logger.write(`===${e.name}===>${JSON.stringify(e)}`);
            });
        });
    } catch (error) {
        Logger.write("===SOMETHING_WENT_WRONG===");
        Logger.write(JSON.stringify(error));
        VoxEngine.terminate();
    }
});

```