Voximplant now includes a native Cartesia Line / Agents connector that connects any Voximplant call to a Cartesia Line voice agent for real-time, speech-to-speech conversations—over PSTN, SIP, WebRTC, or WhatsApp Business Calling—without building custom media gateways or WebSocket streaming infrastructure.


This integration is available as a Voice AI Connector inside VoxEngine, Voximplant’s serverless Voice AI Orchestration environment. You deploy your agent logic on Cartesia Line (code-first, managed runtime), and Voximplant handles the telephony, media conversion, and real-time streaming so you can focus on agent behavior and production call flows.

 

Highlights

  • Cartesia Line voice agents on real calls — Connect Line agents to phone calls, WhatsApp and SIP infrastructure for inbound and outbound call flows
  • Leverage Cartesia’s extensive Text-to-Speech capabilities - choose from any of Cartesia’s voices or your own cloned voices without a separate TTS pipeline. Cartesia’s Realtime TTS continues to be available for Voximplant orchestrated pipelines.
  • Code-first agent development + managed runtime — Line runs your agent code in Cartesia’s managed runtime with auto-scaling and built-in audio orchestration, so you don’t need to stand up your own agent-serving stack for production voice.
  • Advanced telephony routing and control — manage simple to advanced call control, transfers, surveys, escalation logic, SIP routing, and compliance inside VoxEngine—while Line handles the agent conversation loop.

Developer notes

  • Native VoxEngine module — Load the integration with require(Modules.Cartesia); and create a client via Cartesia.createAgentsClient({ apiKey, agentId, cartesiaVersion, ... }).
  • Cartesia Calls API over WebSocket — VoxEngine bridges call audio to Cartesia Line via Line’s Calls API (WebSocket streaming) - this is handled automatically without any additional configuration.
  • Line Agent→VoxEngine coordination - Use VoxEngine’s AppEvents.HttpRequest to handle `POST messages from the Cartesia line script for coordinating tool calls and routing information. 
  • VoxEngine→Line Agent configuration - pass telephony related information and HTTP endpoints to the Line Agent by passing a metadata object with the agent client start method.
  • Barge-in and Turn-taking - interactivity between the agent and the caller/callee is handled completely by the Line Agent
  • Redefine telephony tools for Voximplant control — Line’s built-in tools like end_call and `transfer_call are designed to act inside Line’s calling environment. For Voximplant-controlled routing (warm transfers, surveys, SIP handoff), define your own passthrough tools in Line that signal VoxEngine out-of-band.

Demo video

-

Pricing and availability


The Cartesia Line / Agents connector follows the same Voice AI Connector pricing model as Voximplant’s other Voice AI connectors:

  • $0.001 per 15 seconds of audio streaming (0.4¢/min)
  • Price includes bidirectional audio (inbound + outbound)

As with Voximplant’s other Voice AI connectors, Voximplant charges for real-time streaming, while Cartesia Line usage is billed according to your Cartesia plan.

Quick start

 

The VoxEngine scenario below connects a Line Agent and listens for a call transfer command from the agent in response to a tool call.

// Voximplant VoxEngine scenario:
// - Streams caller audio <-> Cartesia Line agent (Agents connector)
// - Supports:
//   - end_call: hang up the caller leg
//   - call_transfer: place an outbound PSTN consult call and then bridge caller -> consult leg
//
// Configure these keys in Voximplant Application Storage:
// - CARTESIA_API_KEY
// - CARTESIA_AGENT_ID
// - PSTN_CALLER_ID (required for callPSTN; must be a real E.164 number in your Voximplant account)
//
// Call transfer in this demo always dials the public Voximplant demo number shown on the Cartesia Agents product page.


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


const CARTESIA_VERSION = "2025-04-16";
const CALL_TRANSFER_NUMBER = "+18339906144";


// Per-session control URL. Any HTTPS request to this URL triggers AppEvents.HttpRequest in this session.
// We'll pass it into Cartesia call metadata so the agent runtime can request telephony actions via HTTP.
let sessionControlUrl = null;


// Current call session state (single-call demo scenario).
let callerLeg = null;
let voiceAIClient = null;
let consultLeg = null;
let transferInProgress = false;
let transferred = false;


