How to Transfer Calls in AI Voice Agents Using SIP Telephony

Published: (December 29, 2025 at 05:47 AM EST)
3 min read
Source: Dev.to

Source: Dev.to

Overview

When a caller reaches a business, they expect a quick and clear resolution. An AI voice agent should know when to assist and when to hand the call over to a human. Call Transfer in VideoSDK lets your AI agent move an active SIP call to another phone number without disconnecting the caller, ensuring a seamless conversation flow.

How Call Transfer Works

  • The AI agent evaluates the caller’s intent to determine if a transfer is needed.
  • When a transfer is required, the agent triggers a function tool.
  • The function tool instructs the system to forward the ongoing SIP call to the specified number instantly, without requiring the caller to redial.
  • From the caller’s perspective, the transition is automatic and the call continues without drops or awkward pauses.

Setting Up the Call‑Transfer Agent

Below is a minimal example of an agent that can transfer calls using the transfer_call tool.

import os
import logging

from videosdk.agents import (
    Agent, AgentSession, CascadingPipeline, function_tool,
    WorkerJob, ConversationFlow, JobContext, RoomOptions, Options
)
from videosdk.plugins.deepgram import DeepgramSTT
from videosdk.plugins.google import GoogleLLM
from videosdk.plugins.cartesia import CartesiaTTS
from videosdk.plugins.silero import SileroVAD
from videosdk.plugins.turn_detector import TurnDetector, pre_download_model

# Set up basic logging
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
    handlers=[logging.StreamHandler()]
)

# Pre‑download the turn‑detector model
pre_download_model()


class CallTransferAgent(Agent):
    def __init__(self):
        super().__init__(
            instructions=(
                "You are the Call Transfer Agent. "
                "Help transfer ongoing calls to a new number using the transfer_call tool."
            )
        )

    async def on_enter(self) -> None:
        await self.session.say("Hello! How can I help you today?")

    async def on_exit(self) -> None:
        await self.session.say("Goodbye, and thank you for calling!")

    @function_tool
    async def transfer_call(self) -> None:
        """Transfer the call to the provided number."""
        token = os.getenv("VIDEOSDK_AUTH_TOKEN")
        transfer_to = os.getenv("CALL_TRANSFER_TO")
        return await self.session.call_transfer(token, transfer_to)


async def entrypoint(ctx: JobContext):
    agent = CallTransferAgent()
    conversation_flow = ConversationFlow(agent)

    pipeline = CascadingPipeline(
        stt=DeepgramSTT(),
        llm=GoogleLLM(),
        tts=CartesiaTTS(),
        vad=SileroVAD(),
        turn_detector=TurnDetector()
    )

    session = AgentSession(
        agent=agent,
        pipeline=pipeline,
        conversation_flow=conversation_flow
    )

    await session.start(wait_for_participant=True, run_until_shutdown=True)


def make_context() -> JobContext:
    room_options = RoomOptions(name="Call Transfer Agent", playground=True)
    return JobContext(room_options=room_options)


if __name__ == "__main__":
    job = WorkerJob(
        entrypoint=entrypoint,
        jobctx=make_context,
        options=Options(
            agent_id="YOUR_AGENT_ID",
            register=True,
            host="localhost",
            port=8081
        )
    )
    job.start()

Key Points in the Code

  • transfer_call function tool: Retrieves the VideoSDK auth token and the target phone number from environment variables, then calls self.session.call_transfer.
  • Pipeline components: Deepgram for speech‑to‑text, Google LLM for language understanding, Cartesia for text‑to‑speech, Silero VAD for voice activity detection, and TurnDetector for managing speaker turns.
  • Job configuration: Sets up a WorkerJob with the desired agent_id, host, and port.

Running the Agent

  1. Define the environment variables VIDEOSDK_AUTH_TOKEN and CALL_TRANSFER_TO.
  2. Execute the script (python your_script.py).
  3. The agent will wait for an inbound participant, handle the conversation, and transfer the call when the transfer_call tool is invoked.

Benefits of Call Transfer

  • Seamless handoff: Callers never experience dropped calls or need to redial.
  • Improved user experience: The conversation flows naturally, reducing frustration.
  • Scalable support: AI agents can handle routine queries and automatically route complex issues to human agents.

Additional Resources

  • Quick Start Example – detailed guide for inbound/outbound call handling and routing rules.
  • Call‑Transfer Implementation on GitHub – full repository with sample projects.
  • VideoSDK Documentation – comprehensive reference for all SDK features.
Back to Blog

Related posts

Read more »