Skip to main content

Quick Start Guide

This guide walks you through enabling Inbound SIP URI on a Bandwidth Voice Application, retrieving the generated credentials, and using them from your SIP client to place calls into your Programmable Voice application.

Assumptions

Credentials

The Voice Application Management API is secured with OAuth 2.0 client credentials. Request an access token from Bandwidth's Identity Services token endpoint and include it as a bearer token on subsequent requests:

curl -X POST https://api.bandwidth.com/api/v1/oauth2/token \
-u "$BANDWIDTH_CLIENT_ID:$BANDWIDTH_CLIENT_SECRET" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials"

See Credentials Management for details on generating, rotating, and scoping API credentials.

Enable Inbound SIP URI on a Voice Application

Enable inbound SIP calls on an existing Voice Application by issuing a PATCH request to the Voice Application Management API. When inboundSipCallsEnabled is true, at least one auth mechanism must be configured: either passwordAuthEnabled: true, a non-empty allowedSourceIps list, or both.

Password auth (digest)

curl -X PATCH \
"https://api.bandwidth.com/v2/accounts/$BANDWIDTH_ACCOUNT_ID/voice-applications/$APPLICATION_ID" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"inboundSipCallsEnabled": true,
"passwordAuthEnabled": true,
"allowedRegions": ["US"]
}'

The response returns the generated SIP URI and a one-time SIP authentication password:

{
"links": [],
"data": {
"applicationId": "15f99d57-f823-4718-80cc-5d95d5b83e59",
"applicationName": "My Voice App",
"sipUri": "sip:479fbd44-3362-45f3-bb80-284f21111be4@sip-uri.voice-api.bandwidth.com",
"inboundSipCallsEnabled": true,
"passwordAuthEnabled": true,
"allowedSourceIps": [],
"allowedRegions": ["US"],
"sipAuthPassword": "super_secure_password"
},
"errors": []
}
danger

sipAuthPassword is only returned on the enable/rotate response. Bandwidth does not store or echo the password on subsequent GET requests. If the password is lost, send another PATCH with passwordAuthEnabled: true to rotate to a new password.

IP-only auth

Skip the 407 digest challenge entirely and authenticate by source IP:

curl -X PATCH \
"https://api.bandwidth.com/v2/accounts/$BANDWIDTH_ACCOUNT_ID/voice-applications/$APPLICATION_ID" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"inboundSipCallsEnabled": true,
"passwordAuthEnabled": false,
"allowedSourceIps": ["203.0.113.0/24", "198.51.100.42/32"],
"allowedRegions": ["US"]
}'

Password + IP (layered auth)

Both mechanisms must pass — the request must satisfy digest auth and originate from a whitelisted IP:

curl -X PATCH \
"https://api.bandwidth.com/v2/accounts/$BANDWIDTH_ACCOUNT_ID/voice-applications/$APPLICATION_ID" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"inboundSipCallsEnabled": true,
"passwordAuthEnabled": true,
"allowedSourceIps": ["203.0.113.0/24"],
"allowedRegions": ["US"]
}'

CIDR rules

allowedSourceIps entries must be public IPv4 CIDRs in canonical form, up to 25 entries per application:

InputResultWhy
203.0.113.0/24AcceptedPublic IPv4, canonical form
198.51.100.5/32AcceptedSingle public IP
0.0.0.0/0AcceptedWide-open — explicit customer choice
192.168.1.5/24RejectedHost bits set — ambiguous intent
10.0.0.0/8RejectedRFC 1918 private range
172.16.0.0/12RejectedRFC 1918 private range
192.168.0.0/16RejectedRFC 1918 private range
127.0.0.0/8RejectedLoopback
169.254.0.0/16RejectedLink-local
::1/128RejectedIPv6 not supported

Connecting to Bandwidth

Your SIP client directs its initial INVITE and subsequent signaling to Bandwidth's public Inbound SIP URI DNS records. The service is backed by two pools of public servers:

TierRoleCIDR (us-east-2)
SignalingSIP signaling: authentication, routing, and call setup3.43.67.32/28
MediaRTP media3.43.67.0/28

DNS Records

Point your SIP client at one of the following records. Both are multi-value and resolve to the current pool of signaling instances. Bandwidth may add or remove instances at any time, so DNS is the authoritative source of the current endpoint set. Avoid hard-coding individual IPs.

RecordTypeNotes
sip-uri.voice-api.bandwidth.comA (multi-value)Each value is the IP of a live signaling instance.
_sip._udp.sip-uri.voice-api.bandwidth.comSRV (multi-value)Each value follows the form <priority> <weight> <port> <target>, e.g. 10 60 6160 3.43.67.X.

The SRV record is preferred for clients that support it, since it supplies the port and priority/weight along with the target host in a single lookup.

Both records use a 60-second TTL, so changes to the signaling pool propagate to clients within about a minute.

IP Whitelisting (optional)

If your network egress requires explicit allow-listing, whitelist the CIDRs in the table above. The CIDRs are stable within a region, but the set of active IPs within each CIDR may change as the pool scales. Allow the entire CIDR rather than individual IPs.

Configure Your SIP Client

Configure your SIP client, PBX, or SBC with the values returned by the enable response. Digest credentials only apply when passwordAuthEnabled: true; for IP-only mode, skip the authentication rows.

FieldValue
SIP URIsipUri returned in the enable response
Authentication UserThe Voice Application's applicationId (also the user-part of the URI)
Authentication Realmsip-uri.voice-api.bandwidth.com
PasswordsipAuthPassword from the enable response

