API reference
SIP trunks
Register your own SIP trunks and the numbers that arrive on them.
A SIP trunk record describes a connection to your own carrier: its gateways, how it authenticates, and its codec and transport settings. Numbers (DIDs) are attached to a trunk and are kept apart from the numbers on the Phone numbers page. See the SIP trunks guide.
All routes need Authorization: Bearer <key>. Changing anything here needs the admin role; reading needs viewer. An unknown or foreign trunk id answers 404 with SIP trunk not found.
Limitation: These routes store, validate and return trunk settings. The API's own outbound dialer places calls through Twilio, Plivo or Exotel; it does not register against a stored trunk or dial through it. Carrying calls over a trunk depends on how the operator has connected the voice engine to a SIP gateway.
| Operation | Method and path |
|---|---|
| Create a trunk | POST /sip-trunks/trunks |
| List trunks | GET /sip-trunks/trunks |
| Get a trunk | GET /sip-trunks/trunks/{trunk_id} |
| Update a trunk | PATCH /sip-trunks/trunks/{trunk_id} |
| Delete a trunk | DELETE /sip-trunks/trunks/{trunk_id} |
| Attach a number to a trunk | POST /sip-trunks/trunks/{trunk_id}/numbers |
| List a trunk's numbers | GET /sip-trunks/trunks/{trunk_id}/numbers |
| Detach a number from a trunk | DELETE /sip-trunks/trunks/{trunk_id}/numbers/{phone_number_id} |
Trunk fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | yes | Display name. | |
provider | string | yes | Your carrier's name. Free text. | |
description | string | no | Notes. | |
auth_type | string | yes | userpass or ip-based. | |
auth_username | string | for userpass | SIP user name. | |
auth_password | string | for userpass on create | Stored encrypted and never returned. | |
ip_identifiers | array | for ip-based | The addresses the carrier sends from. | |
gateways | array | yes | At least one object with a gateway_address. | |
allow | string | no | ulaw,alaw | Codecs allowed. |
disallow | string | no | all | Codecs refused before allow is applied. |
transport | string | no | transport-udp | Transport name. |
direct_media | boolean | no | false | |
rtp_symmetric | boolean | no | true | |
force_rport | boolean | no | true | |
media_encryption | string | no | no | |
media_encryption_optimistic | boolean | no | false | |
qualify_frequency | integer | no | 60 | Seconds between keep-alive checks. |
inbound_enabled | boolean | no | true | |
outbound_leading_plus_enabled | boolean | no | true | Keep the leading + on dialed numbers. |
phone_numbers | array | no | On create only: numbers to attach, each as in Attach a number to a trunk. | |
is_active | boolean | no | true | On update only. |
Operations
Create a trunk
POST /sip-trunks/trunks
Creates a trunk, optionally with its numbers.
Auth: API key or session token. Role: admin and up.
Body: the fields in Trunk fields.
Request
curl -X POST https://api.sevennadi.si/sip-trunks/trunks \
-H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef" \
-H "Content-Type: application/json" \
-d '{
"name": "Mumbai carrier",
"provider": "Example Telecom",
"auth_type": "userpass",
"auth_username": "sonic-trunk",
"auth_password": "<your SIP password>",
"gateways": [{"gateway_address": "sip.carrier.example.test"}],
"phone_numbers": [{"phone_number": "+912255501000", "name": "Main line"}]
}'Response 201 Created
{
"id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"name": "Mumbai carrier",
"provider": "Example Telecom",
"auth_type": "userpass",
"auth_username": "sonic-trunk",
"gateways": [{"gateway_address": "sip.carrier.example.test"}],
"allow": "ulaw,alaw",
"disallow": "all",
"transport": "transport-udp",
"direct_media": false,
"rtp_symmetric": true,
"force_rport": true,
"media_encryption": "no",
"media_encryption_optimistic": false,
"qualify_frequency": 60,
"inbound_enabled": true,
"outbound_leading_plus_enabled": true,
"phone_numbers": [
{
"id": "0f9e8d7c-6b5a-4c3d-9e2f-1a0b9c8d7e6f",
"phone_number": "+912255501000",
"name": "Main line",
"byot_trunk_id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"telephony_provider": "sip-trunk",
"deleted": false,
"created_at": "2026-10-13T08:00:00Z",
"updated_at": "2026-10-13T08:00:00Z"
}
],
"is_active": true,
"created_at": "2026-10-13T08:00:00Z",
"updated_at": "2026-10-13T08:00:00Z"
}Fields that were never set, such as description or ip_identifiers here, are left out.
Errors
| Status | Message |
|---|---|
| 400 | name is required, provider is required, auth_type is required |
| 400 | auth_type must be userpass or ip-based |
| 400 | At least one gateway is required |
| 400 | gateways[].gateway_address is required |
| 400 | auth_username and auth_password are required for userpass trunks |
| 400 | ip_identifiers are required for ip-based trunks |
| 400 | phone_number must be E.164 (or set e164_check_enabled to false) |
| 403 | Your role (member) can't change SIP trunks. It needs admin access; ask an owner or admin of the workspace. |
List trunks
GET /sip-trunks/trunks
Returns the account's trunks, oldest first, each with its numbers.
Auth: API key or session token. Role: viewer and up.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
is_active | query | boolean | no | Only active (true) or inactive (false) trunks. |
Request
curl "https://api.sevennadi.si/sip-trunks/trunks?is_active=true" \
-H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"Response 200 OK
An array of trunk objects, each as in Create a trunk.
Get a trunk
GET /sip-trunks/trunks/{trunk_id}
Returns one trunk with its numbers.
Auth: API key or session token. Role: viewer and up.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
trunk_id | path | string (UUID) | yes | The trunk. |
Request
curl https://api.sevennadi.si/sip-trunks/trunks/a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d \
-H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"Response 200 OK
The trunk object.
Errors
| Status | Message |
|---|---|
| 404 | SIP trunk not found |
Update a trunk
PATCH /sip-trunks/trunks/{trunk_id}
Changes the fields you send and keeps the rest. The merged result must still pass the checks of create. Send auth_password to replace the stored password, and is_active to switch the trunk on or off.
Auth: API key or session token. Role: admin and up.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
trunk_id | path | string (UUID) | yes | The trunk. |
| any trunk field | body | no | See Trunk fields. phone_numbers is ignored here. |
Request
curl -X PATCH https://api.sevennadi.si/sip-trunks/trunks/a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d \
-H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef" \
-H "Content-Type: application/json" \
-d '{"description": "Primary route", "is_active": false}'Response 200 OK
The updated trunk object.
Errors
The 400 messages of Create a trunk, and 404 SIP trunk not found.
Delete a trunk
DELETE /sip-trunks/trunks/{trunk_id}
Deletes a trunk for good, together with every number on it.
Auth: API key or session token. Role: admin and up.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
trunk_id | path | string (UUID) | yes | The trunk. |
Request
curl -X DELETE https://api.sevennadi.si/sip-trunks/trunks/a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d \
-H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"Response 200 OK
{"message": "Trunk deleted successfully. 1 phone number(s) removed."}Errors
| Status | Message |
|---|---|
| 404 | SIP trunk not found |
Attach a number to a trunk
POST /sip-trunks/trunks/{trunk_id}/numbers
Attaches one number to a trunk.
Auth: API key or session token. Role: admin and up.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
trunk_id | path | string (UUID) | yes | The trunk. |
phone_number | body | string | yes | 7 to 15 digits, with or without a leading +. |
name | body | string | no | A label. |
e164_check_enabled | body | boolean | no | Set to false to accept a number in another format, such as a short extension. Default true. |
Request
curl -X POST https://api.sevennadi.si/sip-trunks/trunks/a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d/numbers \
-H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef" \
-H "Content-Type: application/json" \
-d '{"phone_number": "+912255501001", "name": "Collections"}'Response 201 Created
{
"id": "5e4d3c2b-1a0f-4e9d-8c7b-6a5f4e3d2c1b",
"phone_number": "+912255501001",
"name": "Collections",
"byot_trunk_id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"telephony_provider": "sip-trunk",
"deleted": false,
"created_at": "2026-10-13T08:05:00Z",
"updated_at": "2026-10-13T08:05:00Z"
}Errors
| Status | Message |
|---|---|
| 400 | phone_number is required |
| 400 | phone_number must be E.164 (or set e164_check_enabled to false) |
| 404 | SIP trunk not found |
List a trunk's numbers
GET /sip-trunks/trunks/{trunk_id}/numbers
Returns the numbers attached to a trunk.
Auth: API key or session token. Role: viewer and up.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
trunk_id | path | string (UUID) | yes | The trunk. |
Request
curl https://api.sevennadi.si/sip-trunks/trunks/a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d/numbers \
-H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"Response 200 OK
An array of number objects, each as in Attach a number to a trunk.
Errors
| Status | Message |
|---|---|
| 404 | SIP trunk not found |
Detach a number from a trunk
DELETE /sip-trunks/trunks/{trunk_id}/numbers/{phone_number_id}
Removes one number from a trunk.
Auth: API key or session token. Role: admin and up.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
trunk_id | path | string (UUID) | yes | The trunk. |
phone_number_id | path | string (UUID) | yes | The number's id. |
Request
curl -X DELETE https://api.sevennadi.si/sip-trunks/trunks/a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d/numbers/5e4d3c2b-1a0f-4e9d-8c7b-6a5f4e3d2c1b \
-H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"Response 200 OK
{"message": "Phone number removed from trunk"}Errors
| Status | Message |
|---|---|
| 404 | SIP trunk not found |
| 404 | Phone number not found (also when the number belongs to another trunk) |