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
- You have created a Voice Application and have its
applicationId. - You have generated API credentials with access to the Voice Application Management API.
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": []
}
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:
| Input | Result | Why |
|---|---|---|
203.0.113.0/24 | Accepted | Public IPv4, canonical form |
198.51.100.5/32 | Accepted | Single public IP |
0.0.0.0/0 | Accepted | Wide-open — explicit customer choice |
192.168.1.5/24 | Rejected | Host bits set — ambiguous intent |
10.0.0.0/8 | Rejected | RFC 1918 private range |
172.16.0.0/12 | Rejected | RFC 1918 private range |
192.168.0.0/16 | Rejected | RFC 1918 private range |
127.0.0.0/8 | Rejected | Loopback |
169.254.0.0/16 | Rejected | Link-local |
::1/128 | Rejected | IPv6 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:
| Tier | Role | CIDR (us-east-2) |
|---|---|---|
| Signaling | SIP signaling: authentication, routing, and call setup | 3.43.67.32/28 |
| Media | RTP media | 3.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.
| Record | Type | Notes |
|---|---|---|
sip-uri.voice-api.bandwidth.com | A (multi-value) | Each value is the IP of a live signaling instance. |
_sip._udp.sip-uri.voice-api.bandwidth.com | SRV (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.
| Field | Value |
|---|---|
| SIP URI | sipUri returned in the enable response |
| Authentication User | The Voice Application's applicationId (also the user-part of the URI) |
| Authentication Realm | sip-uri.voice-api.bandwidth.com |
| Password | sipAuthPassword 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-Authorizationheader. A firstINVITEwithout credentials receives a407 Proxy Authentication Requiredchallenge 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. OPTIONSrequests sent to the SIP URI host are answered with200 Keepalive. Clients that emit periodicOPTIONSfor path liveness work out of the box. No SIPREGISTERis 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:
| Purpose | Protocol & Ports | Destination CIDR |
|---|---|---|
| SIP signaling | UDP 6160 | 3.43.67.32/28 |
| RTP / RTCP media | UDP 30000-40000 | 3.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:
| Code | Meaning | Common cause |
|---|---|---|
| 200 | OK / Keepalive | Call established, or a successful OPTIONS response. |
| 401 | Unauthorized | Credentials failed verification, source IP not in allowedSourceIps, region not in allowedRegions, or inbound SIP calls disabled on this app. |
| 403 | Forbidden | The auth username, Request-URI user-part, and To user-part do not all match the applicationId. |
| 407 | Proxy Authentication Required | No credentials (or a stale nonce). Retry with a digest response built against the returned challenge. Not sent when passwordAuthEnabled: false. |
| 482 | Loop Detected | Your client has looped the request back into the proxy. Check your routing. |
| 483 | Too Many Hops | Max-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
- Voice Application Management API Reference covers the full API surface, error codes, and request/response examples.
- Voice Applications explains how to manage the container that holds your Inbound SIP URI settings.
- Programmable Voice Quick Start walks through configuring call handling once your Inbound SIP URI is live.