Needs keys Adds a number that lives on your carrier, PBX or Twilio Elastic SIP trunk, then provisions the LiveKit SIP inbound trunk, outbound trunk and dispatch rule for it. Real provisioning needs LiveKit (LIVEKIT_URL). Without it, mock mode records the SIP requests in List telephony operations and marks the number provisioned with mock IDs.
Point your trunk's inbound calls at the host from Get SIP origination. To share one trunk between many numbers, create it with Create SIP trunk and pass its sip_trunk_id here instead of a termination_uri.
Request#
| Field | Type | Required | Description |
|---|---|---|---|
phone_number |
string | Yes | The number in E.164, for example +61290001234. |
termination_uri |
string | Conditional | Your trunk's termination URI, where outbound calls are sent, for example sip.example.com or example.pstn.twilio.com. Required unless you pass sip_trunk_id. |
sip_trunk_id |
string | Conditional | A workspace SIP trunk to attach the number to. Required unless you pass termination_uri. |
sip_trunk_auth_username |
string | No | Digest username for outbound calls to your trunk. |
sip_trunk_auth_password |
string | No | Digest password. Stored encrypted and never returned. |
transport |
string | No | TCP, UDP or TLS. Default TCP. |
media_encryption |
string | No | disabled, allowed or required. Default allowed. |
provider |
string | No | custom or twilio. A termination_uri on *.pstn.twilio.com is detected as twilio automatically. |
allowed_inbound_addresses |
string[] | No | Source IPs or CIDRs allowed to send inbound INVITEs. For Twilio numbers left empty, only Twilio's signalling gateways are accepted. |
nickname |
string | No | Label shown in the dashboard. |
inbound_agents |
array | No | Weighted agents for inbound calls. See Agent weights. Default []. |
outbound_agents |
array | No | Weighted agents for outbound calls. Default []. |
inbound_webhook_url |
string | No | URL called with call_inbound before each inbound call. |
fallback_number |
string | No | E.164 number inbound callers go to when no concurrency slot frees up. |
allowed_inbound_country_list |
string[] | No | ISO country codes allowed to call in. |
allowed_outbound_country_list |
string[] | No | ISO country codes this number may dial. |
cps_limit |
number | No | Outbound calls per second, from 0.1 to 150. Without it, custom numbers use 10 and Twilio numbers use 4. |
Example request#
curl -X POST https://api.tried.com.au/import-phone-number \
-H "Authorization: Bearer $TRIED_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone_number": "+61290001234",
"termination_uri": "sip.example.com",
"sip_trunk_auth_username": "tried",
"sip_trunk_auth_password": "s3cret-pass",
"nickname": "Head office",
"inbound_agents": [{ "agent_id": "agent_8d2f61c0a94b3e57d1f0c2a6", "weight": 1 }]
}'const res = await fetch("https://api.tried.com.au/import-phone-number", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.TRIED_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
phone_number: "+61290001234",
termination_uri: "sip.example.com",
sip_trunk_auth_username: "tried",
sip_trunk_auth_password: "s3cret-pass",
nickname: "Head office",
inbound_agents: [{ agent_id: "agent_8d2f61c0a94b3e57d1f0c2a6", weight: 1 }],
}),
});
const number = await res.json();import os, requests
res = requests.post(
"https://api.tried.com.au/import-phone-number",
headers={"Authorization": f"Bearer {os.environ['TRIED_API_KEY']}"},
json={
"phone_number": "+61290001234",
"termination_uri": "sip.example.com",
"sip_trunk_auth_username": "tried",
"sip_trunk_auth_password": "s3cret-pass",
"nickname": "Head office",
"inbound_agents": [{"agent_id": "agent_8d2f61c0a94b3e57d1f0c2a6", "weight": 1}],
},
)
number = res.json()Response#
201 Created
{
"phone_number": "+61290001234",
"phone_number_pretty": "+61 2 9000 1234",
"nickname": "Head office",
"provider": "custom",
"inbound_agents": [{ "agent_id": "agent_8d2f61c0a94b3e57d1f0c2a6", "weight": 1 }],
"outbound_agents": [],
"inbound_webhook_url": null,
"allowed_inbound_country_list": null,
"allowed_outbound_country_list": null,
"termination_uri": "sip.example.com",
"sip_trunk_auth_username": "tried",
"last_modification_timestamp": 1792396800000,
"fallback_number": null,
"transport": "TCP",
"media_encryption": "allowed",
"sip_trunk_id": null,
"cps_limit": null,
"livekit_inbound_trunk_id": "ST_4kQm8vWz2RfT",
"livekit_outbound_trunk_id": "ST_9pLx3cHn7YbD",
"livekit_dispatch_rule_id": "SDR_6tJe1sGa5UoK",
"provisioning_status": "provisioned",
"provisioning_error": null,
"spam_flagged": false,
"country_code": null
}See Get phone number for every field. Imported numbers have no country_code. monthly_price is left out for custom numbers. A twilio number includes it, at the default price of 6 because it has no country.
If provisioning fails, the request still returns 201 with provisioning_status error and the reason in provisioning_error. Retry with Provision phone number.
Errors#
| Status | When |
|---|---|
400 |
Body validation failed, or one of: phone_number must be E.164, termination_uri is required (or sip_trunk_id for a shared workspace trunk), fallback_number must be E.164. |
401 |
Missing or invalid API key. |
403 |
The key's IP allowlist or scopes reject the request. This route needs the numbers scope. Members get The member role is read-only. |
404 |
An agent does not exist (Agent ... not found), or SIP trunk sip_trunk_... not found. |
409 |
The number is already in Tried: +61290001234 already exists. |
429 |
Rate limit exceeded. See Rate limits. |
See Errors for the body format.
Retell compatibility#
Same path and method as Retell, with the same termination_uri, sip_trunk_auth_username, sip_trunk_auth_password and transport fields. In Tried termination_uri is optional when you pass sip_trunk_id.