Phone Numbers
Import a Twilio number
Add a phone number you own in Twilio by its Account SID and Auth Token, and choose the assistants that answer it and dial from it.
POST
/
phone-number
/
twilio
Import a Twilio number
curl --request POST \
--url https://api.verbeo.ai/v1/phone-number/twilio \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"phone_number": "<string>",
"twilio_sid": "<string>",
"twilio_auth_token": "<string>",
"nickname": "<string>",
"inbound_agent_id": "<string>",
"outbound_agent_id": "<string>"
}
'import requests
url = "https://api.verbeo.ai/v1/phone-number/twilio"
payload = {
"phone_number": "<string>",
"twilio_sid": "<string>",
"twilio_auth_token": "<string>",
"nickname": "<string>",
"inbound_agent_id": "<string>",
"outbound_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({
phone_number: '<string>',
twilio_sid: '<string>',
twilio_auth_token: '<string>',
nickname: '<string>',
inbound_agent_id: '<string>',
outbound_agent_id: '<string>'
})
};
fetch('https://api.verbeo.ai/v1/phone-number/twilio', 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.verbeo.ai/v1/phone-number/twilio",
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>',
'twilio_sid' => '<string>',
'twilio_auth_token' => '<string>',
'nickname' => '<string>',
'inbound_agent_id' => '<string>',
'outbound_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.verbeo.ai/v1/phone-number/twilio"
payload := strings.NewReader("{\n \"phone_number\": \"<string>\",\n \"twilio_sid\": \"<string>\",\n \"twilio_auth_token\": \"<string>\",\n \"nickname\": \"<string>\",\n \"inbound_agent_id\": \"<string>\",\n \"outbound_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.verbeo.ai/v1/phone-number/twilio")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"phone_number\": \"<string>\",\n \"twilio_sid\": \"<string>\",\n \"twilio_auth_token\": \"<string>\",\n \"nickname\": \"<string>\",\n \"inbound_agent_id\": \"<string>\",\n \"outbound_agent_id\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.verbeo.ai/v1/phone-number/twilio")
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 \"twilio_sid\": \"<string>\",\n \"twilio_auth_token\": \"<string>\",\n \"nickname\": \"<string>\",\n \"inbound_agent_id\": \"<string>\",\n \"outbound_agent_id\": \"<string>\"\n}"
response = http.request(request)
puts response.read_bodyAdds a number from your own Twilio account, using the account’s credentials to place and receive its calls.
This request stores the number and does not contact Twilio. Inbound calls reach Verbeo only after you point the number at it — call
For a new number, SIP trunking is the path to choose: it works with Twilio through Elastic SIP Trunking, and only a SIP-trunk number has an inbound call webhook.
POST /phone-number/{id}/twilio-webhook once the import has succeeded.
Body
string
required
The number in E.164 format — a
+, the country code, the number: +14155550123. Spaces, dashes and brackets are accepted and removed.string
required
Your Twilio Account SID:
AC followed by 32 hexadecimal characters.string
required
Your Twilio Auth Token, exactly as the Twilio console shows it. Up to 128 characters, no spaces. Write-only: no endpoint returns it.
string
Your label for the number, up to 100 characters.
string
UUID of the assistant that answers calls to this number.
string
UUID of the assistant that places calls from this number when a call names none.
Request
curl -X POST "https://api.verbeo.ai/v1/phone-number/twilio" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone_number": "+14155550123",
"twilio_sid": "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"twilio_auth_token": "your_twilio_auth_token",
"nickname": "Main line",
"inbound_agent_id": "550e8400-e29b-41d4-a716-446655440000"
}'
const headers = {
Authorization: `Bearer ${process.env.VERBEO_API_KEY}`,
"Content-Type": "application/json",
};
const res = await fetch("https://api.verbeo.ai/v1/phone-number/twilio", {
method: "POST",
headers,
body: JSON.stringify({
phone_number: "+14155550123",
twilio_sid: process.env.TWILIO_ACCOUNT_SID,
twilio_auth_token: process.env.TWILIO_AUTH_TOKEN,
nickname: "Main line",
inbound_agent_id: "550e8400-e29b-41d4-a716-446655440000",
}),
});
const { data: number } = await res.json();
// Then point the number's calls at Verbeo.
await fetch(`https://api.verbeo.ai/v1/phone-number/${number.id}/twilio-webhook`, {
method: "POST",
headers,
});
import os, requests
headers = {"Authorization": f"Bearer {os.environ['VERBEO_API_KEY']}"}
number = requests.post(
"https://api.verbeo.ai/v1/phone-number/twilio",
headers=headers,
json={
"phone_number": "+14155550123",
"twilio_sid": os.environ["TWILIO_ACCOUNT_SID"],
"twilio_auth_token": os.environ["TWILIO_AUTH_TOKEN"],
"nickname": "Main line",
"inbound_agent_id": "550e8400-e29b-41d4-a716-446655440000",
},
).json()["data"]
# Then point the number's calls at Verbeo.
requests.post(
f"https://api.verbeo.ai/v1/phone-number/{number['id']}/twilio-webhook",
headers=headers,
)
Response
201 Created with the phone number object. provider is twilio, and the Auth Token is not in it.
{
"success": true,
"data": {
"id": "7d9f3b52-4c1e-4a8e-9b1a-2f6c0d4e8a11",
"workspace_id": "123e4567-e89b-12d3-a456-426614174000",
"phone_number": "+14155550123",
"nickname": "Main line",
"provider": "twilio",
"is_active": true,
"max_cps": 1,
"inbound_agent_id": "550e8400-e29b-41d4-a716-446655440000",
"outbound_agent_id": null,
"inbound_webhook_url": null,
"created_at": "2026-01-15T10:30:00.123456+00:00",
"updated_at": "2026-01-15T10:30:00.123456+00:00",
"inbound_agent_name": "Customer Support",
"outbound_agent_name": null
}
}
Errors
| Code | Status | When |
|---|---|---|
VALIDATION_FAILED | 422 | A missing or malformed field — the message names it, e.g. twilio_sid: must be a Twilio Account SID: AC followed by 32 hex characters. Also an assistant id that is not an assistant of your workspace. |
CONFLICT | 409 | The number is already connected to Verbeo, in your workspace or another. |
The credentials are not checked against Twilio here. Wrong ones are reported when you configure the webhook, and when the number first places a call.
Was this page helpful?
⌘I
Import a Twilio number
curl --request POST \
--url https://api.verbeo.ai/v1/phone-number/twilio \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"phone_number": "<string>",
"twilio_sid": "<string>",
"twilio_auth_token": "<string>",
"nickname": "<string>",
"inbound_agent_id": "<string>",
"outbound_agent_id": "<string>"
}
'import requests
url = "https://api.verbeo.ai/v1/phone-number/twilio"
payload = {
"phone_number": "<string>",
"twilio_sid": "<string>",
"twilio_auth_token": "<string>",
"nickname": "<string>",
"inbound_agent_id": "<string>",
"outbound_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({
phone_number: '<string>',
twilio_sid: '<string>',
twilio_auth_token: '<string>',
nickname: '<string>',
inbound_agent_id: '<string>',
outbound_agent_id: '<string>'
})
};
fetch('https://api.verbeo.ai/v1/phone-number/twilio', 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.verbeo.ai/v1/phone-number/twilio",
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>',
'twilio_sid' => '<string>',
'twilio_auth_token' => '<string>',
'nickname' => '<string>',
'inbound_agent_id' => '<string>',
'outbound_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.verbeo.ai/v1/phone-number/twilio"
payload := strings.NewReader("{\n \"phone_number\": \"<string>\",\n \"twilio_sid\": \"<string>\",\n \"twilio_auth_token\": \"<string>\",\n \"nickname\": \"<string>\",\n \"inbound_agent_id\": \"<string>\",\n \"outbound_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.verbeo.ai/v1/phone-number/twilio")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"phone_number\": \"<string>\",\n \"twilio_sid\": \"<string>\",\n \"twilio_auth_token\": \"<string>\",\n \"nickname\": \"<string>\",\n \"inbound_agent_id\": \"<string>\",\n \"outbound_agent_id\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.verbeo.ai/v1/phone-number/twilio")
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 \"twilio_sid\": \"<string>\",\n \"twilio_auth_token\": \"<string>\",\n \"nickname\": \"<string>\",\n \"inbound_agent_id\": \"<string>\",\n \"outbound_agent_id\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body