> ## Documentation Index
> Fetch the complete documentation index at: https://plivo.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# SIP Authentication

> Secure inbound SIP calls to your Plivo applications and authenticate outbound calls to SIP providers

<Info title="TL;DR">
  * **What:** Secure your Plivo voice applications by controlling who can place inbound SIP calls, and authenticate outbound calls to SIP providers that require credentials
  * **How:** Assign an IP ACL, SIP credential, or both to your Plivo Application via the [Application API](/account/api/application/). For outbound, pass credentials in [Dial XML](/voice/xml/routing#dial/) or the [Make Call API](/voice/api/calls/).
  * **Key concept:** Inbound auth resolves from the SIP Request-URI (`sip:{app_id}@app.plivo.com`), not the To header. Your SIP provider must send INVITEs to the application's SIP URI for auth to apply.
  * **Note:** Rate limiting protects against brute-force: 10 failed attempts from the same IP in 60 seconds triggers a 60-second lockout.
</Info>

SIP Authentication lets you secure your Plivo voice applications by controlling who can place inbound SIP calls and by authenticating outbound calls to SIP trunks that require credentials.

<Warning>
  **Request-URI requirement:** For inbound SIP authentication to apply, the Request-URI of the INVITE must be `sip:{app_id}@app.plivo.com`. Plivo resolves the application from the Request-URI user part, not from the To header. If your SIP provider places a phone number in the Request-URI, configure the provider to send INVITEs to the application's SIP URI instead.
</Warning>

***

## Three Authentication Capabilities

| Capability                                  | Direction | What It Does                                                                                        |
| ------------------------------------------- | --------- | --------------------------------------------------------------------------------------------------- |
| **Inbound Authentication**                  | Inbound   | Restrict who can call your Plivo app using IP-based access control, SIP digest credentials, or both |
| **Outbound Authentication (Dial XML)**      | Outbound  | Provide SIP credentials in your Dial XML so Plivo can authenticate with external SIP providers      |
| **Outbound Authentication (Make Call API)** | Outbound  | Same as above, but credentials are passed via the Make Call REST API instead of XML                 |

***

## Inbound Authentication

Inbound authentication protects your Plivo Application from unauthorized SIP calls. You configure it by assigning a credential, IP ACL, or both to your Application.

### Three Options

| Option                         | `sip_auth_type`         | When to Use                                                                                                            |
| ------------------------------ | ----------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **IP ACL only**                | `ip_acl`                | Calls only allowed from whitelisted IP addresses or CIDR ranges. Fastest — no challenge/response handshake.            |
| **Credential only**            | `credential`            | Callers must authenticate with username/password via SIP digest auth (407 challenge). Use when source IPs are dynamic. |
| **Both (IP ACL + Credential)** | `ip_acl_and_credential` | Caller must pass both the IP check AND provide valid credentials. Maximum security.                                    |

### How Inbound Authentication Works

```text theme={null}
Caller sends SIP INVITE to sip:{app_id}@app.plivo.com
   |
   v
Plivo resolves app from Request-URI user part
   |
   v
Plivo checks auth config for the app
   |
   |-- IP ACL configured?
   |     Check caller's IP against allowed list
   |     Not in list -> Call rejected (403)
   |
   |-- Credential configured?
   |     Send 407 Proxy Authentication Required
   |     Caller responds with digest credentials
   |     Wrong credentials -> Call rejected (403)
   |
   |-- Both configured?
   |     IP check first, then credential check
   |     Either fails -> Call rejected (403)
   |
   v
Authentication passed -> Call routed to your app's answer_url
```

### Setup Steps

<Steps>
  <Step title="Create a credential and/or IP ACL">
    Use the [SIP Authentication API](/account/api/sip-authentication/) to create:

    * A **SIP credential** with username and password (`POST /SipAuth/Credential/`)
    * An **IP ACL** with a name (`POST /SipAuth/IpAccessControlList/`), then add IP entries (`POST /SipAuth/IpAccessControlList/{uuid}/Entry/`)
  </Step>

  <Step title="Assign to your Application">
    Update your Application via the [Application API](/account/api/application/) by setting `sip_auth_type` and the corresponding `credential_uuid` and/or `ip_acl_uuid`.
  </Step>

  <Step title="Test">
    Make a test SIP call to your application's SIP URI (`sip:{app_id}@app.plivo.com`) and verify it succeeds with valid auth and fails without.

    To confirm auth is running, check for the `SIPAuthType` parameter in your answer\_url callback (see Callback Parameters below).
  </Step>
</Steps>

### Callback Parameters

When authentication succeeds, your `answer_url` callback receives these additional parameters:

| Parameter     | Description                                                          |
| ------------- | -------------------------------------------------------------------- |
| `SIPAuthType` | Auth method used: `ip_acl`, `credential`, or `ip_acl_and_credential` |
| `SIPAuthUser` | Authenticated SIP username (credential auth only)                    |
| `SIPSourceIP` | The caller's source IP address                                       |

If you don't see `SIPAuthType` in your callback, auth is not running. The most common cause is the SIP provider placing a phone number in the Request-URI instead of your app\_id — see the Warning at the top of this page.

### Rate Limiting and Lockout

To protect against brute-force attacks, Plivo enforces rate limiting on failed authentication attempts:

* Both IP ACL denials and credential denials increment the same per-source-IP failure counter.
* Once the counter crosses **10 failures**, every subsequent call from that IP is rejected with `403 Forbidden` for the remainder of the counter TTL.
* **Updating the IP ACL to include the locked-out IP does NOT clear an active lockout.** The IP stays locked until the counter TTL expires. This is by design.
* IP ACL changes propagate to the SIP edge within \~30 seconds (see FAQ below). During an active lockout, even a freshly allowed IP will be rejected until the counter expires.

***

## Outbound Authentication

When making outbound calls to SIP providers that require authentication (responds with 401/407 challenge), provide credentials so Plivo can complete the digest handshake on your behalf.

### Before You Start

Confirm with your SIP provider:

* **Username and password** for digest authentication
* **Whether they use IP-based auth instead** — if so, you don't need to pass credentials; instead ask the provider to whitelist [Plivo's media server IPs](/voice/concepts/firewall-network-configuration/)
* **Realm** — Plivo handles realm matching automatically from the 407 response, so you generally don't need to configure this

