curl --request POST \
--url https://api.fish.audio/v1/agent/phone-numbers \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"provider": "twilio",
"phone_number": "<string>",
"label": "",
"agent_id": "<string>"
}
'import requests
url = "https://api.fish.audio/v1/agent/phone-numbers"
payload = {
"provider": "twilio",
"phone_number": "<string>",
"label": "",
"agent_id": "<string>"
}
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({provider: 'twilio', phone_number: '<string>', label: '', agent_id: '<string>'})
};
fetch('https://api.fish.audio/v1/agent/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.fish.audio/v1/agent/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([
'provider' => 'twilio',
'phone_number' => '<string>',
'label' => '',
'agent_id' => '<string>'
]),
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.fish.audio/v1/agent/phone-numbers"
payload := strings.NewReader("{\n \"provider\": \"twilio\",\n \"phone_number\": \"<string>\",\n \"label\": \"\",\n \"agent_id\": \"<string>\"\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.fish.audio/v1/agent/phone-numbers")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"provider\": \"twilio\",\n \"phone_number\": \"<string>\",\n \"label\": \"\",\n \"agent_id\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fish.audio/v1/agent/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 \"provider\": \"twilio\",\n \"phone_number\": \"<string>\",\n \"label\": \"\",\n \"agent_id\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"phone_number_id": "<string>",
"workspace_id": "<string>",
"phone_number": "<string>",
"provider": "livekit",
"agent_id": "<string>",
"status": "provisioning",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"label": "",
"transfer_caller_id": "agent_number",
"cold_transfer_use_original_caller": true,
"cold_transfer_use_original_caller_effective": true,
"caller_id_sync_status": "carrier_managed",
"caller_id_sync_error": "",
"status_detail": "",
"supports_outbound": false,
"termination_uri": "<string>",
"inbound_auth_username": "<string>",
"inbound_allowed_addresses": [
"<string>"
],
"termination_transport": "<string>",
"termination_auth_username": "<string>",
"termination_headers": {}
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}Purchase Phone Number
Buy a number from the inventory.
curl --request POST \
--url https://api.fish.audio/v1/agent/phone-numbers \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"provider": "twilio",
"phone_number": "<string>",
"label": "",
"agent_id": "<string>"
}
'import requests
url = "https://api.fish.audio/v1/agent/phone-numbers"
payload = {
"provider": "twilio",
"phone_number": "<string>",
"label": "",
"agent_id": "<string>"
}
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({provider: 'twilio', phone_number: '<string>', label: '', agent_id: '<string>'})
};
fetch('https://api.fish.audio/v1/agent/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.fish.audio/v1/agent/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([
'provider' => 'twilio',
'phone_number' => '<string>',
'label' => '',
'agent_id' => '<string>'
]),
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.fish.audio/v1/agent/phone-numbers"
payload := strings.NewReader("{\n \"provider\": \"twilio\",\n \"phone_number\": \"<string>\",\n \"label\": \"\",\n \"agent_id\": \"<string>\"\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.fish.audio/v1/agent/phone-numbers")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"provider\": \"twilio\",\n \"phone_number\": \"<string>\",\n \"label\": \"\",\n \"agent_id\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fish.audio/v1/agent/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 \"provider\": \"twilio\",\n \"phone_number\": \"<string>\",\n \"label\": \"\",\n \"agent_id\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"phone_number_id": "<string>",
"workspace_id": "<string>",
"phone_number": "<string>",
"provider": "livekit",
"agent_id": "<string>",
"status": "provisioning",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"label": "",
"transfer_caller_id": "agent_number",
"cold_transfer_use_original_caller": true,
"cold_transfer_use_original_caller_effective": true,
"caller_id_sync_status": "carrier_managed",
"caller_id_sync_error": "",
"status_detail": "",
"supports_outbound": false,
"termination_uri": "<string>",
"inbound_auth_username": "<string>",
"inbound_allowed_addresses": [
"<string>"
],
"termination_transport": "<string>",
"termination_auth_username": "<string>",
"termination_headers": {}
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
- PublicPhoneNumberPurchasePayload
- PublicSipNumberImportPayload
twilio buys from the managed inventory (supports call transfer); sip imports a number you already own at your carrier; see the sip request variant.
"twilio"E.164 number from GET /v1/agent/available-phone-numbers, e.g. +14155550123.
120Bind an agent to answer inbound calls right away.
Response
Document created, URL follows
E.164, e.g. +14155550123.
livekit, twilio, sip Inbound calls route to this agent; unbound numbers ring busy.
provisioning, active, error, released Managed twilio numbers: the caller ID a transfer target sees, on cold and warm transfers alike. agent_number shows this number, original_caller shows the caller's own number (a warm transfer falls back to this number when the caller withholds theirs). null for imported sip numbers, whose carrier decides.
agent_number, original_caller Deprecated, read transfer_caller_id. True when it is original_caller.
Deprecated, read caller_id_sync_status. Whether the carrier has confirmed the original caller policy for cold transfers, null while unknown.
synced once the carrier confirmed the policy, pending while it is being applied, error when the last attempt failed (send retry_caller_id_sync), carrier_managed for imported sip numbers.
synced, pending, error, carrier_managed Why the last synchronization failed; empty otherwise.
What failed when status is error; empty otherwise.
Whether the number can place calls (outbound and warm-transfer consult legs): managed twilio always, imported sip only when a termination was configured.
Imported sip numbers: the customer trunk's termination host.
Imported sip numbers: the inbound digest username. Passwords are never echoed.
Imported sip numbers: allowed source IPs/CIDRs.
Imported sip numbers: termination transport.
Imported sip numbers: the termination digest username. Passwords are never echoed.
Imported sip numbers: custom SIP headers added to every outbound INVITE through the termination.
Show child attributes
Show child attributes
Was this page helpful?

