:443 connection to
relay.telequick.dev — the same track substrate as every other leg of the call
(voice/<sid>/{uplink,downlink}). There is no media SFU and no gateway
round-trip on the audio path.
The transport ladder
The standing design is a ladder: QUIC/MoQT is first-class, with WebSocket (control/data) and WebRTC (media) as the fallbacks for networks where UDP is blocked or a browser lacks WebTransport. Be aware of where each rung actually ships today — the ladder is complete in the native SDK cores, but the browser/TypeScript SDK is WebTransport-only right now.| Rung | Carries | Browser / TS SDK | Native cores (Py/Go/Rust/Java/.NET) |
|---|---|---|---|
| WebTransport + MoQT (primary) | Encoded audio, all tracks | Shipped — the only media path | Shipped (QUIC, ALPN h3) |
| WebSocket fallback | MoQT muxed over WSS | Not yet — planned | Shipped — sticky auto-fallback rung |
| WebRTC media leg | Server-terminated SRTP audio | Not yet on this SDK path | Server-side termination exists |
On the browser today, if the QUIC/WebTransport path is unavailable the SDK does
not silently downgrade to WebSocket or WebRTC media — that rung is not yet
shipped for the TypeScript client. The QUIC→WebSocket fallback ladder currently
lives only in the native SDK cores. Plan browser deployments for a
WebTransport-capable, UDP-reachable network; see
Browser compatibility
for the gate and the current matrix.
WebTransport: the browser-native QUIC path
WebTransport gives the browser a real QUIC connection without you running any UDP plumbing. The SDK’sMoqtClient dials relay.telequick.dev, negotiates the
moqt-16 subprotocol, and returns immediately — it queues your publishes and
subscribes and replays them once the session is up, then auto-reconnects with
capped backoff if the link drops. Audio then flows as MoQT objects on the call’s
two tracks:
serverCertificateHashes, and the 127.0.0.1
local-dev gotcha live in WebTransport.
Reusing the browser’s audio pipeline (WebRTC diversion)
The trick that makes browser voice sound good is that you keep the browser’s audio pipeline but not its transport. A loopbackRTCPeerConnection runs the
browser’s capture graph — echo cancellation, gain control, noise suppression, the
Opus encoder, the jitter buffer — and an
RTCRtpScriptTransform
running in a Worker taps the encoded Opus frames and hands them to MoQT. The
WebRTC ICE/DTLS/SRTP transport is never used; only its codec and processing are.
Raw PCM never crosses the wire, and because the tap is at the encoded-frame layer
the relay only ever sees opaque payloads.
Capture and encode
captureMicrophone(publication) requests the mic with AEC/AGC/NS enabled,
wires the loopback peer connection, and installs the Worker transform on the
sender so the browser’s Opus encoder runs on your audio.Publish over QUIC/MoQT
The Worker reads each encoded frame off the transform’s readable stream and
writes it to
voice/<sid>/uplink as a MoQT object over WebTransport. The
relay fans it to whatever the engine bridged the call to — a SIP leg, an
agent, a recorder.Mobile apps
Native iOS/Android transport is planned, not shipped. There is no
Swift or Kotlin SDK today; the path is a portable QUIC/MoQT client compiled
through a shared C++ FFI (per-ABI
.so on Android, static .a on iOS, and a
.jslib shim for WebGL builds). If you are shipping to phones now, run the app
inside a WebTransport-capable mobile browser view, or reach the engine through a
server-side leg. Track status in
Mobile app transport.Where to go next
WebTransport
The browser-native QUIC path — connect, subprotocol, dev certs, and the
track model in detail.
One-line WebRTC diversion
Divert an existing WebRTC audio pipeline onto QUIC with a single call.
RTCRtpScriptTransform
How the encoded-Opus tap works in a Worker, and why it is the only path.
Browser audio capture
Capture, encode, and publish mic audio — options, codecs, and playback.
Browser compatibility
What works where, the hard-gate, and the current fallback story.
Mobile app transport
The planned native path for carrying voice from iOS and Android apps.