### How Outbound Authentication Works

<Steps>
  <Step title="Plivo sends INVITE">
    Plivo sends a SIP `INVITE` to the destination (e.g., `sip:endpoint@provider.example.com`).
  </Step>

  <Step title="Provider challenges">
    Provider responds with `407 Proxy Authentication Required` (or `401 Unauthorized`).
  </Step>

  <Step title="Plivo computes digest">
    Plivo automatically computes the digest response using the credentials you provided.
  </Step>

  <Step title="Plivo re-sends INVITE">
    Plivo re-sends the `INVITE` with authentication headers.
  </Step>

  <Step title="Call connects">
    Provider accepts and the call connects. If authentication fails, the call ends with hangup cause `sip_auth_failed` (code `4240`).
  </Step>
</Steps>

### Option 1: Dial XML

Pass credentials on the `<User>` element in your answer URL XML:

```xml theme={null}
<Response>
    <Dial>
        <User sipAuthUsername="<sip_username>" sipAuthPassword="<sip_password>">
            sip:endpoint@provider.example.com
        </User>
    </Dial>
</Response>
```

### Option 2: Make Call API

Pass credentials when initiating an outbound call via the API:

```bash theme={null}
curl -X POST "https://api.plivo.com/v1/Account/<auth_id>/Call/" \
  -u '<auth_id>:<auth_token>' \
  -H "Content-Type: application/json" \
  -d '{
    "from": "+14155551234",
    "to": "sip:endpoint@provider.example.com",
    "answer_url": "https://example.com/answer.xml",
    "sip_auth_username": "<sip_username>",
    "sip_auth_password": "<sip_password>"
  }'
```

`sip_auth_username` and `sip_auth_password` are only accepted when `to` is a SIP URI.

### Use Case: Transfer to Human Agent

A common use case is transferring an AI-handled call to a human agent. The agent typically sits behind a softphone, contact center software, or PBX that requires SIP authentication. See [Transfer to Human Agent](/voice/use-cases/transfer-to-human-agent/) for the full workflow.

***

## Hangup Causes

When a call fails due to authentication, the CDR and hangup callback include a specific cause:

| HangupCauseName    | Code   | Direction | CallStatus | Meaning                                                       |
| ------------------ | ------ | --------- | ---------- | ------------------------------------------------------------- |
| `sip_auth_failed`  | `4210` | Inbound   | `failed`   | Caller failed IP ACL or credential check                      |
| `sip_auth_failed`  | `4240` | Outbound  | `failed`   | Provided credentials were rejected by the remote provider     |
| `sip_auth_timeout` | `4250` | Outbound  | `timeout`  | Remote provider did not respond to the authentication attempt |

These values appear in the `HangupCauseName` / `PlivoHangupCause` fields. `CallStatus` stays within the standard set (`completed`, `busy`, `no-answer`, `failed`, `timeout`, `cancel`).

***

## Validation Limits

