SIP Trunks
Last updated September 4, 2026
Outbound SIP trunks (REGISTER or static peering)
List configured SIP trunks
Responses
| Field | Type | Description | |
|---|---|---|---|
trunks | array[object] | required |
Create an outbound SIP trunk (REGISTER or static peering)
Creates a typed SIP trunk. For type: "sip_register", VoiceBlender begins REGISTERing to the supplied registrar URI with digest auth, refreshes before expiry, and routes inbound INVITEs that arrive on that peer's socket plus outbound INVITEs whose from matches the AOR through the trunk. Set sip_register.outbound_proxy to send both the REGISTER and those INVITEs via a next-hop proxy instead of straight at the registrar; the Request-URI and digest authentication still target registrar_uri. It defaults to SIP_OUTBOUND_PROXY and is resolved at creation time, so the trunk snapshot reports the hop actually in effect. For type: "ip_ip", returns 501 (reserved, not yet implemented).
Request Body
| Field | Type | Description | |
|---|---|---|---|
type | enum | required | Trunk type discriminator. Only `sip_register` is implemented today; `ip_ip` is reserved and returns 501. Values: sip_register, ip_ip |
app_id | string | optional | Application identifier carried through to every event emitted by this trunk. |
sip_register | object | optional | Required when type == "sip_register". Configures the outbound REGISTER (registrar URI, AOR, digest credentials, expiry). |
registrar_uri | string | required | Upstream registrar SIP URI (e.g. "sip:pbx.example.com:5060" or "sips:pbx.example.com:5061"). Transport is taken from the URI: a "sips:" scheme or a ";transport=tls" parameter selects TLS, ";transport=tcp" selects TCP, otherwise UDP. Note that "transport" is a URI parameter (";"), not a URI header ("?") — RFC 3261 section 19.1. |
outbound_proxy | string | optional | Next-hop SIP proxy for this trunk's REGISTER and for outbound INVITEs placed from its AOR, attached as a loose `Route` header (the Request-URI is left unchanged, and digest auth still targets `registrar_uri`). E.g. "sip:edge.example.com:5060;transport=tcp". Defaults to `SIP_OUTBOUND_PROXY`; when neither is set, requests go straight to `registrar_uri`. |
aor | string | required | Address-of-record this trunk REGISTERs (e.g. "sip:alice@pbx.example.com"). Becomes the From URI on outbound REGISTER, and the From / P-Asserted-Identity host on outbound INVITEs placed `from` this AOR. |
username | string | optional | Digest auth username. Defaults to the AOR user-part when empty. |
password | string | required | Digest auth password. Required. Never returned in any response. |
contact_user | string | optional | Override the user-part of the Contact header sent in REGISTER. Defaults to the AOR user-part. |
expires_seconds | integer | optional | Requested registration lifetime in seconds. Clamped to [SIP_OUTBOUND_REGISTRATION_MIN_EXPIRES_SECONDS, SIP_OUTBOUND_REGISTRATION_MAX_EXPIRES_SECONDS]. Default: SIP_OUTBOUND_REGISTRATION_DEFAULT_EXPIRES_SECONDS (3600). |
tls_insecure_skip_verify | boolean | optional | Accept this trunk's next-hop certificate without verifying it, for a `sips:` / `;transport=tls` registrar or outbound proxy whose certificate is self-signed, privately signed, or carries no SAN (`x509: certificate relies on legacy Common Name field`). Scoped to that peer's hostname — every other TLS peer is still verified in full, unlike the server-wide `SIP_TLS_INSECURE_SKIP_VERIFY`. Ignored (with a logged warning) when the next hop is not TLS, or when it is named by IP literal: such a dial sends no SNI and cannot be told apart from any other, so use `SIP_TLS_CA_FILE` or `SIP_TLS_INSECURE_SKIP_VERIFY` there. Prefer `SIP_TLS_CA_FILE` when the peer's CA can simply be trusted. |
ip_ip | object | optional | Reserved for static-IP peering (no REGISTER). Not yet implemented; supplying this returns 501. |
peer_uri | string | optional | Static peer SIP URI for IP-IP peering. Reserved; not yet implemented. |
Responses
| Field | Type | Description | |
|---|---|---|---|
id | string | required | |
type | string | required | |
status | string | required |
| Field | Type | Description | |
|---|---|---|---|
instance_id | string | optional | Instance identifier |
error | string | required | Error message |
| Field | Type | Description | |
|---|---|---|---|
instance_id | string | optional | Instance identifier |
error | string | required | Error message |
Get a single SIP trunk
Parameters
| Name | In | Type | Description | |
|---|---|---|---|---|
id | path | string | required | Leg ID |
Responses
| Field | Type | Description | |
|---|---|---|---|
id | string | required | |
type | string | required | |
app_id | string | optional | |
status | string | required | |
last_error | string | optional | |
created_at | string | required | |
sip_register | object | optional | |
registrar_uri | string | required | |
outbound_proxy | string | optional | |
aor | string | required | |
username | string | optional | |
contact_uri | string | optional | |
requested_expires_seconds | integer | required | |
granted_expires_seconds | integer | optional | |
last_registered_at | string | optional | |
next_refresh_at | string | optional | |
call_id | string | optional | |
cseq | integer | optional | |
source_address | string | optional | |
tls_insecure_skip_verify | boolean | optional | |
ip_ip | object | optional | |
peer_uri | string | optional |
| Field | Type | Description | |
|---|---|---|---|
instance_id | string | optional | Instance identifier |
error | string | required | Error message |
Unregister and remove a SIP trunk
Returns 202 Accepted; the unregister (REGISTER with Expires: 0) and final removal run asynchronously.
Parameters
| Name | In | Type | Description | |
|---|---|---|---|---|
id | path | string | required | Leg ID |
Responses
| Field | Type | Description | |
|---|---|---|---|
instance_id | string | optional | Instance identifier |
error | string | required | Error message |
Schemas
Objects used by the SIP Trunks endpoints above.
CreateTrunkRequest
| Field | Type | Description | |
|---|---|---|---|
type | enum | required | Trunk type discriminator. Only `sip_register` is implemented today; `ip_ip` is reserved and returns 501. Values: sip_register, ip_ip |
app_id | string | optional | Application identifier carried through to every event emitted by this trunk. |
sip_register | object | optional | Required when type == "sip_register". Configures the outbound REGISTER (registrar URI, AOR, digest credentials, expiry). |
registrar_uri | string | required | Upstream registrar SIP URI (e.g. "sip:pbx.example.com:5060" or "sips:pbx.example.com:5061"). Transport is taken from the URI: a "sips:" scheme or a ";transport=tls" parameter selects TLS, ";transport=tcp" selects TCP, otherwise UDP. Note that "transport" is a URI parameter (";"), not a URI header ("?") — RFC 3261 section 19.1. |
outbound_proxy | string | optional | Next-hop SIP proxy for this trunk's REGISTER and for outbound INVITEs placed from its AOR, attached as a loose `Route` header (the Request-URI is left unchanged, and digest auth still targets `registrar_uri`). E.g. "sip:edge.example.com:5060;transport=tcp". Defaults to `SIP_OUTBOUND_PROXY`; when neither is set, requests go straight to `registrar_uri`. |
aor | string | required | Address-of-record this trunk REGISTERs (e.g. "sip:alice@pbx.example.com"). Becomes the From URI on outbound REGISTER, and the From / P-Asserted-Identity host on outbound INVITEs placed `from` this AOR. |
username | string | optional | Digest auth username. Defaults to the AOR user-part when empty. |
password | string | required | Digest auth password. Required. Never returned in any response. |
contact_user | string | optional | Override the user-part of the Contact header sent in REGISTER. Defaults to the AOR user-part. |
expires_seconds | integer | optional | Requested registration lifetime in seconds. Clamped to [SIP_OUTBOUND_REGISTRATION_MIN_EXPIRES_SECONDS, SIP_OUTBOUND_REGISTRATION_MAX_EXPIRES_SECONDS]. Default: SIP_OUTBOUND_REGISTRATION_DEFAULT_EXPIRES_SECONDS (3600). |
tls_insecure_skip_verify | boolean | optional | Accept this trunk's next-hop certificate without verifying it, for a `sips:` / `;transport=tls` registrar or outbound proxy whose certificate is self-signed, privately signed, or carries no SAN (`x509: certificate relies on legacy Common Name field`). Scoped to that peer's hostname — every other TLS peer is still verified in full, unlike the server-wide `SIP_TLS_INSECURE_SKIP_VERIFY`. Ignored (with a logged warning) when the next hop is not TLS, or when it is named by IP literal: such a dial sends no SNI and cannot be told apart from any other, so use `SIP_TLS_CA_FILE` or `SIP_TLS_INSECURE_SKIP_VERIFY` there. Prefer `SIP_TLS_CA_FILE` when the peer's CA can simply be trusted. |
ip_ip | object | optional | Reserved for static-IP peering (no REGISTER). Not yet implemented; supplying this returns 501. |
peer_uri | string | optional | Static peer SIP URI for IP-IP peering. Reserved; not yet implemented. |
CreateTrunkResponse
| Field | Type | Description | |
|---|---|---|---|
id | string | required | |
type | string | required | |
status | string | required |
Error
| Field | Type | Description | |
|---|---|---|---|
instance_id | string | optional | Instance identifier |
error | string | required | Error message |
IPIPTrunkSpec
| Field | Type | Description | |
|---|---|---|---|
peer_uri | string | optional | Static peer SIP URI for IP-IP peering. Reserved; not yet implemented. |
IPIPTrunkView
| Field | Type | Description | |
|---|---|---|---|
peer_uri | string | optional |
SIPRegisterTrunkSpec
| Field | Type | Description | |
|---|---|---|---|
registrar_uri | string | required | Upstream registrar SIP URI (e.g. "sip:pbx.example.com:5060" or "sips:pbx.example.com:5061"). Transport is taken from the URI: a "sips:" scheme or a ";transport=tls" parameter selects TLS, ";transport=tcp" selects TCP, otherwise UDP. Note that "transport" is a URI parameter (";"), not a URI header ("?") — RFC 3261 section 19.1. |
outbound_proxy | string | optional | Next-hop SIP proxy for this trunk's REGISTER and for outbound INVITEs placed from its AOR, attached as a loose `Route` header (the Request-URI is left unchanged, and digest auth still targets `registrar_uri`). E.g. "sip:edge.example.com:5060;transport=tcp". Defaults to `SIP_OUTBOUND_PROXY`; when neither is set, requests go straight to `registrar_uri`. |
aor | string | required | Address-of-record this trunk REGISTERs (e.g. "sip:alice@pbx.example.com"). Becomes the From URI on outbound REGISTER, and the From / P-Asserted-Identity host on outbound INVITEs placed `from` this AOR. |
username | string | optional | Digest auth username. Defaults to the AOR user-part when empty. |
password | string | required | Digest auth password. Required. Never returned in any response. |
contact_user | string | optional | Override the user-part of the Contact header sent in REGISTER. Defaults to the AOR user-part. |
expires_seconds | integer | optional | Requested registration lifetime in seconds. Clamped to [SIP_OUTBOUND_REGISTRATION_MIN_EXPIRES_SECONDS, SIP_OUTBOUND_REGISTRATION_MAX_EXPIRES_SECONDS]. Default: SIP_OUTBOUND_REGISTRATION_DEFAULT_EXPIRES_SECONDS (3600). |
tls_insecure_skip_verify | boolean | optional | Accept this trunk's next-hop certificate without verifying it, for a `sips:` / `;transport=tls` registrar or outbound proxy whose certificate is self-signed, privately signed, or carries no SAN (`x509: certificate relies on legacy Common Name field`). Scoped to that peer's hostname — every other TLS peer is still verified in full, unlike the server-wide `SIP_TLS_INSECURE_SKIP_VERIFY`. Ignored (with a logged warning) when the next hop is not TLS, or when it is named by IP literal: such a dial sends no SNI and cannot be told apart from any other, so use `SIP_TLS_CA_FILE` or `SIP_TLS_INSECURE_SKIP_VERIFY` there. Prefer `SIP_TLS_CA_FILE` when the peer's CA can simply be trusted. |
SIPRegisterTrunkView
| Field | Type | Description | |
|---|---|---|---|
registrar_uri | string | required | |
outbound_proxy | string | optional | |
aor | string | required | |
username | string | optional | |
contact_uri | string | optional | |
requested_expires_seconds | integer | required | |
granted_expires_seconds | integer | optional | |
last_registered_at | string | optional | |
next_refresh_at | string | optional | |
call_id | string | optional | |
cseq | integer | optional | |
source_address | string | optional | |
tls_insecure_skip_verify | boolean | optional |
TrunkView
| Field | Type | Description | |
|---|---|---|---|
id | string | required | |
type | string | required | |
app_id | string | optional | |
status | string | required | |
last_error | string | optional | |
created_at | string | required | |
sip_register | object | optional | |
registrar_uri | string | required | |
outbound_proxy | string | optional | |
aor | string | required | |
username | string | optional | |
contact_uri | string | optional | |
requested_expires_seconds | integer | required | |
granted_expires_seconds | integer | optional | |
last_registered_at | string | optional | |
next_refresh_at | string | optional | |
call_id | string | optional | |
cseq | integer | optional | |
source_address | string | optional | |
tls_insecure_skip_verify | boolean | optional | |
ip_ip | object | optional | |
peer_uri | string | optional |
TrunksListResponse
| Field | Type | Description | |
|---|---|---|---|
trunks | array[object] | required |