CalloraVoipSdk
Build your own voice product on a sovereign telephony core.
European B2B voice runtime for teams building calling, dialer, contact center, or voice AI products — with full technical control over telephony, media path, and intelligent decision logic.
Built for
- PBX and UC vendors
- Contact center software makers
- Dialer and campaign tools
- CRM/Sales automation with calling
- Voicebot and AI agent platforms
- Fraud, spam and scam detection systems
Current Status
Latest release: v4.6.0 on nuget.org (this documentation). It adds the WebRTC facade, DTLS-SRTP with AEAD-AES-GCM, and a self-hostable STUN/TURN server on top of the stable SIP + RTP core.
How to read the status column. Stable = mature, covered by the RFC-oriented test suite and by automated interop, and the intended production surface. Opt-in = shipped and tested, but off by default and not yet proven in production traffic — validate for your environment first. The production-proven NAT path is symmetric RTP (comedia), which needs no ICE or STUN. The SIP + RTP core is exercised by an automated interop suite against a real Asterisk (PJSIP) container in CI — calls, media, codecs, SRTP-SDES, DTMF, transfer, session timers, early media and TCP/TLS, plus a two-leg bridged call with byte-exact bidirectional media (currently all cases green, none skipped). The WebRTC path is validated in CI against real Chromium and Firefox and a real coturn relay (see the interop matrix). Known gaps and interop defects are tracked openly in the issue tracker.
Core (SIP + RTP):
| Capability | Status |
|---|---|
| SIP Register / Dial / Accept / Hangup | ✅ Stable |
| Hold / Unhold / Blind + Attended Transfer | ✅ Stable |
| REFER transfer progress subscription (RFC 3515 / 6665) | ✅ Stable |
| Early media (RFC 3960): pre-answer receive-only media + DTMF in the early dialog | ✅ Stable |
| RTP media transport | ✅ Stable |
| SRTP + SRTCP media encryption (SDES, offer & answer; RFC 4568 / RFC 3711) | ✅ Stable |
| DTLS-SRTP media encryption (RFC 5763, incl. AEAD-AES-GCM per RFC 7714) | ✅ Stable |
| Adaptive jitter buffer | ✅ Stable |
| Media cross-connect / bridge | ✅ Stable |
| Per-call media tap (frame receivers/senders for bots and streaming) | ✅ Stable |
Module registry (client.Modules) as plugin extension point |
✅ Stable |
| Configurable audio codec preference | ✅ Stable |
| DTMF send/receive (RFC 4733) | ✅ Stable |
| SIP MESSAGE send & receive (RFC 3428) | ✅ Stable |
| SIP PUBLISH: event-state publish / refresh / modify / remove (RFC 3903) | ✅ Stable |
| RTCP quality metrics (measured jitter, loss, round-trip time) | ✅ Stable |
| Recording + Playback (WAV/MP3) | ✅ Stable |
| Linux + Windows audio devices | ✅ Stable |
| Runtime device hot-switch + controls | ✅ Stable |
| Encoded video: send/receive, transport-cc bitrate recommendation, keyframe feedback (transport-only) | ✅ Stable (single-stream) |
WebRTC and NAT traversal:
| Capability | Status |
|---|---|
| WebRTC facade: peer connections, SDK-driven signalling, W3C tracks, media taps (transport-only) | ✅ Stable — browser-validated (Chromium + Firefox, both roles) |
WebRTC video repair & congestion control: NACK/PLI/FIR, RTX, transport-cc, getStats |
✅ Stable |
| Send-side simulcast (RFC 8853 / 8852) | ✅ Stable (send-side only — receive-side RID demux not included) |
| Data channels (SCTP) | 🚫 Not included |
| Self-hostable STUN / TURN server (RFC 5389 / 5766 / 8656) | ✅ Stable — verified against coturn (UDP relay only) |
ICE for NAT traversal (RFC 8445/7675: role + tie-breaker, check-list FSM, nomination, inbound/triggered checks, consent freshness, restart incl. RestartIceAsync) |
⚙️ Opt-in — off by default, unproven in production trunks |
| ICE-TCP candidates (RFC 6544) | 🚫 Not included (deliberate — trunk calls use symmetric RTP) |
| Backend/API for signed plugin marketplace + tenant entitlements | 📋 Roadmap |
Choose your integration depth
CalloraVoipSdk uses a progressive API. Start with managed workflows for registration,
dialing, default audio, playback and recording. When the product needs more control, the
same call remains available through typed IPhoneLine/ICall contracts, encoded media
receivers/senders, cross-connect, custom devices, telemetry and modules.
The boundary is deliberate: supported call, media and extension seams are public, while transport/parser implementation types and arbitrary wire mutation remain internal. Choose the right depth →
SDK Structure
CalloraVoipSdk.Core — Sovereign calling foundation
Clean DDD architecture: Domain → Application → Infrastructure → public VoipClient facade.
No vendor lock-in. Full protocol stack owned in-house (SIP, RTP, SRTP, DTLS-SRTP, SDP,
STUN/TURN client and server) — no external SIP/RTP/ICE library.
Commercial plugins (private feed, licensed separately — in development)
The SDK core is open and free. Advanced capabilities ship as paid plugins on a private feed, built on the public module registry and media-tap contract:
- Callora.Realtime — bridge call audio to realtime AI APIs (e.g. OpenAI Realtime) with pacing, backpressure and barge-in; the foundation for AI voice agents
- Callora.WebSocket — raw call-audio streaming over WebSocket
- Callora.Privacy — redaction, consent management, policy gates, audit trail
- Callora.Risk — spam/scam signals, call risk screening, PBX abuse prevention
- Callora.Intelligence — AMD, sentiment, transcription, local model integration
Interested in early access? Contact info@bechstein.digital.
Quickstart
using var client = new VoipClient(new VoipConfiguration
{
LoggerFactory = loggerFactory,
UserAgent = "MySoftphone/1.0"
});
var connectResult = await client.ConnectAsync(new SipAccount
{
Username = "1001",
Password = "secret",
SipServer = "pbx.example.com"
});
if (!connectResult.IsSuccess || connectResult.Line is null)
throw new InvalidOperationException($"Connect failed: {connectResult.Status}");
var dialResult = await client.DialAndWaitUntilConnectedAsync(
connectResult.Line,
"sip:1002@pbx.example.com");
if (!dialResult.IsSuccess || dialResult.Call is null)
throw new InvalidOperationException($"Dial failed: {dialResult.Status}");
await client.AttachDefaultAudioAsync(dialResult.Call);
await dialResult.Call.HangupAsync();
→ Getting Started · Progressive API · Core Concepts · Guides · WebRTC · Interop · Production · Capacity