Transfer call
Transfer a call to a new destination. If the transfer is unsuccessful, a call.hangup webhook for the other call (Leg B) will be sent indicating that the transfer could not be completed. The original call will remain active and may be issued additional commands, potentially transfering the call to an alternate destination.
Expected Webhooks:
call.initiatedcall.bridgedto Leg Bcall.answeredorcall.hangupcall.machine.detection.endedifanswering_machine_detectionwas requestedcall.machine.greeting.endedifanswering_machine_detectionwas requested to detect the end of machine greetingcall.machine.premium.detection.endedifanswering_machine_detection=premiumwas requestedcall.machine.premium.greeting.endedifanswering_machine_detection=premiumwas requested and a beep was detectedcall.machine.premium.call_screening.detectedifanswering_machine_detection=premium_ios_call_screening_detectionwas requested and an Apple Call Screening tone was detected
import Telnyx from 'telnyx';
const client = new Telnyx({
apiKey: process.env['TELNYX_API_KEY'], // This is the default and can be omitted
});
const response = await client.calls.actions.transfer('call_control_id', {
to: '+18005550100 or sip:[email protected];secure=srtp',
});
console.log(response.data);import os
from telnyx import Telnyx
client = Telnyx(
api_key=os.environ.get("TELNYX_API_KEY"), # This is the default and can be omitted
)
response = client.calls.actions.transfer(
call_control_id="call_control_id",
to="+18005550100 or sip:[email protected];secure=srtp",
)
print(response.data)
package main
import (
"context"
"fmt"
"github.com/team-telnyx/telnyx-go"
"github.com/team-telnyx/telnyx-go/option"
)
func main() {
client := telnyx.NewClient(
option.WithAPIKey("My API Key"),
)
response, err := client.Calls.Actions.Transfer(
context.TODO(),
"call_control_id",
telnyx.CallActionTransferParams{
To: "+18005550100 or sip:[email protected];secure=srtp",
},
)
if err != nil {
panic(err.Error())
}
fmt.Printf("%+v\n", response.Data)
}
package com.telnyx.sdk.example;
import com.telnyx.sdk.client.TelnyxClient;
import com.telnyx.sdk.client.okhttp.TelnyxOkHttpClient;
import com.telnyx.sdk.models.calls.actions.ActionTransferParams;
import com.telnyx.sdk.models.calls.actions.ActionTransferResponse;
public final class Main {
private Main() {}
public static void main(String[] args) {
TelnyxClient client = TelnyxOkHttpClient.fromEnv();
ActionTransferParams params = ActionTransferParams.builder()
.callControlId("call_control_id")
.to("+18005550100 or sip:[email protected];secure=srtp")
.build();
ActionTransferResponse response = client.calls().actions().transfer(params);
}
}require "telnyx"
telnyx = Telnyx::Client.new(api_key: "My API Key")
response = telnyx.calls.actions.transfer(
"call_control_id",
to: "+18005550100 or sip:[email protected];secure=srtp"
)
puts(response)<?php
require_once dirname(__DIR__) . '/vendor/autoload.php';
use Telnyx\Client;
use Telnyx\Core\Exceptions\APIException;
$client = new Client(apiKey: getenv('TELNYX_API_KEY') ?: 'My API Key');
try {
$response = $client->calls->actions->transfer(
'call_control_id',
to: '+18005550100 or sip:[email protected];secure=srtp',
answeringMachineDetection: 'detect',
answeringMachineDetectionConfig: [
'afterGreetingSilenceMillis' => 1000,
'betweenWordsSilenceMillis' => 1000,
'greetingDurationMillis' => 1000,
'greetingSilenceDurationMillis' => 2000,
'greetingTotalAnalysisTimeMillis' => 50000,
'initialSilenceMillis' => 1000,
'maximumNumberOfWords' => 1000,
'maximumWordLengthMillis' => 2000,
'silenceThreshold' => 512,
'totalAnalysisTimeMillis' => 5000,
],
audioURL: 'http://www.example.com/sounds/greeting.wav',
clientState: 'aGF2ZSBhIG5pY2UgZGF5ID1d',
commandID: '891510ac-f3e4-11e8-af5b-de00688a4901',
customHeaders: [
['name' => 'head_1', 'value' => 'val_1'],
['name' => 'head_2', 'value' => 'val_2'],
],
earlyMedia: true,
from: '+18005550101',
fromDisplayName: 'Company Name',
mediaEncryption: 'SRTP',
mediaName: 'my_media_uploaded_to_media_storage_api',
muteDtmf: 'opposite',
parkAfterUnbridge: 'self',
preferredCodecs: 'G722,PCMU,PCMA,G729,OPUS,VP8,H264',
privacy: 'id',
record: 'record-from-answer',
recordChannels: 'single',
recordCustomFileName: 'my_recording_file_name',
recordFormat: 'wav',
recordMaxLength: 1000,
recordTimeoutSecs: 100,
recordTrack: 'outbound',
recordTrim: 'trim-silence',
sendDigitsOnAnswer: 'wwww200',
sipAuthPassword: 'password',
sipAuthUsername: 'username',
sipHeaders: [['name' => 'User-to-User', 'value' => 'value']],
sipRegion: 'Canada',
sipTransportProtocol: 'TLS',
soundModifications: [
'octaves' => 0.1, 'pitch' => 0.8, 'semitone' => -2, 'track' => 'both'
],
targetLegClientState: 'aGF2ZSBhIG5pY2UgZGF5ID1d',
timeLimitSecs: 60,
timeoutSecs: 60,
webhookRetriesPolicies: [
'call.answered' => ['retriesMs' => [1000, 2000, 5000]]
],
webhookURL: 'https://www.example.com/server-b/',
webhookURLMethod: 'POST',
webhookURLs: [
'call.answered' => 'https://www.example.com/webhooks/answered',
'call.hangup' => 'https://www.example.com/webhooks/hangup',
],
webhookURLsMethod: 'POST',
);
var_dump($response);
} catch (APIException $e) {
echo $e->getMessage();
}telnyx calls:actions transfer \
--api-key 'My API Key' \
--call-control-id call_control_id \
--to '+18005550100 or sip:[email protected];secure=srtp'curl --request POST \
--url https://api.telnyx.com/v2/calls/{call_control_id}/actions/transfer \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"to": "+18005550100 or sip:[email protected];secure=srtp",
"from": "+18005550101",
"from_display_name": "Company Name",
"audio_url": "http://www.example.com/sounds/greeting.wav",
"send_digits_on_answer": "wwww200",
"timeout_secs": 60,
"time_limit_secs": 60,
"webhook_url": "https://www.example.com/server-b/",
"webhook_url_method": "POST",
"answering_machine_detection": "detect",
"answering_machine_detection_config": {
"total_analysis_time_millis": 5000,
"after_greeting_silence_millis": 1000,
"between_words_silence_millis": 1000,
"greeting_duration_millis": 1000,
"initial_silence_millis": 1000,
"maximum_number_of_words": 1000,
"maximum_word_length_millis": 2000,
"silence_threshold": 512,
"greeting_total_analysis_time_millis": 50000,
"greeting_silence_duration_millis": 2000
},
"custom_headers": [
{
"name": "head_1",
"value": "val_1"
},
{
"name": "head_2",
"value": "val_2"
}
],
"client_state": "aGF2ZSBhIG5pY2UgZGF5ID1d",
"command_id": "891510ac-f3e4-11e8-af5b-de00688a4901",
"early_media": true,
"media_encryption": "SRTP",
"sip_auth_username": "username",
"sip_auth_password": "password",
"sip_headers": [
{
"name": "User-to-User",
"value": "value"
}
],
"sip_transport_protocol": "TLS"
}
'{
"data": {
"result": "ok"
}
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
Unique identifier and token for controlling the call
Body
Transfer call request
The DID or SIP URI to dial out to. For SIP URI destinations, append ;secure=true or ;secure=srtp to enable SRTP media encryption for that endpoint, or ;secure=dtls to enable DTLS media encryption for that endpoint. If media_encryption is set to SRTP or DTLS, it takes precedence over any per-endpoint secure URI parameter. You may also append a comma followed by DTMF digits (e.g. +18004247767,200) to play those digits as DTMF once the transfer destination answers — equivalent to setting send_digits_on_answer separately. If both are present, the explicit send_digits_on_answer parameter takes precedence.
"+18005550100 or sip:[email protected];secure=srtp"
The from number to be used as the caller id presented to the destination (to number). The number should be in +E164 format. This attribute will default to the to number of the original call if omitted.
"+18005550101"
The to number of an active inbound call, in +E164 format. Telnyx checks whether there is currently an active inbound call where to matches this diversion value and from matches the from number supplied for this request. If such a call exists, the from number is treated as verified (since it is already on an active inbound call to you) and can be used as the caller id for this outbound call.
"+18005550101"
The from_display_name string to be used as the caller id name (SIP From Display Name) presented to the destination (to number). The string should have a maximum of 128 characters, containing only letters, numbers, spaces, and -_~!.+ special characters. If ommited, the display name will be the same as the number in the from field.
"Company Name"
Indicates the privacy level to be used for the call. When set to id, caller ID information (name and number) will be hidden from the called party. When set to none or omitted, caller ID will be shown normally.
id, none "id"
The URL of a file to be played back when the transfer destination answers before bridging the call. The URL can point to either a WAV or MP3 file. media_name and audio_url cannot be used together in one request.
"http://example.com/message.wav"
DTMF digits to send automatically after the transfer destination answers. Useful for reaching an extension behind an IVR (e.g. "200" to dial extension 200 once the called party picks up). Allowed characters: 0-9, A-D, w (0.5s pause), W (1s pause), *, #. Maximum 64 characters. When omitted, no automatic DTMF is sent. May also be supplied inline by appending ,<digits> to to (e.g. to=+18004247767,200); if both forms are present, this explicit field takes precedence.
"wwww200"
If set to false, early media will not be passed to the originating leg.
false
The media_name of a file to be played back when the transfer destination answers before bridging the call. The media_name must point to a file previously uploaded to api.telnyx.com/v2/media by the same user/organization. The file must either be a WAV or MP3 file.
"my_media_uploaded_to_media_storage_api"
The number of seconds that Telnyx will wait for the call to be answered by the destination to which it is being transferred. If the timeout is reached before an answer is received, the call will hangup and a call.hangup webhook with a hangup_cause of timeout will be sent. Minimum value is 5 seconds. Maximum value is 600 seconds.
60
Sets the maximum duration of a Call Control Leg in seconds. If the time limit is reached, the call will hangup and a call.hangup webhook with a hangup_cause of time_limit will be sent. For example, by setting a time limit of 120 seconds, a Call Leg will be automatically terminated two minutes after being answered. The default time limit is 14400 seconds or 4 hours and this is also the maximum allowed call length.
30 <= x <= 14400600
Specifies behavior after the bridge ends (i.e. the opposite leg either hangs up or is transferred). If supplied with the value self, the current leg will be parked after unbridge. If not set, the default behavior is to hang up the leg.
"self"
Enables Answering Machine Detection. When a call is answered, Telnyx runs real-time detection to determine if it was picked up by a human or a machine and sends an call.machine.detection.ended webhook with the analysis result. If 'greeting_end' or 'detect_words' is used and a 'machine' is detected, you will receive another 'call.machine.greeting.ended' webhook when the answering machine greeting ends with a beep or silence. If detect_beep is used, you will only receive 'call.machine.greeting.ended' if a beep is detected. If answering_machine_detection is set to premium_ios_call_screening_detection, Premium AMD runs with iOS Call Screening support: after an initial machine result, Telnyx listens for the iOS call-screening prompt to end or for an Apple Call Screening tone, sends call.machine.premium.greeting.ended with result=prompt_ended or call.machine.premium.call_screening.detected with result=screening respectively. When the Apple Call Screening tone is detected, Premium AMD is restarted on the screened call and a call.machine.premium.detection.ended webhook with the post-screening classification follows.
premium, premium_ios_call_screening_detection, detect, detect_beep, detect_words, greeting_end, disabled Optional configuration parameters to modify 'answering_machine_detection' performance. Only total_analysis_time_millis and greeting_duration_millis parameters are applicable when premium is selected as answering_machine_detection. prompt_end_timeout_millis is additionally applicable when premium_ios_call_screening_detection is selected.
Show child attributes
Show child attributes
Custom headers to be added to the SIP INVITE.
Show child attributes
Show child attributes
[
{ "name": "head_1", "value": "val_1" },
{ "name": "head_2", "value": "val_2" }
]
Use this field to add state to every subsequent webhook. It must be a valid Base-64 encoded string.
"aGF2ZSBhIG5pY2UgZGF5ID1d"
Use this field to add state to every subsequent webhook for the new leg. It must be a valid Base-64 encoded string.
"aGF2ZSBhIG5pY2UgZGF5ID1d"
Use this field to avoid duplicate commands. Telnyx will ignore any command with the same command_id for the same call_control_id.
"891510ac-f3e4-11e8-af5b-de00688a4901"
Defines whether media should be encrypted on the new call leg. For SIP URI destinations, media encryption can also be requested per endpoint with the secure URI parameter: ;secure=true or ;secure=srtp enables SRTP, and ;secure=dtls enables DTLS. This parameter, when set to SRTP or DTLS, takes precedence over the per-endpoint secure value.
disabled, SRTP, DTLS SIP Authentication username used for SIP challenges.
"username"
SIP Authentication password used for SIP challenges.
"password"
SIP headers to be added to the SIP INVITE. Currently only User-to-User header is supported.
Show child attributes
Show child attributes
[
{ "name": "User-to-User", "value": "value" }
]
Defines SIP transport protocol to be used on the call.
UDP, TCP, TLS Use this field to modify sound effects, for example adjust the pitch.
Show child attributes
Show child attributes
{
"pitch": 0.8,
"semitone": -2,
"octaves": 0.1,
"track": "both"
}
Use this field to override the URL for which Telnyx will send subsequent webhooks to for this call.
"https://www.example.com/server-b/"
HTTP request type used for webhook_url.
POST, GET "GET"
When enabled, DTMF tones are not passed to the call participant. The webhooks containing the DTMF information will be sent.
none, both, self, opposite "opposite"
Start recording automatically after an event. Disabled by default.
record-from-answer "record-from-answer"
Defines which channel should be recorded ('single' or 'dual') when record is specified.
single, dual "single"
Defines the format of the recording ('wav' or 'mp3') when record is specified.
wav, mp3 "wav"
Defines the maximum length for the recording in seconds when record is specified. The minimum value is 0. The maximum value is 43200. The default value is 0 (infinite).
1000
The number of seconds that Telnyx will wait for the recording to be stopped if silence is detected when record is specified. The timer only starts when the speech is detected. Please note that call transcription is used to detect silence and the related charge will be applied. The minimum value is 0. The default value is 0 (infinite).
100
The audio track to be recorded. Can be either both, inbound or outbound. If only single track is specified (inbound, outbound), channels configuration is ignored and it will be recorded as mono (single channel).
both, inbound, outbound "outbound"
When set to trim-silence, silence will be removed from the beginning and end of the recording.
trim-silence "trim-silence"
The custom recording file name to be used instead of the default call_leg_id. Telnyx will still add a Unix timestamp suffix.
1 - 40"my_recording_file_name"
Defines the SIP region to be used for the call.
US, Europe, Canada, Australia, Middle East "Canada"
The list of comma-separated codecs in order of preference to be used during the call. The codecs supported are G722, PCMU, PCMA, G729, OPUS, VP8, H264, AMR-WB.
"G722,PCMU,PCMA,G729,OPUS,VP8,H264"
A map of event types to arrays of webhook URLs. When an event of the specified type occurs, the webhook URLs associated with that event type will be called instead of webhook_url. Events not mapped here will use the default webhook_url.
Show child attributes
Show child attributes
{
"call.answered": ["https://www.example.com/webhooks/answered"],
"call.hangup": ["https://www.example.com/webhooks/hangup"]
}
HTTP request method to invoke webhook_urls.
POST, GET "POST"
A map of event types to retry policies. Each retry policy contains an array of retries_ms specifying the delays between retry attempts in milliseconds. Maximum 5 retries, total delay cannot exceed 60 seconds.
Show child attributes
Show child attributes
{
"call.answered": { "retries_ms": [1000, 2000, 5000] }
}
When set to true, routes the call directly to the mobile device associated with the destination Telnyx Mobile number, bypassing Inbound Calls Interception configured in the Telnyx Portal under Mobile Numbers → select the number → Voice → Call Interception. Use this when transferring an intercepted call to the mobile device to prevent the call from being intercepted again. Defaults to false.
true
Response
Successful response upon making a call control command.
Show child attributes
Show child attributes
{ "result": "ok" }
Was this page helpful?
import Telnyx from 'telnyx';
const client = new Telnyx({
apiKey: process.env['TELNYX_API_KEY'], // This is the default and can be omitted
});
const response = await client.calls.actions.transfer('call_control_id', {
to: '+18005550100 or sip:[email protected];secure=srtp',
});
console.log(response.data);import os
from telnyx import Telnyx
client = Telnyx(
api_key=os.environ.get("TELNYX_API_KEY"), # This is the default and can be omitted
)
response = client.calls.actions.transfer(
call_control_id="call_control_id",
to="+18005550100 or sip:[email protected];secure=srtp",
)
print(response.data)
package main
import (
"context"
"fmt"
"github.com/team-telnyx/telnyx-go"
"github.com/team-telnyx/telnyx-go/option"
)
func main() {
client := telnyx.NewClient(
option.WithAPIKey("My API Key"),
)
response, err := client.Calls.Actions.Transfer(
context.TODO(),
"call_control_id",
telnyx.CallActionTransferParams{
To: "+18005550100 or sip:[email protected];secure=srtp",
},
)
if err != nil {
panic(err.Error())
}
fmt.Printf("%+v\n", response.Data)
}
package com.telnyx.sdk.example;
import com.telnyx.sdk.client.TelnyxClient;
import com.telnyx.sdk.client.okhttp.TelnyxOkHttpClient;
import com.telnyx.sdk.models.calls.actions.ActionTransferParams;
import com.telnyx.sdk.models.calls.actions.ActionTransferResponse;
public final class Main {
private Main() {}
public static void main(String[] args) {
TelnyxClient client = TelnyxOkHttpClient.fromEnv();
ActionTransferParams params = ActionTransferParams.builder()
.callControlId("call_control_id")
.to("+18005550100 or sip:[email protected];secure=srtp")
.build();
ActionTransferResponse response = client.calls().actions().transfer(params);
}
}require "telnyx"
telnyx = Telnyx::Client.new(api_key: "My API Key")
response = telnyx.calls.actions.transfer(
"call_control_id",
to: "+18005550100 or sip:[email protected];secure=srtp"
)
puts(response)<?php
require_once dirname(__DIR__) . '/vendor/autoload.php';
use Telnyx\Client;
use Telnyx\Core\Exceptions\APIException;
$client = new Client(apiKey: getenv('TELNYX_API_KEY') ?: 'My API Key');
try {
$response = $client->calls->actions->transfer(
'call_control_id',
to: '+18005550100 or sip:[email protected];secure=srtp',
answeringMachineDetection: 'detect',
answeringMachineDetectionConfig: [
'afterGreetingSilenceMillis' => 1000,
'betweenWordsSilenceMillis' => 1000,
'greetingDurationMillis' => 1000,
'greetingSilenceDurationMillis' => 2000,
'greetingTotalAnalysisTimeMillis' => 50000,
'initialSilenceMillis' => 1000,
'maximumNumberOfWords' => 1000,
'maximumWordLengthMillis' => 2000,
'silenceThreshold' => 512,
'totalAnalysisTimeMillis' => 5000,
],
audioURL: 'http://www.example.com/sounds/greeting.wav',
clientState: 'aGF2ZSBhIG5pY2UgZGF5ID1d',
commandID: '891510ac-f3e4-11e8-af5b-de00688a4901',
customHeaders: [
['name' => 'head_1', 'value' => 'val_1'],
['name' => 'head_2', 'value' => 'val_2'],
],
earlyMedia: true,
from: '+18005550101',
fromDisplayName: 'Company Name',
mediaEncryption: 'SRTP',
mediaName: 'my_media_uploaded_to_media_storage_api',
muteDtmf: 'opposite',
parkAfterUnbridge: 'self',
preferredCodecs: 'G722,PCMU,PCMA,G729,OPUS,VP8,H264',
privacy: 'id',
record: 'record-from-answer',
recordChannels: 'single',
recordCustomFileName: 'my_recording_file_name',
recordFormat: 'wav',
recordMaxLength: 1000,
recordTimeoutSecs: 100,
recordTrack: 'outbound',
recordTrim: 'trim-silence',
sendDigitsOnAnswer: 'wwww200',
sipAuthPassword: 'password',
sipAuthUsername: 'username',
sipHeaders: [['name' => 'User-to-User', 'value' => 'value']],
sipRegion: 'Canada',
sipTransportProtocol: 'TLS',
soundModifications: [
'octaves' => 0.1, 'pitch' => 0.8, 'semitone' => -2, 'track' => 'both'
],
targetLegClientState: 'aGF2ZSBhIG5pY2UgZGF5ID1d',
timeLimitSecs: 60,
timeoutSecs: 60,
webhookRetriesPolicies: [
'call.answered' => ['retriesMs' => [1000, 2000, 5000]]
],
webhookURL: 'https://www.example.com/server-b/',
webhookURLMethod: 'POST',
webhookURLs: [
'call.answered' => 'https://www.example.com/webhooks/answered',
'call.hangup' => 'https://www.example.com/webhooks/hangup',
],
webhookURLsMethod: 'POST',
);
var_dump($response);
} catch (APIException $e) {
echo $e->getMessage();
}telnyx calls:actions transfer \
--api-key 'My API Key' \
--call-control-id call_control_id \
--to '+18005550100 or sip:[email protected];secure=srtp'curl --request POST \
--url https://api.telnyx.com/v2/calls/{call_control_id}/actions/transfer \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"to": "+18005550100 or sip:[email protected];secure=srtp",
"from": "+18005550101",
"from_display_name": "Company Name",
"audio_url": "http://www.example.com/sounds/greeting.wav",
"send_digits_on_answer": "wwww200",
"timeout_secs": 60,
"time_limit_secs": 60,
"webhook_url": "https://www.example.com/server-b/",
"webhook_url_method": "POST",
"answering_machine_detection": "detect",
"answering_machine_detection_config": {
"total_analysis_time_millis": 5000,
"after_greeting_silence_millis": 1000,
"between_words_silence_millis": 1000,
"greeting_duration_millis": 1000,
"initial_silence_millis": 1000,
"maximum_number_of_words": 1000,
"maximum_word_length_millis": 2000,
"silence_threshold": 512,
"greeting_total_analysis_time_millis": 50000,
"greeting_silence_duration_millis": 2000
},
"custom_headers": [
{
"name": "head_1",
"value": "val_1"
},
{
"name": "head_2",
"value": "val_2"
}
],
"client_state": "aGF2ZSBhIG5pY2UgZGF5ID1d",
"command_id": "891510ac-f3e4-11e8-af5b-de00688a4901",
"early_media": true,
"media_encryption": "SRTP",
"sip_auth_username": "username",
"sip_auth_password": "password",
"sip_headers": [
{
"name": "User-to-User",
"value": "value"
}
],
"sip_transport_protocol": "TLS"
}
'{
"data": {
"result": "ok"
}
}