VoxEngine.addEventListener(AppEvents.Started, (appEvent) => {
 sessionControlUrl = appEvent.accessSecureURL;
 Logger.write(`===SESSION_CONTROL_URL_READY===>${JSON.stringify({accessSecureURL: sessionControlUrl}) || ""}`);
});


VoxEngine.addEventListener(AppEvents.HttpRequest, (appEvent) => {
 Logger.write(`===HTTP_CONTROL_REQUEST===>${JSON.stringify({method: appEvent.method, path: appEvent.path}) || ""}`);


 // Check for and handle control commands
 const cmd = JSON.parse(appEvent?.content);
 if (cmd.action === "end_call") {
   Logger.write(`===CONTROL_END_CALL===>${JSON.stringify(cmd) || ""}`);
   callerLeg.hangup();
   voiceAIClient?.close();
   VoxEngine.terminate();
 } else if (cmd.action === "call_transfer") {
   Logger.write(`===CONTROL_CALL_TRANSFER===>${JSON.stringify(cmd) || ""}`);
   callTransfer(cmd);
 } else {
   Logger.write(`===CONTROL_COMMAND_UNKNOWN===>${JSON.stringify(cmd) || ""}`);
 }
 return JSON.stringify({ok: true});
});


async function callTransfer(cmd) {
 if (transferInProgress || transferred) return;
 if (!callerLeg) return;


 transferInProgress = true;
 Logger.write(`===CALL_TRANSFER_REQUESTED===>${JSON.stringify(cmd || {}) || ""}`);


 // Detach the agent now for a blind transfer. Delay or conference for a warm transfer
 if (voiceAIClient) {
   VoxEngine.stopMediaBetween(callerLeg, voiceAIClient);
   voiceAIClient.close();
   voiceAIClient = null;
 }


 const currentPstnCallerId = (await ApplicationStorage.get("PSTN_CALLER_ID")).value;
 consultLeg = VoxEngine.callPSTN(CALL_TRANSFER_NUMBER, currentPstnCallerId, {followDiversion: true});


 consultLeg.addEventListener(CallEvents.Failed, () => {
   transferInProgress = false;
   Logger.write(`===CONSULT_CALL_FAILED===>${JSON.stringify({}) || ""}`);
   callerLeg.hangup();
 });


 consultLeg.addEventListener(CallEvents.Disconnected, (event) => {
   Logger.write(`===CONSULT_CALL_DISCONNECTED===>${JSON.stringify(event) || ""}`);
 });


 consultLeg.addEventListener(CallEvents.Connected, () => {
   Logger.write(`===CONSULT_CALL_CONNECTED===>${JSON.stringify({}) || ""}`);
   transferInProgress = false;
   transferred = true;
   VoxEngine.sendMediaBetween(callerLeg, consultLeg);
 });
}


function onWebSocketClose(event) {
 Logger.write(`===ON_WEB_SOCKET_CLOSE===>${JSON.stringify(event) || ""}`);
 // Ignore expected close during transfer
 if (transferInProgress || transferred || event.code === 1000) return;
 // otherwise end the call
 callerLeg.hangup();
 VoxEngine.terminate();
}


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


 // Termination functions - add cleanup and logging as needed
 call.addEventListener(CallEvents.Disconnected, () => VoxEngine.terminate());
 call.addEventListener(CallEvents.Failed, () => VoxEngine.terminate());


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


   voiceAIClient = await Cartesia.createAgentsClient({
     apiKey: (await ApplicationStorage.get("CARTESIA_API_KEY")).value,
     agentId: (await ApplicationStorage.get("CARTESIA_AGENT_ID")).value,
     cartesiaVersion: CARTESIA_VERSION,
     onWebSocketClose,
   });


   VoxEngine.sendMediaBetween(call, voiceAIClient);


   voiceAIClient.start({
     // Optional metadata passed into the Cartesia agent
     metadata: {
       from: call.callerid(),
       to: call.number(),
       vox_session_control_url: sessionControlUrl, // Control plane from Cartesia via HTTPS callback
     },
   });


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


See the corresponding Cartesia Agents code here.

References


Voximplant product information and documentation:

Cartesia Line Agents product information and documentation: