The AudioBridge helper in the SDK is a thin wrapper. Under it, every call’s audio is two live MoQT tracks that the relay fans out. This page is the surface below the SDK. It documents the raw publish_audio / subscribe_audio primitive, the exact namespace layout for a call, the capability tags that route a track, and how the relay authorizes you to touch a namespace. Use this surface when you bridge your own runtime, tape a call into a recorder, or connect a human agent to a live caller. Read Realtime Tracks (MoQT) first for the general model (namespace + name + capability, connect/backoff/reconnect, track kinds). Everything here is that model, pinned to voice.

The two tracks of a call

The call_sid keys every call (see Sessions, calls, tracks & streams). The call’s audio lives under a per-call namespace, split by direction, with the track name audio: The RTP media plane publishes the caller’s audio to uplink. It subscribes to downlink for playback. The track that you publish and the track that you subscribe to depend on your side:
  • Agent / server side (the common case) — subscribe to uplink to hear the caller. Publish downlink to talk back.
  • Browser-caller side — the mirror: subscribe to downlink to play cloud audio. Publish uplink with captured mic frames.
Uplink and downlink are distinct namespaces on purpose. A single track would feed the agent its own output. The same split lets a human agent or a supervisor subscribe to uplink alone and hear only the caller (see Handoffs).

Publish & subscribe

publish_audio(ns, name, …) returns a publication. The publication’s write(ts_us, frame) sends one encoded audio frame (e.g. a 20 ms Opus packet). Objects roll into a new group about once a second. subscribe_audio(ns, name, on_frame) delivers each object back as (ts_us, frame). Hold both handles for the life of the call. A dropped subscription frees the native callback. A dropped publication stops the track.
string
required
The per-call track namespace, voice/<sid>/uplink or voice/<sid>/downlink. <sid> is the call_sid.
string
required
The track name within the namespace — audio for voice legs.
string
default:""
A free-form routing intent (see Capability tags). Voice legs use voice/<codec>, e.g. voice/opus.
number
default:"48000"
The codec sample rate of the frames that you write. Opus stays 48000. Narrowband PCM/G.711 legs use 8000.
number
default:"1"
The channel count. Voice is mono.
number
default:"20"
The frame duration per object. 20 ms is the wire cadence for Opus and G.711.

Raw objects vs. decoded frames

The RTP media plane publishes the caller’s audio on uplink as raw 8 kHz PCM16 LE objects — the runtime’s internal audio format — with no SDK frame wrapper. To consume those bytes verbatim, use subscribe_raw. It gives you each MoQT object’s payload untouched:
Use subscribe_audio when the other side is an SDK publisher (frames carry a timestamp header). Use subscribe_raw for engine-published raw tracks. See the audio contract for the 8 kHz PCM16 / Opus / G.711 details.

Capability tags

A capability is an open-ended intent string attached to a track. The relay and the in-engine modules route on it: “route on intent, not on media kind.” Voice legs tag themselves voice/<codec>, where <codec> is one of the SDK’s audio codecs: So a browser caller publishes voice/opus. A passthrough leg off a µ-law trunk publishes voice/g711_ulaw. The capability is informational for the track itself. Subscribers select which namespace/name to receive. The tag tells the routing layer what the bytes are, so the routing layer can hand them to the module that registered for that intent (an ASR node, a recorder, a media.passthrough relay).
Two publishers can carry different capabilities on the same namespace. Set the tag to the actual codec that you write. A mislabeled leg goes to a decoder that cannot parse it.

Namespace authorization

There is no separate ACL call. Authorization rides the connect token:
1

Present your tenant token at connect

Pass your workspace API key as the token to connect. The SDK sends the key as a URL query parameter to relay.clutchcall.dev. The relay control plane verifies the key before the MoQT session opens.
2

The relay scopes you to your workspace's calls

A verified session can publish and subscribe to voice/<sid> namespaces for calls that belong to your workspace. <sid> values are unguessable per-call keys. The relay rejects a namespace outside your tenant scope. Cross-tenant subscription is not possible.
3

Namespaces are non-empty tuples

MoQT namespaces are tuples with at least one element. When you subscribe to a namespace that no publisher announced yet, the relay holds the subscribe. The relay delivers it when the publisher appears. For multi-participant rooms, the SDK scopes each participant under a [room, identity] tuple. A single call’s audio lives under the flat voice/<sid>/… namespace.
The token is a workspace-scoped credential. Mint short-lived tokens for browser clients. Do not ship a long-lived API key into a page. Treat voice/<sid> as sensitive: anyone with a valid token for your workspace and the sid can join the audio.

Transport & runtimes

Tracks ride MoQT over WebTransport on the single QUIC/HTTP-3 :443 plane. Browsers negotiate the moqt-16 WebTransport subprotocol. The relay handles connect and capped-backoff reconnect. The relay also re-establishes every publication and subscription for you. Two runtimes sit behind one API. The native SDK cores (Python, Go, Rust, and the C++ FFI, clutchcall_moqt_ffi) speak QUIC. They carry a QUIC → WebSocket fallback ladder for UDP-blocked networks. The TypeScript SDK is a standalone WebTransport implementation and is WebTransport-only today. There is no browser WS fallback yet. Hold the two as separate conformance surfaces. The publish/subscribe APIs match, but the queueing and unsubscribe lifecycle can differ.
For browser callers, you rarely call this primitive directly. The SDK’s WebRTC-diversion capture wraps publish_audio with encoded-Opus tapping. See Browser audio capture and WebTransport.

Realtime Tracks (MoQT)

The general publish/subscribe model that this page pins to voice.

Sessions, calls, tracks & streams

How call_sid keys the SIP dialog, the media session, and every track.

AudioBridge SDK

The high-level helper that wraps these tracks per call.

Handoffs

Subscribe to voice/<sid>/uplink to put a human on a live caller.