| Resource                | Limit                                                                               |
| ----------------------- | ----------------------------------------------------------------------------------- |
| IP ACLs per account     | 100                                                                                 |
| Credentials per account | 200                                                                                 |
| Entries per IP ACL      | 50                                                                                  |
| Username                | 3-64 characters. Allowed: letters, digits, `.`, `_`, `-`                            |
| Password                | 8-128 characters. Must include at least one uppercase, one lowercase, and one digit |
| IP ACL name             | Up to 120 characters                                                                |
| Entry description       | Up to 255 characters                                                                |
| CIDR prefix             | 0-32                                                                                |

***

## Reserved `sipHeaders` Prefixes

When using `sipHeaders` on `<User>` or `<Number>` elements within `<Dial>`, or via the Make Call API `sip_headers` parameter, customer-supplied header keys with the following prefixes (case-insensitive) are silently dropped to prevent impersonation of Plivo-internal headers:

`PH-`, `Plivo`, `FS-`, `SipAuth`, `ZT-`, `Twilio`

The exact name `ClientRegion` is also reserved.

### SIP Headers and Raw-Mode Rendering

When the inbound leg used SIP authentication, customer `sipHeaders` are emitted on the outbound B-leg INVITE **without** the `X-PH-` prefix. For example, `CustomerId=123` renders as `X-CustomerId: 123` rather than `X-PH-CustomerId: 123`. This raw-mode rendering is automatic when SIP auth is enabled on the inbound leg.

***

## Non-Auth Mode

When `sip_auth_type` is empty (no authentication configured), inbound SIP calls still require the calling endpoint to be a registered Plivo endpoint as the SIP From user. Calls from unknown From users are rejected with `486 Busy Here`.

***

## Security

Plivo treats SIP credentials with the same care as account credentials:

* Passwords are stored as one-way hashes (HA1) — never in plaintext
* Passwords are never returned in any API response
* SIP auth credentials are never included in CDR data or callback parameters
* Auth headers are stripped before forwarding calls externally
* Failed authentication attempts are rate-limited to prevent brute-force attacks
* All internal communication uses encrypted channels
* **Always use HTTPS for your answer\_url** — Plivo sends callback parameters (including `SIPAuthUser`) over HTTP to your server
* **Validate callbacks with `X-Plivo-Signature`** — verify that callbacks are genuinely from Plivo using [Signature Validation](/voice/concepts/signature-validation/)
* **Beware of shared IPs** — if your SIP provider is on carrier-grade NAT or a shared-IP platform, IP ACL alone may not be sufficient. Use `ip_acl_and_credential` for defense in depth.
* **Monitor auth failures** — track `sip_auth_failed` hangup causes in your call logs to detect unauthorized access attempts

***

## Troubleshooting

| Symptom                                                           | Likely Cause                                             | Fix                                                                                                        |
| ----------------------------------------------------------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| All calls get 403 Forbidden                                       | IP not in ACL, or wrong credentials                      | Verify the caller's IP matches an ACL entry. For credentials, check username/password match exactly.       |
| Calls succeed but no `SIPAuthType` in callback                    | Request-URI doesn't contain your app\_id                 | Configure your SIP provider to send INVITEs to `sip:{app_id}@app.plivo.com`, not to a phone number.        |
| Digest auth fails (`sip_auth_failed`) despite correct credentials | Realm mismatch or provider uses a non-standard challenge | Plivo handles realm automatically. Contact the provider to confirm they send a standard 407/401 challenge. |
| All calls fail after working fine                                 | Rate limit lockout (10 failures in 60s)                  | Wait 60 seconds for lockout to expire. Fix the underlying auth issue.                                      |
| Outbound call fails with `sip_auth_failed` (code 4240)            | Remote provider rejected your credentials                | Verify username/password with the provider. Check if the provider uses IP auth instead of digest.          |
| Outbound call fails with `sip_auth_timeout` (code 4250)           | Remote provider didn't respond to the auth challenge     | Provider may be unreachable. Check network connectivity and provider status.                               |

***

## End-to-End Examples

### Example 1: Secure inbound calls with IP whitelist

```bash theme={null}
# 1a. Create IP ACL
curl -X POST "https://api.plivo.com/v1/Account/<auth_id>/SipAuth/IpAccessControlList/" \
  -u '<auth_id>:<auth_token>' \
  -H "Content-Type: application/json" \
  -d '{"name": "Office Network"}'
# Response: {"ip_acl_uuid": "acl-abc123"}

# 1b. Add an entry
curl -X POST "https://api.plivo.com/v1/Account/<auth_id>/SipAuth/IpAccessControlList/acl-abc123/Entry/" \
  -u '<auth_id>:<auth_token>' \
  -H "Content-Type: application/json" \
  -d '{"ip": "198.51.100.5", "cidr_prefix": 32, "description": "Remote PBX"}'

# 2. Assign to app
curl -X POST "https://api.plivo.com/v1/Account/<auth_id>/Application/<app_id>/" \
  -u '<auth_id>:<auth_token>' \
  -H "Content-Type: application/json" \
  -d '{"sip_auth_type": "ip_acl", "ip_acl_uuid": "acl-abc123"}'

# 3. Call from allowed IP -> connects
# 4. Call from other IP -> 403 Forbidden
```

