> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zeroruntime.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Call Transfer

> Move an ongoing SIP call to another phone number without ending the session.

Call Transfer lets your AI Agent move an ongoing SIP call to another phone number without ending the current session. Instead of making the caller hang up and redial, the agent routes the call automatically.

<Note>
  This page covers transferring from your **agent code**. For the underlying SIP REFER mechanism and provider requirements, see [Call Transfer](/telephony/managing-calls/call-transfer) in the Telephony platform docs.
</Note>

## How Call Transfer Works

The agent evaluates the user’s intent to determine when a call transfer is required and then triggers the function tool.
When the function tool is triggered, it tells the system to move the call to another phone number.
The ongoing SIP call is forwarded to the new number instantly, without disconnecting or redialing.

## Setup

Expose a function tool on your agent that calls `session.transfer_call` with your auth token and the destination number.
&#x20;The agent invokes the tool when it detects the user wants to be transferred.

<CodeGroup>
  ```python title="Python" Python theme={null}
  import os
  from zeroruntime import Agent, Pipeline, function_tool

  class CallTransferAgent(Agent):
      def __init__(self, pipeline: Pipeline):
          super().__init__(
              agent_id="call-transfer",
              instructions="You are the Call Transfer Agent. Use the call_transfer tool to transfer the ongoing call to a new number.",
              pipeline=pipeline,
          )

      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, thank you for calling!")

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

  ```typescript title="Node JS" Node JS theme={null}
  import { Agent, Pipeline, function_tool } from '@zeroruntime/js-sdk';

  class CallTransferAgent extends Agent {
    constructor(pipeline: Pipeline) {
      super({
        agent_id: 'call-transfer',
        instructions:
          'You are the Call Transfer Agent. Use the call_transfer tool to transfer ' +
          'the ongoing call to a new number.',
        pipeline,
      });
    }

    async on_enter(): Promise<void> {
      await this.session!.say('Hello, how can I help you today?');
    }

    async on_exit(): Promise<void> {
      await this.session!.say('Goodbye, thank you for calling!');
    }

    // A tool held on a field is registered for you; the arrow keeps `this` bound
    // to the agent, so the tool reaches the live session the way `self` does.
    call_transfer = function_tool({
      name: 'call_transfer',
      description: 'Transfer the call to the provided number',
      parameters: {},
      execute: async () => {
        const transfer_to = process.env.CALL_TRANSFER_TO ?? '';
        return await this.session!.transfer_call(transfer_to);
      },
    });
  }
  ```
</CodeGroup>

<Note>
  See [Handoff vs Transfer](/build/agent-handoffs#handoff-vs-transfer) for the difference between Call Transfer and Agent Handoff.
</Note>

## What's Next

<CardGroup cols={2}>
  <Card title="Voicemail Detection" icon="voicemail" href="/build/telephony/voicemail-detection">
    Detect voicemail systems on outbound calls.
  </Card>

  <Card title="DTMF Events" icon="hashtag" href="/build/telephony/dtmf">
    Capture caller key presses.
  </Card>
</CardGroup>
