Inbound Dispatch Rules

Inbound Dispatch Rules

Inbound calls reach your agent through a SIP dispatch rule. SIPHON wraps this with Dispatch.

Provider-specific SIP examples (Twilio, Telnyx, Plivo, Wavix): Provider-specific quickstarts

What Dispatch creates

When you run Dispatch(...).agent() SIPHON:

  • Ensures you have an inbound SIP trunk ID (existing or created).
  • Creates a SIP dispatch rule that routes calls to a room/session prefix (for example inbound-call-).
  • Optionally attaches agent configuration as metadata so the worker can use your LLM/STT/TTS + instructions.

Create a dispatch rule

There are two common patterns:

  • A routing-only dispatch rule (agent runs with its own defaults)
  • A dispatch rule that also carries agent configuration (LLM/STT/TTS + instructions)

Routing-only dispatch (no agent config)

Use this when your worker is already configured with defaults and you only need routing.

import os
from siphon.telephony.inbound import Dispatch
from dotenv import load_dotenv

load_dotenv()

dispatch = Dispatch(
    dispatch_name="customer-support",
    agent_name="CustomerSupport",
    sip_trunk_id=os.getenv("SIP_TRUNK_ID"),
    # Or: sip_number=os.getenv("SIP_NUMBER"),
)

dispatch.agent()

Dispatch with agent configuration

Use this when you want the dispatch rule to define (or override) the agent configuration for calls routed through it.

import os
from siphon.telephony.inbound import Dispatch
from siphon.plugins import openai, cartesia, deepgram
from dotenv import load_dotenv

load_dotenv()

llm = openai.LLM()
tts = cartesia.TTS()
stt = deepgram.STT()

dispatch = Dispatch(
    dispatch_name="customer-support",
    agent_name="CustomerSupport",
    sip_trunk_id=os.getenv("SIP_TRUNK_ID"),
    # Alternatively, omit sip_trunk_id and provide sip_number
    # sip_number=os.getenv("SIP_NUMBER"),
    llm=llm,
    stt=stt,
    tts=tts,
    system_instructions="You are a helpful customer support agent.",
    greeting_instructions="Thanks for calling. How can I help?",
)

result = dispatch.agent()
print(result)

Find dispatch rules

You can discover all dispatch rules associated with a phone number or find a specific rule by ID.

Find by phone number

import asyncio
from siphon.telephony.inbound import Dispatch

async def main():
    dispatch = Dispatch()
    result = await dispatch.get_dispatch_rule(sip_number="+15550100")
    print(result)
    # {
    #   "dispatch_rules": [
    #     {
    #       "dispatch_id": "SDR_abc123",
    #       "name": "customer-support",
    #       "trunk_ids": ["ST_xyz789"]
    #     },
    #     {
    #       "dispatch_id": "SDR_def456",
    #       "name": "sales-team",
    #       "trunk_ids": ["ST_xyz789"]
    #     }
    #   ],
    #   "count": 2
    # }

if __name__ == "__main__":
    asyncio.run(main())

This returns ALL dispatch rules using the trunk associated with that phone number.

Find by dispatch ID

result = await dispatch.get_dispatch_rule(dispatch_id="SDR_abc123")
# Returns the specific dispatch rule if found

Delete dispatch rules

You can delete dispatch rules by rule ID or phone number.

Delete by dispatch ID

import asyncio
from siphon.telephony.inbound import Dispatch

async def main():
    dispatch = Dispatch()
    result = await dispatch.delete_dispatch_rule(dispatch_id="SDR_abc123")
    print(result)
    # {
    #   "success": True,
    #   "deleted_count": 1,
    #   "deleted_ids": ["SDR_abc123"]
    # }

if __name__ == "__main__":
    asyncio.run(main())

Delete ALL rules for a phone number

import asyncio
from siphon.telephony.inbound import Dispatch

async def main():
    dispatch = Dispatch()
    result = await dispatch.delete_dispatch_rule(sip_number="+15550100")
    print(result)
    # {
    #   "success": True,
    #   "deleted_count": 2,
    #   "deleted_ids": ["SDR_abc123", "SDR_def456"]
    # }

if __name__ == "__main__":
    asyncio.run(main())

Important: When deleting by phone number, ALL dispatch rules using that number's trunk will be deleted. This is useful for cleaning up multiple rules at once.

Required inputs

  • dispatch_name
    • A stable identifier for the rule (required).
  • One of:
    • sip_trunk_id (use an existing inbound trunk)
    • sip_number (let SIPHON look up or create a trunk for that number)

Next