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

# Example: Answering an incoming call

> This example answers an inbound Voximplant call and bridges audio to Cartesia Line Agents for real-time speech-to-speech conversations.

<blockquote>
  For the complete documentation index, see <a href="/llms.txt">llms.txt</a>.
</blockquote>

This example answers an inbound Voximplant call and bridges audio to Cartesia Line Agents for real-time speech-to-speech conversations.

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

## Prerequisites

* Set up an inbound entrypoint for the caller:
  * Phone number: [https://voximplant.com/docs/getting-started/basic-concepts/phone-numbers](https://voximplant.com/docs/getting-started/basic-concepts/phone-numbers)
  * WhatsApp: [https://voximplant.com/docs/guides/integrations/whatsapp](https://voximplant.com/docs/guides/integrations/whatsapp)
  * SIP user / SIP registration: [https://voximplant.com/docs/guides/calls/sip](https://voximplant.com/docs/guides/calls/sip)
  * App user: [https://voximplant.com/docs/getting-started/basic-concepts/users](https://voximplant.com/docs/getting-started/basic-concepts/users) (see also [https://voximplant.com/docs/guides/calls/scenarios#how-to-call-a-voximplant-user](https://voximplant.com/docs/guides/calls/scenarios#how-to-call-a-voximplant-user))
* Create a routing rule that points the destination (phone number / WhatsApp / SIP username / app user alias) to this scenario: [https://voximplant.com/docs/getting-started/basic-concepts/routing-rules](https://voximplant.com/docs/getting-started/basic-concepts/routing-rules)
* Store your Cartesia API key in Voximplant [Secrets](/platform/voxengine/secrets) under `CARTESIA_API_KEY`
* Store your Cartesia Agent ID in Voximplant `ApplicationStorage` under `CARTESIA_AGENT_ID` (the agent ID is not sensitive, so it can live in key-value storage)

## Session setup

Create a `Cartesia.AgentsClient` with your API key, API version, and agent ID:

```js title="Create Cartesia client"
voiceAIClient = await Cartesia.createAgentsClient({
  apiKey: VoxEngine.getSecretValue('CARTESIA_API_KEY'),
  cartesiaVersion: "2025-04-16",
  agentId: (await ApplicationStorage.get("CARTESIA_AGENT_ID")).value,
});
```

After client creation, send a `start` event with optional metadata:

```js title="Start session"
voiceAIClient.start({
  metadata: {
    channel: "voice",
    provider: "voximplant",
    mode: "inbound"
  }
});
```

## Events

The example logs key lifecycle and debugging events:

```js title="Events (example from the scenario)"
voiceAIClient.addEventListener(Cartesia.AgentsEvents.ACK, (event) => {
  Logger.write("===Cartesia.Agents.ACK===");
  if (event?.data) Logger.write(JSON.stringify(event.data));
});
```

## Notes

[See the VoxEngine API Reference for more details](https://voximplant.com/docs/references/voxengine/cartesia).

## Full VoxEngine scenario

```javascript title={"voxeengine-cartesia-inbound.js"} maxLines={0}
/**
 * Voximplant + Cartesia Line Agents connector demo
 * Scenario: answer an incoming call and bridge it to Cartesia.
 */

require(Modules.Cartesia);
require(Modules.ApplicationStorage);

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

    // Termination handlers
    call.addEventListener(CallEvents.Disconnected, () => VoxEngine.terminate());
    call.addEventListener(CallEvents.Failed, () => VoxEngine.terminate());

    try {
        call.answer();
        // Optional: record & transcribe the call. Note:`require(Modules.ASR)` needed for TranscriptionProvider enum
        // call.record({hd_audio: true, stereo: true, transcribe: true, provider: TranscriptionProvider.GOOGLE });

        // Create client and connect to Cartesia Agents
        voiceAIClient = await Cartesia.createAgentsClient({
            apiKey: VoxEngine.getSecretValue('CARTESIA_API_KEY'),
            cartesiaVersion: "2025-04-16",
            agentId: (await ApplicationStorage.get("CARTESIA_AGENT_ID")).value,
            onWebSocketClose: (event) => {
                Logger.write("===Cartesia.WebSocket.Close===");
                if (event) Logger.write(JSON.stringify(event));
                VoxEngine.terminate();
            },
        });

        // Start the client and pass optional metadata
        voiceAIClient.start({
            metadata: {channel: "voice", provider: "voximplant", mode: "inbound"},
        });

        // Send the call media to the Agent
        VoxEngine.sendMediaBetween(call, voiceAIClient);

        // Consolidated log only handlers for debugging
        [
            Cartesia.AgentsEvents.ACK,
            Cartesia.AgentsEvents.Clear,
            Cartesia.AgentsEvents.ConnectorInformation,
            Cartesia.AgentsEvents.DTMF,
            Cartesia.AgentsEvents.Unknown,
            Cartesia.AgentsEvents.WebSocketError,
            Cartesia.Events.WebSocketMediaStarted,
            Cartesia.Events.WebSocketMediaEnded,
        ].forEach((eventName) => {
            voiceAIClient.addEventListener(eventName, (event) => {
                Logger.write(`===${event.name}===>${JSON.stringify(event.data) || ""}`);
            });
        });
    } catch (error) {
        Logger.write("===UNHANDLED_ERROR===");
        Logger.write(error);
        voiceAIClient?.close();
        VoxEngine.terminate();
    }
});

```