Skip to main content
POST
/
agents
/
{agent_id}
/
phone-numbers
Register Phone Number
curl --request POST \
  --url https://api.example.com/agents/{agent_id}/phone-numbers \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "phone_number": "<string>",
  "provider": "<string>",
  "trunk_numbers": [
    "<string>"
  ],
  "allowed_addresses": [
    "<string>"
  ],
  "allowed_numbers": [
    "<string>"
  ],
  "auth_username": "<string>",
  "auth_password": "<string>",
  "enable_outbound": false,
  "outbound_address": "<string>",
  "outbound_numbers": [
    "<string>"
  ],
  "outbound_transport": "AUTO",
  "destination_country": "<string>",
  "media_encryption": "ALLOW",
  "krisp_enabled": true,
  "ringing_timeout_seconds": 30,
  "max_call_duration_seconds": 3600,
  "hide_phone_number": false,
  "custom_headers": {},
  "headers_to_attributes": {},
  "dtmf_config": {
    "auto_navigate_ivr": true,
    "dtmf_sequence": "*123#ww456",
    "dtmf_timeout": 30,
    "ivr_detection": true
  },
  "transfer_config": {
    "allowed_destinations": [
      "tel:+15105550100"
    ],
    "cold_transfer_enabled": true,
    "requires_confirmation": true,
    "supervisor_phone": "tel:+15105550100",
    "warm_transfer_enabled": false
  },
  "agent_features": {
    "call_screening": false,
    "recording_enabled": true,
    "sentiment_analysis": true,
    "transcription_enabled": true
  },
  "metadata": {},
  "provider_config": {}
}
'
import requests

url = "https://api.example.com/agents/{agent_id}/phone-numbers"

payload = {
"phone_number": "<string>",
"provider": "<string>",
"trunk_numbers": ["<string>"],
"allowed_addresses": ["<string>"],
"allowed_numbers": ["<string>"],
"auth_username": "<string>",
"auth_password": "<string>",
"enable_outbound": False,
"outbound_address": "<string>",
"outbound_numbers": ["<string>"],
"outbound_transport": "AUTO",
"destination_country": "<string>",
"media_encryption": "ALLOW",
"krisp_enabled": True,
"ringing_timeout_seconds": 30,
"max_call_duration_seconds": 3600,
"hide_phone_number": False,
"custom_headers": {},
"headers_to_attributes": {},
"dtmf_config": {
"auto_navigate_ivr": True,
"dtmf_sequence": "*123#ww456",
"dtmf_timeout": 30,
"ivr_detection": True
},
"transfer_config": {
"allowed_destinations": ["tel:+15105550100"],
"cold_transfer_enabled": True,
"requires_confirmation": True,
"supervisor_phone": "tel:+15105550100",
"warm_transfer_enabled": False
},
"agent_features": {
"call_screening": False,
"recording_enabled": True,
"sentiment_analysis": True,
"transcription_enabled": True
},
"metadata": {},
"provider_config": {}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
phone_number: '<string>',
provider: '<string>',
trunk_numbers: ['<string>'],
allowed_addresses: ['<string>'],
allowed_numbers: ['<string>'],
auth_username: '<string>',
auth_password: '<string>',
enable_outbound: false,
outbound_address: '<string>',
outbound_numbers: ['<string>'],
outbound_transport: 'AUTO',
destination_country: '<string>',
media_encryption: 'ALLOW',
krisp_enabled: true,
ringing_timeout_seconds: 30,
max_call_duration_seconds: 3600,
hide_phone_number: false,
custom_headers: {},
headers_to_attributes: {},
dtmf_config: {
auto_navigate_ivr: true,
dtmf_sequence: '*123#ww456',
dtmf_timeout: 30,
ivr_detection: true
},
transfer_config: {
allowed_destinations: ['tel:+15105550100'],
cold_transfer_enabled: true,
requires_confirmation: true,
supervisor_phone: 'tel:+15105550100',
warm_transfer_enabled: false
},
agent_features: {
call_screening: false,
recording_enabled: true,
sentiment_analysis: true,
transcription_enabled: true
},
metadata: {},
provider_config: {}
})
};