### Example 2: Secure inbound calls with digest credentials

```bash theme={null}
# 1. Create credential
curl -X POST "https://api.plivo.com/v1/Account/<auth_id>/SipAuth/Credential/" \
  -u '<auth_id>:<auth_token>' \
  -H "Content-Type: application/json" \
  -d '{"username": "pbx-user", "password": "<your_password>"}'
# Response: {"credential_uuid": "cred-def456"}

# 2. Assign to app
curl -X POST "https://api.plivo.com/v1/Account/<auth_id>/Application/<app_id>/" \
  -u '<auth_id>:<auth_token>' \
  -H "Content-Type: application/json" \
  -d '{"sip_auth_type": "credential", "credential_uuid": "cred-def456"}'

# 3. Configure your PBX/SIP client with username "pbx-user" and password from step 1
# 4. Call -> 407 challenge -> PBX responds with credentials -> call connects
```

### Example 3: Outbound call to an authenticated SIP trunk

```bash theme={null}
curl -X POST "https://api.plivo.com/v1/Account/<auth_id>/Call/" \
  -u '<auth_id>:<auth_token>' \
  -H "Content-Type: application/json" \
  -d '{
    "from": "+14155551234",
    "to": "sip:+14155559999@trunk.provider.com",
    "answer_url": "https://example.com/answer.xml",
    "sip_auth_username": "<sip_username>",
    "sip_auth_password": "<sip_password>"
  }'
```

Or via Dial XML in your answer URL:

```xml theme={null}
<Response>
    <Dial>
        <User sipAuthUsername="<sip_username>" sipAuthPassword="<sip_password>">
            sip:+14155559999@trunk.provider.com
        </User>
    </Dial>
</Response>
```

***

## FAQ

***

### Can I use both IP ACL and credential auth together?

Yes. Set `sip_auth_type` to `ip_acl_and_credential`. The caller must pass the IP check AND provide valid credentials.

***

### What happens if I delete a credential or IP ACL that's assigned to an app?

The API returns a 400 error. You must first remove the assignment from the application by setting `sip_auth_type` to empty (`""`).

***

### Can I update the password on an existing credential?

Yes. Send a `POST` to the credential's URL with just the `password` field. The username remains unchanged. The change takes effect immediately for all applications using that credential.

***

### What realm is used for digest authentication?

The default realm is `app.plivo.com`. This is included in the 407 challenge response. Plivo handles realm matching automatically during the handshake.

***

### Can I set different auth for different apps?

Yes. Each application has its own `sip_auth_type`, `ip_acl_uuid`, and `credential_uuid` configuration. You can reuse the same credential or IP ACL across multiple apps.

***

### Does changing an IP ACL take effect immediately?

No. Changes propagate to the SIP edge within \~30 seconds. During that window, calls may still match the previous ruleset.

***

### Can I use a hostname in an IP ACL?

No. IP ACL entries require a valid IPv4 address. Hostnames are not supported.

***

### Can one app have multiple IP ACLs?

No. Each application can have at most one IP ACL and one credential assigned. To allow multiple IP ranges, add multiple entries to a single ACL (up to 50 entries).

***

### What's the latency impact of SIP authentication?

IP ACL adds negligible latency (simple lookup). Credential auth adds one round-trip for the 407 challenge/response (typically under 50ms on well-connected networks).

***

### Can I rotate a password without call interruption?

Yes. Update the password on the credential via the API, then update your SIP client with the new password. There may be a brief window where calls using the old password fail.

***

## Related

* [SIP Authentication API](/account/api/sip-authentication/) — Manage credentials and IP ACLs
* [Application API](/account/api/application/) — Assign auth to your application
* [Voice API: Make a Call](/voice/api/calls/) — Outbound auth via REST API
* [Dial XML](/voice/xml/routing#dial/) — Outbound auth via XML
* [Firewall & Network Configuration](/voice/concepts/firewall-network-configuration/) — Plivo media server IPs
* [Signature Validation](/voice/concepts/signature-validation/) — Verify callbacks are from Plivo
* [Connect External Numbers](/voice/use-cases/connect-external-numbers/) — Route external numbers via SIP
* [Transfer to Human Agent](/voice/use-cases/transfer-to-human-agent/) — Handoff AI calls to humans
