Skip to content

Cookbook

Build real things, fast. Each recipe is a complete, working starting point — the YAML config, the Python script, and how to test it — for a common SIP role. They're deliberately small (usually under 60 lines of Python) so you can read the whole thing and adapt it.

Every recipe is grounded in a real script in the repo (linked at the bottom of each page); none of the APIs here are invented.

The recipes

Recipe What you build Key ideas
Registrar A SIP registrar with digest auth auth.require_digest, registrar.save/lookup, NAT fixups
Stateful proxy A residential/edge proxy request.fork, loose_route, record_route, sanity checks
Load balancer A front LB over a backend pool gateway.select, health probing, subscriber affinity
SBC (B2BUA) A topology-hiding SBC with media @b2bua.*, call.dial/fork, header policies, RTPEngine
Media & RTP profiles SRTP↔RTP, WebRTC, transcoding, hold rtpengine.offer/answer, profiles, the sdp namespace
Hardening & security A locked-down edge rate-limit, scanner/auth bans, TLS/mTLS, STIR/SHAKEN, IPsec
Monitoring & observability Metrics, CDRs, tracing, probes custom Prometheus metrics, /admin/*, CDR, HEP/Homer

How to run any recipe

Each recipe is a siphon.yaml + a Python script. Point the config at the script and run siphon:

# siphon.yaml
script:
  path: "/etc/siphon/myscript.py"
siphon --config /etc/siphon/siphon.yaml

Scripts hot-reload — edit and save, no restart (except listen: changes). Test your script logic without a running server using the siphon-sip mock SDK.

Mixing roles

A single script can be several of these at once — the dispatcher routes INVITEs to your @b2bua.on_invite handler and everything else to @proxy.on_request. So a "proxy for REGISTER/OPTIONS + SBC for calls" is one script, one process (see the SBC recipe and the README's hybrid-mode section).

For running more than one node, see Scaling & redundancy and Deployment & operations.