fetch('https://api.example.com/agents/{agent_id}/phone-numbers', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));
<?php

$curl = curl_init();

curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/agents/{agent_id}/phone-numbers",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'phone_number' => '<string>',
'provider' => '<string>',
'trunk_numbers' => [
'<string>'
],
'allowed_addresses' => [
'<string>'
],
'allowed_numbers' => [
'<string>'
],
'auth_username' => '<string>',
'auth_password' => '<string>',
'enable_outbound' => false,
'outbound_address' => '<string>',
'outbound_numbers' => [
'<string>'
],
'outbound_transport' => 'AUTO',
'destination_country' => '<string>',
'media_encryption' => 'ALLOW',
'krisp_enabled' => true,
'ringing_timeout_seconds' => 30,
'max_call_duration_seconds' => 3600,
'hide_phone_number' => false,
'custom_headers' => [

],
'headers_to_attributes' => [

],
'dtmf_config' => [
'auto_navigate_ivr' => true,
'dtmf_sequence' => '*123#ww456',
'dtmf_timeout' => 30,
'ivr_detection' => true
],
'transfer_config' => [
'allowed_destinations' => [
'tel:+15105550100'
],
'cold_transfer_enabled' => true,
'requires_confirmation' => true,
'supervisor_phone' => 'tel:+15105550100',
'warm_transfer_enabled' => false
],
'agent_features' => [
'call_screening' => false,
'recording_enabled' => true,
'sentiment_analysis' => true,
'transcription_enabled' => true
],
'metadata' => [

],
'provider_config' => [

]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
package main

import (
"fmt"
"strings"
"net/http"
"io"
)

func main() {

url := "https://api.example.com/agents/{agent_id}/phone-numbers"

payload := strings.NewReader("{\n \"phone_number\": \"<string>\",\n \"provider\": \"<string>\",\n \"trunk_numbers\": [\n \"<string>\"\n ],\n \"allowed_addresses\": [\n \"<string>\"\n ],\n \"allowed_numbers\": [\n \"<string>\"\n ],\n \"auth_username\": \"<string>\",\n \"auth_password\": \"<string>\",\n \"enable_outbound\": false,\n \"outbound_address\": \"<string>\",\n \"outbound_numbers\": [\n \"<string>\"\n ],\n \"outbound_transport\": \"AUTO\",\n \"destination_country\": \"<string>\",\n \"media_encryption\": \"ALLOW\",\n \"krisp_enabled\": true,\n \"ringing_timeout_seconds\": 30,\n \"max_call_duration_seconds\": 3600,\n \"hide_phone_number\": false,\n \"custom_headers\": {},\n \"headers_to_attributes\": {},\n \"dtmf_config\": {\n \"auto_navigate_ivr\": true,\n \"dtmf_sequence\": \"*123#ww456\",\n \"dtmf_timeout\": 30,\n \"ivr_detection\": true\n },\n \"transfer_config\": {\n \"allowed_destinations\": [\n \"tel:+15105550100\"\n ],\n \"cold_transfer_enabled\": true,\n \"requires_confirmation\": true,\n \"supervisor_phone\": \"tel:+15105550100\",\n \"warm_transfer_enabled\": false\n },\n \"agent_features\": {\n \"call_screening\": false,\n \"recording_enabled\": true,\n \"sentiment_analysis\": true,\n \"transcription_enabled\": true\n },\n \"metadata\": {},\n \"provider_config\": {}\n}")

req, _ := http.NewRequest("POST", url, payload)

req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")

res, _ := http.DefaultClient.Do(req)

defer res.Body.Close()
body, _ := io.ReadAll(res.Body)

fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.post("https://api.example.com/agents/{agent_id}/phone-numbers")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"phone_number\": \"<string>\",\n \"provider\": \"<string>\",\n \"trunk_numbers\": [\n \"<string>\"\n ],\n \"allowed_addresses\": [\n \"<string>\"\n ],\n \"allowed_numbers\": [\n \"<string>\"\n ],\n \"auth_username\": \"<string>\",\n \"auth_password\": \"<string>\",\n \"enable_outbound\": false,\n \"outbound_address\": \"<string>\",\n \"outbound_numbers\": [\n \"<string>\"\n ],\n \"outbound_transport\": \"AUTO\",\n \"destination_country\": \"<string>\",\n \"media_encryption\": \"ALLOW\",\n \"krisp_enabled\": true,\n \"ringing_timeout_seconds\": 30,\n \"max_call_duration_seconds\": 3600,\n \"hide_phone_number\": false,\n \"custom_headers\": {},\n \"headers_to_attributes\": {},\n \"dtmf_config\": {\n \"auto_navigate_ivr\": true,\n \"dtmf_sequence\": \"*123#ww456\",\n \"dtmf_timeout\": 30,\n \"ivr_detection\": true\n },\n \"transfer_config\": {\n \"allowed_destinations\": [\n \"tel:+15105550100\"\n ],\n \"cold_transfer_enabled\": true,\n \"requires_confirmation\": true,\n \"supervisor_phone\": \"tel:+15105550100\",\n \"warm_transfer_enabled\": false\n },\n \"agent_features\": {\n \"call_screening\": false,\n \"recording_enabled\": true,\n \"sentiment_analysis\": true,\n \"transcription_enabled\": true\n },\n \"metadata\": {},\n \"provider_config\": {}\n}")
.asString();
require 'uri'
require 'net/http'

