- 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
speaks the control-plane tRPC surface over HTTPS). The AudioBridge data plane
binds a bundled native transport library — the shared QUIC/MoQT engine core used
by every TeleQuick native SDK — via callbacks. There is no async/tokio
Voice surface today; run the control-plane calls from a blocking context (or
tokio::task::spawn_blocking), and treat the audio callbacks as running on the
transport thread. See Native transport library.Install
The Voice module ships in the TeleQuick 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 your audio bridges dial.
Voice hands out the three sub-clients:
| Method | Returns | Plane |
|---|---|---|
voice.calls() | Calls | Control — originate / fetch / transfer / hangup |
voice.agents() | Agents | Control — bind a server-side agent to a call |
voice.audio_bridge() | AudioBridgeFactory | Data — attach to a live call’s audio |
Place and control a call
Originate
Calls::originate takes an OriginateArgs and returns a Call whose data
field carries the assigned sid and initial status.OriginateArgs
Destination in E.164 (
+14155550101).Caller-ID / originating number in E.164.
The trunk to route the outbound leg over. Configure trunks in the console; see
SIP trunking.
Bind a server-side agent to answer the call.
None originates a bare call you
drive yourself (e.g. via AudioBridge).Seconds to ring before giving up.
OriginateArgs::default() sets 30.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; executing the outbound leg from a peer-initiated REFER is still
partial in the engine — see
AI ⇄ human handoff
for what’s wired end-to-end.Stream call audio (AudioBridge)
When you want to send and receive raw media yourself — feed uplink to your own
ASR, play your own TTS back — attach an AudioBridge to a live call_sid. The
factory subscribes to the caller’s audio (voice/<sid>/uplink) and opens a
publication for audio back to the caller (voice/<sid>/downlink) in one call.
Codec::Opus | Pcm16 | G711ULaw | G711ALaw. This is the on-track capability;
audio is audio-only (no video codecs in Voice). The runtime bus is 8 kHz PCM16
end-to-end — see
Codecs.Wire sample rate.
AudioBridgeOpts::default() is Opus / 48000 / 1 channel /
20 ms.Channel count (voice is mono).
Frame duration in milliseconds (20 ms = one media tick).
Bind a server-side agent
If you’d rather 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 — so:
- Build and run with the native library on your linker/library path
(
RUSTFLAGS="-L …",LD_LIBRARY_PATH=…). - The transport auto-reconnects with backoff and re-announces / re-subscribes every track on reconnect — no app code. You can publish/subscribe before the session is up; calls are queued and replayed 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
telequick::moqt
(MoqtClient::connect, publish_audio, subscribe_audio) if you need
capabilities beyond the Voice convention — for example subscribing with an
explicit filter or window. AudioBridge is the ergonomic wrapper that applies
the voice/<sid>/{uplink,downlink} naming for you.What’s not in the Rust surface
Grounding you before you reach for something that isn’t here:- No async Voice API. Control-plane calls block; there is no
tokio-native Voice client. Wrap them inspawn_blockingif you’re 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.