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

# Configure Twilio SIP

> Point Twilio Elastic SIP Trunking at Sayna’s SIP endpoint and let Sayna handle the LiveKit plumbing.

Sayna auto-provisions the LiveKit SIP trunk + dispatch rule as soon as you populate the [`sip` configuration](/guides/sip) and provide `LIVEKIT_API_KEY` / `LIVEKIT_API_SECRET`. All you need to do on the carrier side is tell Twilio where to send calls.

> **TL;DR** – Create/choose a Twilio Elastic SIP trunk, add Sayna’s SIP domain/IP to the **Origination** list as a SIP URI (e.g., `sip:sip.sayna.ai;transport=tcp`), and make sure Twilio’s source IP ranges are present in `SIP_ALLOWED_ADDRESSES`.

## Prerequisites

1. `sip` block configured in Sayna (`room_prefix`, `allowed_addresses`, optional `hooks`).
2. Public DNS record or static IP that routes to your Sayna deployment (Load balancer, ingress, etc.).
3. LiveKit credentials so Sayna can create the trunk + dispatch rule automatically.
4. Twilio account with Elastic SIP Trunking enabled.

<Callout>
  Sayna creates the LiveKit resources (names `sayna-{prefix}-trunk` / `sayna-{prefix}-dispatch`) so you **do not** need to follow LiveKit’s manual steps from their quickstarts. Focus on the Twilio console configuration only.
</Callout>

## Step 1 — Expose Sayna’s SIP endpoint

* Pick a hostname such as `sip.yourcompany.com` that resolves to the Sayna service running with SIP enabled.
* Ensure TCP 5060/5061 reaches Sayna (or whatever port your reverse proxy exposes for SIP traffic).
* Add Twilio’s regional egress IP ranges to `SIP_ALLOWED_ADDRESSES` so Sayna accepts their traffic. Twilio lists these ranges in the [Elastic SIP Trunking IP access control documentation](https://www.twilio.com/docs/sip-trunking/ip-addresses) — copy the ranges for every region you plan to use.

Example env vars:

```bash theme={null}
export SIP_ROOM_PREFIX="sip-"
export SIP_ALLOWED_ADDRESSES="54.172.60.0/23,34.203.250.0/23,52.40.51.128/25" # Twilio us-east-1 + us-west-2
export SIP_HOOKS_JSON='[{"host":"sip.yourcompany.com","url":"https://backend.yourcompany.com/sip/events"}]'
```

Once Sayna boots, it provisions the LiveKit trunk/dispatch and you’ll see log lines similar to:

```text theme={null}
INFO Successfully provisioned SIP resources: trunk=sayna-sip--trunk, dispatch=sayna-sip--dispatch
```

## Step 2 — Create or select a Twilio trunk

1. In the Twilio Console, navigate to **Elastic SIP Trunking → Trunks**.
2. Create a new trunk or open an existing one dedicated to Sayna.
3. Give it a meaningful name (e.g., `SaynaBridge`).

You do not need to configure **Termination** for this integration unless you want Sayna to place outbound PSTN calls via Twilio. We only care about **Origination** (Twilio → Sayna).

## Step 3 — Configure origination URI

Twilio needs to know where to send inbound SIP INVITE requests. Use the domain/IP where Sayna listens for SIP traffic.

1. Inside the trunk, go to the **Origination** tab.
2. Click **Add new Origination URI**.
3. Set **SIP URI** to the Sayna address with TCP enforced:
   ```text theme={null}
   sip:sip.yourcompany.com;transport=tcp
   ```
4. (Optional) Specify a **Friendly Name** like “Sayna Primary”.
5. Leave the weight/priority defaults unless you have multiple Sayna regions.
6. Save the trunk.

<Info>
  Twilio supports TLS/SRTP as well, but Sayna currently expects TCP. Keep the `;transport=tcp` suffix in the URI to avoid UDP-only failures.
</Info>

Behind the scenes Twilio now dials `sip.yourcompany.com` whenever the trunk’s phone numbers receive a call. Sayna detects the `room_prefix`, routes the call into the auto-provisioned LiveKit room, and forwards events/webhooks per your SIP configuration.

## Step 4 — Map numbers to the trunk

1. Still in the Twilio Console, open **Phone Numbers → Manage → Active numbers**.
2. Assign the desired DID(s) to the trunk you configured.
3. Test by dialing the number and watching Sayna logs—the connection should hit the SIP trunk and trigger your WebSocket workflow.

## Operational checklist

* **Allowed addresses** – keep Twilio IP ranges current; Twilio occasionally adds regions.
* **Health checks** – monitor Sayna logs for `Failed to provision SIP resources` to catch LiveKit credential issues early.
* **Recording + hooks** – configure `livekit.enable_recording` and `SIP_HOOKS_JSON` in Sayna if you want downstream webhooks when Twilio callers join/leave.
* **Twilio failover** – add a backup Origination URI (secondary Sayna region) with lower priority if you run multi-region fleets.

## Troubleshooting

| Symptom                                           | Likely cause                                   | Fix                                                                                                  |
| ------------------------------------------------- | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| Twilio calls immediately fail                     | Origination URI unreachable or wrong transport | Verify DNS resolves to Sayna, firewall allows TCP 5060/5061, and URI uses `;transport=tcp`.          |
| Twilio 403/603 responses                          | Sayna rejected IP                              | Add the relevant Twilio IP range/CIDR to `SIP_ALLOWED_ADDRESSES`.                                    |
| Sayna logs “SIP room\_prefix is required”         | SIP env vars incomplete                        | Set `SIP_ROOM_PREFIX` (and other SIP vars) before starting Sayna.                                    |
| Calls reach Sayna but never hit LiveKit           | LiveKit credentials missing or invalid         | Ensure `LIVEKIT_API_KEY`/`LIVEKIT_API_SECRET` are configured so auto-provisioning can join the room. |
|                                                   |                                                |                                                                                                      |
| LiveKit room created but no downstream hooks fire | `SIP_HOOKS_JSON` empty or host mismatch        | Populate hooks with the domains you expect in `sip.h.to` headers.                                    |

## Related docs

* [SIP configuration](/guides/sip) – field-by-field breakdown of Sayna’s SIP options (room prefix, hooks, auto-provisioning).
* [Twilio guide](https://docs.livekit.io/sip/quickstarts/configuring-twilio-trunk/) – reference article that inspired this flow (follow only the Twilio console steps; Sayna handles the LiveKit pieces).