url = URI("https://api.example.com/agents/{agent_id}/phone-numbers")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"phone_number\": \"<string>\",\n \"provider\": \"<string>\",\n \"trunk_numbers\": [\n \"<string>\"\n ],\n \"allowed_addresses\": [\n \"<string>\"\n ],\n \"allowed_numbers\": [\n \"<string>\"\n ],\n \"auth_username\": \"<string>\",\n \"auth_password\": \"<string>\",\n \"enable_outbound\": false,\n \"outbound_address\": \"<string>\",\n \"outbound_numbers\": [\n \"<string>\"\n ],\n \"outbound_transport\": \"AUTO\",\n \"destination_country\": \"<string>\",\n \"media_encryption\": \"ALLOW\",\n \"krisp_enabled\": true,\n \"ringing_timeout_seconds\": 30,\n \"max_call_duration_seconds\": 3600,\n \"hide_phone_number\": false,\n \"custom_headers\": {},\n \"headers_to_attributes\": {},\n \"dtmf_config\": {\n \"auto_navigate_ivr\": true,\n \"dtmf_sequence\": \"*123#ww456\",\n \"dtmf_timeout\": 30,\n \"ivr_detection\": true\n },\n \"transfer_config\": {\n \"allowed_destinations\": [\n \"tel:+15105550100\"\n ],\n \"cold_transfer_enabled\": true,\n \"requires_confirmation\": true,\n \"supervisor_phone\": \"tel:+15105550100\",\n \"warm_transfer_enabled\": false\n },\n \"agent_features\": {\n \"call_screening\": false,\n \"recording_enabled\": true,\n \"sentiment_analysis\": true,\n \"transcription_enabled\": true\n },\n \"metadata\": {},\n \"provider_config\": {}\n}"