SIP Request Format

Your INVITE (and other in-dialog requests) should target the Voice Application's SIP URI. The Request-URI and To header user-parts must both equal the application's applicationId:

INVITE sip:15f99d57-f823-4718-80cc-5d95d5b83e59@sip-uri.voice-api.bandwidth.com SIP/2.0
To: <sip:15f99d57-f823-4718-80cc-5d95d5b83e59@sip-uri.voice-api.bandwidth.com>
From: <sip:your-calling-party@your-domain>;tag=…
  • Supply digest credentials in the Proxy-Authorization header. A first INVITE without credentials receives a 407 Proxy Authentication Required challenge carrying the realm above and a fresh nonce. Retry with a digest response built against that challenge.
  • No Bandwidth-specific headers are required. Use standard SIP; vendor-specific X-* headers are stripped at the proxy and will not reach your call flow.
  • OPTIONS requests sent to the SIP URI host are answered with 200 Keepalive. Clients that emit periodic OPTIONS for path liveness work out of the box. No SIP REGISTER is required, since the service is a proxy, not a registrar.

Media Path and Firewall Rules

Media is always relayed through Bandwidth's media tier. SDP answers returned by the service advertise a public IP inside the media CIDR, and your RTP must flow to that address rather than to the signaling host.

Your network egress must allow symmetric UDP paths to both tiers:

PurposeProtocol & PortsDestination CIDR
SIP signalingUDP 61603.43.67.32/28
RTP / RTCP mediaUDP 30000-400003.43.67.0/28
  • Plain RTP is supported. Standard narrowband codecs (for example, PCMU / G.711 μ-law) pass through without transcoding.
  • The media tier handles NAT traversal on your behalf, so you do not need to supply ICE, STUN, or TURN candidates for this service.
  • Direct your RTP to the c= / m= address in the SDP answer, which will be inside the media CIDR above.

SIP Response Reference

Common status codes you may see from the signaling tier and how to interpret them:

CodeMeaningCommon cause
200OK / KeepaliveCall established, or a successful OPTIONS response.
401UnauthorizedCredentials failed verification, source IP not in allowedSourceIps, region not in allowedRegions, or inbound SIP calls disabled on this app.
403ForbiddenThe auth username, Request-URI user-part, and To user-part do not all match the applicationId.
407Proxy Authentication RequiredNo credentials (or a stale nonce). Retry with a digest response built against the returned challenge. Not sent when passwordAuthEnabled: false.
482Loop DetectedYour client has looped the request back into the proxy. Check your routing.
483Too Many HopsMax-Forwards reached zero before the request was delivered.

Verify Inbound SIP URI Settings

Retrieve the current Inbound SIP URI settings for a Voice Application at any time using a GET request. The password is not returned on this call.

curl "https://api.bandwidth.com/v2/accounts/$BANDWIDTH_ACCOUNT_ID/voice-applications/$APPLICATION_ID" \
-H "Authorization: Bearer $ACCESS_TOKEN"

The response includes sipUri, inboundSipCallsEnabled, passwordAuthEnabled, allowedSourceIps, and allowedRegions alongside the application's other configuration. When inbound SIP calls are disabled, sipUri is null and the auth fields are cleared.

Update Allowed Regions

You can update allowedRegions at any time without changing the SIP URI or password by patching only that field:

curl -X PATCH \
"https://api.bandwidth.com/v2/accounts/$BANDWIDTH_ACCOUNT_ID/voice-applications/$APPLICATION_ID" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"allowedRegions": ["US", "EU"]
}'

Update Allowed Source IPs

Similarly, allowedSourceIps can be updated without touching other fields. The full list is replaced with what you send:

curl -X PATCH \
"https://api.bandwidth.com/v2/accounts/$BANDWIDTH_ACCOUNT_ID/voice-applications/$APPLICATION_ID" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"allowedSourceIps": ["203.0.113.0/24", "198.51.100.0/24"]
}'

Rotate the SIP Password

Send passwordAuthEnabled: true again to rotate the password. The old password is invalidated immediately and a new sipAuthPassword is returned in the response:

curl -X PATCH \
"https://api.bandwidth.com/v2/accounts/$BANDWIDTH_ACCOUNT_ID/voice-applications/$APPLICATION_ID" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"passwordAuthEnabled": true
}'

Disable Inbound SIP URI

Disable inbound SIP calls to clear the SIP URI and all auth config from the Voice Application:

curl -X PATCH \
"https://api.bandwidth.com/v2/accounts/$BANDWIDTH_ACCOUNT_ID/voice-applications/$APPLICATION_ID" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"inboundSipCallsEnabled": false
}'

After disabling, sipUri is null, passwordAuthEnabled is false, allowedSourceIps and allowedRegions are empty lists, and the existing credential is invalidated. Re-enabling generates a new SIP URI and (if passwordAuthEnabled: true) a new password.

Using Inbound SIP URI in a Call Flow

Inbound SIP URI is an over-the-top (OTT) entry point into Programmable Voice, distinct from the traditional PSTN path that reaches your application via an SBC and the carrier network. Once a call arrives over the SIP URI, it is handed to the same Programmable Voice call-handling flow as any other inbound call on the Voice Application: the application's configured callInitiatedCallbackUrl fires an initiate webhook, and your backend responds with BXML to control the call.

Next Steps