Twilio Integration

Siphon with Twilio

This guide shows how to connect Twilio Elastic SIP Trunking to SIPHON for:

  • Inbound calls (PSTN -> Twilio -> SIPHON Agent)
  • Outbound calls (Your code -> SIPHON -> Twilio -> PSTN)

Prerequisites

  • A Twilio account with Elastic SIP Trunking enabled
  • Your SIP endpoint is available (from your project settings)
  • A purchased Twilio phone number that supports Voice
  • SIPHON installed and a working agent worker script

You will need:

  • SIP URI / SIP endpoint (from your project settings)
  • Twilio trunk domain (ends with pstn.twilio.com)
  • A Credential List (username/password) for outbound authentication

Project settings showing SIP URI Twilio phone number page


1) Create your Twilio resources (Twilio Console)

Step 1.1: Buy a Twilio phone number

  1. Open the Twilio Console: https://console.twilio.com
  2. Go to:
    • Phone Numbers -> Manage -> Buy a number
  3. Purchase a number that supports Voice.

Purchased Twilio phone number details

Step 1.2: Create an Elastic SIP Trunk

  1. In Twilio Console, go to:
    • Elastic SIP Trunking -> Manage -> Trunks
  2. Click Create new SIP Trunk
  3. Set:
    • Friendly Name: e.g. SIPHON Trunk
    • Domain: Twilio will create a domain that ends with pstn.twilio.com (required by Twilio)

Created Trunk Created Trunk Details

Step 1.3 (Inbound): Create an Origination Connection Policy and point it to your SIP endpoint

This makes Twilio forward inbound calls to your SIP endpoint.

  1. In Twilio Console, go to:

    • Elastic SIP Trunking -> Manage -> Trunks -> select your trunk -> Origination
  2. Add new Origination URI New Origination URI

  3. Set Origination SIP URI to your LiveKit project’s SIP endpoint (the SIP URI shown in your project settings - on cloud).

    • Example format: sip:<your-project>.sip.livekit.cloud

Origination SIP URI Origination SIP URI SET

Step 1.4 (Outbound): Create a Credential List and attach it to the trunk

This is required for SIPHON to authenticate when placing outbound calls through Twilio.

Step 1.4.1: Create the credential list

  1. In Twilio Console, go to:

    • Elastic SIP Trunking -> Manage -> Credential lists Credential list page
  2. Create a new credential list.

  3. Add a credential (choose a username/password).

Credential list created Credential added

Step 1.4.2: Associate the credential list with your trunk

  1. Go to:
    • Elastic SIP Trunking -> Manage -> Trunks -> select your trunk
  2. Go to:
    • Termination -> Authentication -> Credential Lists
  3. Select the credential list you created
  4. Click Save

Trunk termination authentication using the credential list

Step 1.4.3: Copy the trunk domain

On the same trunk page, find the termination SIP URI and create, save and copy the trunk domain.

You will typically use:

  • The trunk domain (e.g. siphon-trunk.pstn.twilio.com) as the sip_address value in SIPHON

Trunk termination SIP URI

Step 1.5: Attach your Twilio phone number to the trunk

  1. Go to:

    • Elastic SIP Trunking -> Manage -> Trunks -> select your trunk -> Numbers SIP number list page
  2. Find the section to associate/attach phone numbers to the trunk

  3. Attach the phone number you purchased

Phone number associated with the SIP trunk

2) SIPHON setup (Inbound + Outbound)

Step 3.1: Run your agent worker

Start your agent worker (dev or prod):

  • Agent(...).dev() for local development
  • Agent(...).start() for production

Make sure your environment is configured:

  • LIVEKIT_URL
  • LIVEKIT_API_KEY
  • LIVEKIT_API_SECRET

Step 3.2 (Inbound): Create the inbound dispatch in SIPHON

Inbound calls are routed to a worker by agent_name. Ensure the same agent_name is used by:

  • your running agent worker, and
  • your inbound dispatch

Example:

from siphon.telephony.inbound import Dispatch

dispatch = Dispatch(
    agent_name="Calling-Agent-System",
    dispatch_name="twilio-inbound",
    sip_number="+15105550123",
)

dispatch.agent()

Now, when a PSTN caller dials your Twilio number:

  • Twilio forwards the call to your SIP endpoint (via the Origination policy)
  • SIPHON routes the call to your agent worker (by agent_name)
  • Your agent session starts and runs the voice loop

Step 3.3 (Outbound): Place a call from code

Example:

from siphon.telephony.outbound import Call

call = Call(
    agent_name="Calling-Agent-System",
    sip_trunk_setup={
        "name": "twilio-primary",
        "sip_address": "<your-twilio-trunk-domain>",
        "sip_number": "+15105550123",
        "sip_username": "<twilio-credential-username>",
        "sip_password": "<twilio-credential-password>",
    },
    number_to_call="+14155550100",
)

call.start()

Notes:

  • sip_address should be your Twilio trunk domain (example: my-trunk.pstn.twilio.com).
  • The username/password must match the Twilio Credential List attached under trunk Termination Authentication.

4) Testing checklist

Inbound test

  1. Confirm the SIPHON worker is running
  2. Call your Twilio number from a real phone
  3. Confirm:
    • The SIP participant appears
    • The agent greets/responds (if enabled)

Outbound test

  1. Confirm the SIPHON worker is running
  2. Run your outbound Call(...).start() script
  3. Confirm:
    • PSTN destination rings
    • Agent audio is heard

Common issues

Twilio trial account limitations

  • Twilio trial projects often restrict calling to verified phone numbers only.
  • If outbound calls fail (or inbound doesn’t behave as expected), confirm the destination/source numbers are verified in your Twilio Console.
  • To remove these limits, upgrade your Twilio account.

Inbound calls don’t reach SIPHON

  • Verify Twilio Origination SIP URI is set to your project’s SIP endpoint
  • Verify your Twilio number is attached to the trunk
  • Verify you created a SIPHON inbound dispatch (and that dispatch_name is unique)
  • Verify agent_name matches the worker you are running

Outbound calls fail authentication

  • Ensure the Twilio Credential List is attached to the trunk under Termination Authentication
  • Ensure the SIPHON sip_trunk_setup username/password exactly match the Twilio credentials

Outbound calls fail routing / wrong caller ID

  • Ensure you’re passing sip_trunk_setup["sip_number"] with a Twilio number you own/attached to the trunk