response = http.request(request)
puts response.read_body
{
  "agent_id": "<string>",
  "phone_number": "<string>",
  "provider": "<string>",
  "sip_uri": "<string>",
  "dispatch_rule_id": "<string>",
  "outbound_enabled": true,
  "status": "<string>",
  "created_at": "<string>",
  "instructions": {},
  "outbound_trunk_id": "<string>",
  "outbound_address": "<string>",
  "provider_config": {},
  "room_pattern": "<string>",
  "livekit_sip_domain": "<string>",
  "inbound_addresses": [
    "<string>"
  ],
  "supported_providers": [
    {}
  ]
}
{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Path Parameters

agent_id
string<uuid>
required

Body

application/json

Request to register a phone number for an agent.

Provide phone number and trunk details - LiveKit handles the SIP infrastructure.

For LiveKit phone numbers (provider='livekit'):

  • Purchase your number through LiveKit Cloud dashboard first
  • No trunk configuration needed - LiveKit manages the infrastructure
  • Just provide the phone number and it will be configured automatically

For external providers (twilio, vonage, etc.):

  • You must own the number already
  • SIP trunk configuration is required
  • You'll receive a SIP URI to configure in provider's dashboard

IMPORTANT FOR VONAGE USERS: Vonage Elastic SIP Trunking requires your trunk domain in the outbound_address. Format: {your-trunk-domain}.sip-{region}.vonage.com Example: mrassistant-developer.sip-us.vonage.com Find this in Vonage Dashboard → SIP Trunks → Your Trunk → Outbound Calling section.

phone_number
string
required

E.164 format phone number (e.g., +15551234567)

provider
string
required

SIP provider: livekit, twilio, vonage, telnyx, bandwidth, or custom

trunk_numbers
string[] | null

Phone numbers on this trunk (defaults to [phone_number])

allowed_addresses
string[] | null

Allowed IP addresses (empty = allow all)

allowed_numbers
string[] | null

Allowed caller numbers (empty = allow all)

auth_username
string | null

SIP authentication username (REQUIRED for Vonage outbound)

auth_password
string | null

SIP authentication password (REQUIRED for Vonage outbound)

enable_outbound
boolean
default:false

Enable outbound calling (frontend may also send as 'outbound_enabled')

outbound_address
string | null

Provider's SIP termination URI for outbound calls. REQUIRED for outbound calling. Get this from your provider's dashboard. Examples: - Vonage: sip-us.vonage.com - Twilio: pstn.twilio.com - Telnyx: sip.telnyx.com

outbound_numbers
string[] | null

Phone numbers for outbound caller ID

outbound_transport
string
default:AUTO

SIP transport protocol: AUTO, UDP, TCP, or TLS

Pattern: ^(AUTO|UDP|TCP|TLS)$
destination_country
string | null

Two-letter country code (e.g., 'US', 'IN'). Required for India compliance.

Required string length: 2
media_encryption
string
default:ALLOW

Media encryption: DISABLE, ALLOW, or REQUIRE (ALLOW recommended)

Pattern: ^(DISABLE|ALLOW|REQUIRE)$
krisp_enabled
boolean
default:true

Enable Krisp noise cancellation for better call quality

ringing_timeout_seconds
integer
default:30

Maximum time for call to ring (1-300 seconds)

Required range: 1 <= x <= 300
max_call_duration_seconds
integer
default:3600

Maximum call duration (60-86400 seconds)

Required range: 60 <= x <= 86400
hide_phone_number
boolean
default:false

Hide caller phone number from participant attributes for privacy

custom_headers
Custom Headers · object | null

Custom SIP X-* headers to include in requests

headers_to_attributes
Headers To Attributes · object | null

Map SIP headers to participant attributes

dtmf_config
Dtmf Config · object | null

DTMF and IVR configuration

Example:
{
"auto_navigate_ivr": true,
"dtmf_sequence": "*123#ww456",
"dtmf_timeout": 30,
"ivr_detection": true
}
transfer_config
Transfer Config · object | null

Call transfer configuration

Example:
{
"allowed_destinations": ["tel:+15105550100"],
"cold_transfer_enabled": true,
"requires_confirmation": true,
"supervisor_phone": "tel:+15105550100",
"warm_transfer_enabled": false
}
agent_features
Agent Features · object | null

Agent-specific telephony features

Example:
{
"call_screening": false,
"recording_enabled": true,
"sentiment_analysis": true,
"transcription_enabled": true
}
metadata
Metadata · object | null

Additional metadata

provider_config
Provider Config · object | null

Provider-specific configuration (stored in database as JSON)

Response

Successful Response

Response for phone number registration.

agent_id
string
required
phone_number
string
required
provider
string
required
sip_uri
string
required
dispatch_rule_id
string
required
outbound_enabled
boolean
required
status
string
required
created_at
string
required
instructions
Instructions · object
required
outbound_trunk_id
string | null

LiveKit outbound trunk ID if outbound is enabled

outbound_address
string | null

SIP address used for outbound calls (e.g., sip.telnyx.com)

provider_config
Provider Config · object | null
room_pattern
string | null

LiveKit room naming pattern for this agent's calls

livekit_sip_domain
string | null

LiveKit SIP domain for this deployment

inbound_addresses
string[] | null

LiveKit inbound SIP server addresses

supported_providers
Supported Providers · object[] | null

List of supported SIP providers with default addresses