Telephony

SIP & Telephony

The SIP server bridges phone calls and SIP trunks into the same voice pipeline used by browser clients, transcoding between PCMU and Opus transparently.

Architecture

The SIP server sits between the phone network and the StreamCore AI server:

Phone NetworkSIP (PCMU/RTP @ 8kHz)SIP Server (transcode)WHIP (Opus/WebRTC @ 48kHz)StreamCore AI Server

What the SIP server does

  • Listens for incoming SIP INVITE on UDP 5060
  • Opens a local RTP listener for each call (G.711 μ-law at 8kHz)
  • Transcodes audio: 8kHz PCMU ↔ 48kHz Opus
  • Connects to the StreamCore AI server via the Go SDK (WHIP)
  • Manages call lifecycle (answer, hangup, timeout)

Supported Trunk Providers

Asterisk (local testing)

Dockerized Asterisk PBX for end-to-end local testing without a trunk provider. Included in the repo.

Twilio

Elastic SIP Trunking. Connect real phone numbers to your voice agent.

RingCentral

SIP trunk proxy integration for enterprise telephony.

REST API

The SIP server exposes a REST API for call management:

MethodPathDescription
GET/healthHealth check
GET/providersList available trunk providers
GET/callsList active calls
POST/callsInitiate outgoing call (requires provider)
DELETE/calls/{id}Hang up a call

Quick Start with Asterisk

Test the full phone-to-voice-agent pipeline locally using the included Asterisk Docker setup:

1. Start the StreamCore AI server

cd server && go run .

2. Start the SIP server with Asterisk

cd sip-server
docker compose up -d    # Starts Asterisk PBX
go run .                # Starts the SIP bridge

3. Make a test call

Use a SIP client (like Linphone or Zoiper) to call the Asterisk PBX. The call will be bridged through to the voice agent.

# Or use the REST API to initiate an outgoing call
curl -X POST http://localhost:8090/calls \
  -H "Content-Type: application/json" \
  -d '{"provider": "asterisk", "to": "1001"}'

Twilio Setup

To connect real phone numbers via Twilio Elastic SIP Trunking:

  1. 1. Create a Twilio Elastic SIP Trunk in the Twilio console
  2. 2. Set the Origination URI to your SIP server’s public IP (port 5060)
  3. 3. Assign a phone number to the trunk
  4. 4. Configure the SIP server with the Twilio provider credentials
  5. 5. Incoming calls to the assigned number will be bridged to the voice agent

Audio Transcoding

The SIP server handles the codec mismatch between telephony and WebRTC:

DirectionFromToNotes
Inbound (caller → agent)G.711 μ-law @ 8kHzOpus @ 48kHzUpsample + encode
Outbound (agent → caller)Opus @ 48kHzG.711 μ-law @ 8kHzDecode + downsample

Design Decisions

Why a separate server?

SIP and WebRTC are fundamentally different protocols. Keeping the SIP bridge separate means the core server stays focused on WebRTC performance, and the SIP server can be deployed independently or not at all.

Why use the Go SDK internally?

The SIP server connects to the StreamCore AI server using the same Go SDK that external clients use. This ensures the telephony path goes through the exact same pipeline as browser clients.

Asterisk for testing

The Dockerized Asterisk PBX lets you test the full end-to-end telephony flow without a real trunk provider or phone number. Just connect a SIP softphone to the local PBX.