- a control plane —
Calls,Agents— a small blocking client over the control-plane API (originate, transfer, hangup, bind an agent), and - a data plane —
AudioBridge— bidirectional call audio (Opus / PCM16 / G.711) over QUIC (MoQT), with thevoice/<sid>/{uplink,downlink}track convention enforced for you.
The control-plane client (
Calls/Agents) is synchronous and blocking (it
uses the control-plane tRPC surface over HTTPS). The AudioBridge data plane
binds a bundled native transport library through callbacks. That library is
the shared QUIC/MoQT engine core used by every ClutchCall native SDK. There
is no async/tokio Voice surface today. Run the control-plane calls from a
blocking context (or tokio::task::spawn_blocking). Treat the audio callbacks
as code that runs on the transport thread.
See Native transport library.Install
The Voice module ships in the ClutchCall Rust SDK crate. Add it to yourCargo.toml:
Connect
Construct aVoice client with your control-plane API base URL, an API key,
and your workspace (org) id. The key and org scope every control-plane request.
The client also carries the relay_host that your audio bridges dial.
Voice hands out the three sub-clients:
Place and control a call
1
Originate
Calls::originate takes an OriginateArgs and returns a Call whose data
field carries the assigned sid and initial status.2
Fetch an existing call
Look a call up later by its
sid:3
Transfer or hang up
A
Call exposes the control operations. Transfers map onto the same
control-plane route (voice.calls.transfer). Pass a PSTN number or an
agent.OriginateArgs
&str
required
Destination in E.164 (
+14155550101).&str
required
Caller-ID / originating number in E.164.
&str
required
The trunk to route the outbound leg over. Configure trunks in the console. See
SIP trunking.
Option<&str>
default:"None"
Bind a server-side agent to answer the call.
None originates a bare call you
drive yourself (for example, via AudioBridge).u32
default:"30"
The number of seconds to ring before the attempt stops.
OriginateArgs::default() sets 30.CallData
The returned
Call carries a CallData with sid, status, to, from,
started_at, trunk_id: Option<String>, and agent: Option<String>.transfer_to performs a SIP REFER-based transfer. Operator-initiated transfers
are shipped. Execution of the outbound leg from a peer-initiated REFER is
still partial in the engine. See
AI ⇄ human handoff
for what is wired end-to-end.Stream call audio (AudioBridge)
Attach an AudioBridge to a live call_sid when you want to send and receive
raw media yourself — for example, to feed uplink to your own ASR and play your
own TTS back. In one call, the factory subscribes to the caller’s audio
(voice/<sid>/uplink) and opens a publication for audio back to the caller
(voice/<sid>/downlink).
Codec
default:"Codec::Opus"
Codec::Opus | Pcm16 | G711ULaw | G711ALaw. This is the on-track capability.
Voice is audio-only (there are no video codecs). The runtime bus is 8 kHz
PCM16 end-to-end — see
Codecs.u32
default:"48000"
Wire sample rate.
AudioBridgeOpts::default() is Opus / 48000 / 1 channel /
20 ms.u8
default:"1"
Channel count (voice is mono).
u16
default:"20"
Frame duration in milliseconds (20 ms = one media tick).
Bind a server-side agent
To let a configured agent (ASR/LLM/TTS or a speech-to-speech provider) run the conversation, attach one to a live call instead of bridging audio yourself:End-to-end example
Native transport library
The control plane (Calls, Agents) is pure Rust over HTTPS and needs no
native dependency. The data plane (AudioBridge, and the underlying
MoqtClient in the crate’s moqt module) binds the bundled native QUIC/MoQT
transport core, the same engine core shared across the native SDKs. This
means:
- Build and run with the native library on your linker/library path
(
RUSTFLAGS="-L …",LD_LIBRARY_PATH=…). - The transport auto-reconnects with backoff. It re-announces and re-subscribes every track on reconnect, with no app code. You can publish and subscribe before the session is up. The SDK queues those calls and replays them on connect.
- Native SDKs get the QUIC → WebSocket fallback ladder transparently for UDP-blocked networks. (The browser/TS SDK is WebTransport-only today; this fallback is a native-core benefit.)
The lower-level track API is available directly as
clutchcall::moqt
(MoqtClient::connect, publish_audio, subscribe_audio). Use it if you
need capabilities beyond the Voice convention — for example, a subscription
with an explicit filter or window. AudioBridge is the wrapper that applies
the voice/<sid>/{uplink,downlink} naming for you.What’s not in the Rust surface
Know these limits before you look for a feature that is not here:- No async Voice API. Control-plane calls block. There is no
tokio-native Voice client. Wrap the calls inspawn_blockingif you are inside a runtime. - No human-agent control channel. The event-driven softphone/agent control
channel (call-offered / accept / reject) currently ships only in the
TypeScript SDK. In Rust, drive calls via
Calls/Agentsand bridge audio viaAudioBridge. - No browser capture. WebRTC-diversion mic capture is a browser-only concern (Browser audio capture). The Rust SDK is a server-side / backend client.
Next steps
Calls API
The control-plane routes behind
Calls — originate, transfer, hangup.Transport & tracks
The MoQT track model
AudioBridge builds on.Sessions, calls & tracks
How
call_sid and the voice/<sid>/{uplink,downlink} layout fit together.Outbound call cookbook
A full originate → stream → hang up walkthrough.

