call_sid.
This page documents how the SDK authenticates and brings up that session. This
is the plumbing under
AudioBridge.attach. You rarely wire it by
hand, but you need the shapes to reason about auth, tenancy, and reconnection.
There is no public REST API for sessions. The control plane is a set of
tRPC-style procedures on the control-plane host. The SDK calls these procedures
for you. You authenticate with an API key. The SDK does the procedure calls
and the relay handshake. The shapes below are the real shapes that the SDK
sends. Treat them as the contract, not as endpoints to hand-roll.
Two planes, one credential
A session touches two planes. The same workspace API key authorizes both:
The control plane is a request/response surface (queries and mutations). The
data plane is a long-lived session that auto-reconnects. To get onto the data
plane, first ask the control plane where the relay lives. The control plane
also proves that you can attach.
Establish a session
1
Authenticate the control plane
Construct the client with your workspace API key and org id. The SDK sends
the key as
Authorization: Bearer <apiKey> on every control-plane call.
The org id scopes every procedure to your tenant.2
Resolve the relay edge
Before the SDK opens a session, it asks the control plane which relay edge
to dial. This is a query. The SDK sends it, but the shape is worth
knowing. The query geo-routes you to the nearest edge. It also carries the
fields that the WebTransport handshake needs.Response:
string
required
Your tenant id. It scopes the response to your workspace.
string
Pin a specific relay edge (e.g.
"us", "uk"). Omit this field to let
the server geo-route to the nearest edge.boolean
false when the tenant has no QUIC/relay entitlement. The rest of the
fields are then absent. Fall back to a control-plane-only integration.string
The MoQT relay endpoint to open the session against. The server already
selected the region.
string
The edge that the server chose. The response echoes it for telemetry and
for a pin on reconnect.
string | null
A base64 SHA-256 certificate fingerprint for self-signed dev relays.
This is
null in production. In production, the relay presents a
public-CA certificate, and no fingerprint pin is necessary.On managed cloud, the relay runs on a public-CA certificate, so
relayCertHashBase64 is null. You pass a cert hash only when you point
the SDK at a self-signed relay in local development.3
Open the relay session
With the relay URL and a token, the SDK opens the MoQT session. Under the
hood this is The session address is the
MoqtClient.connect(url, token, onState, opts). The SDK
appends the token to the URL as a ?token= query. The relay’s control
plane verifies the token. The WebTransport handshake advertises the
moqt-16 subprotocol. The relay closes the session if the version
subprotocol is missing.call_sid. The SDK connects to
moq://<relayHost>/voice/<call_sid> and binds the uplink / downlink
tracks under that namespace. One call_sid is the whole addressing story.
The SIP dialog, the media session, the agent session, the telemetry, and
this transport session all key off it (see
Sessions, calls, tracks & streams).4
Observe session state
The session reconnects transparently with capped backoff. The SDK
re-establishes publications and subscriptions on every reconnect. Subscribe
to the state machine to drive UI and to know when audio actually flows.
The first connect is in progress.
The session is up; the tracks are live.
The transport dropped. The SDK retries with capped exponential backoff.
On success, the SDK replays your pubs/subs.
You (or the peer) ended the session cleanly.
The initial connect failed. The state carries a reason string.
Namespace auth (room scope)
The relay does not give a token holder the whole tenant. Authorization is namespace-scoped: a session can publish and subscribe only within the room-shaped namespace tuple that the relay authorized it for. For voice, that room isvoice/<call_sid>. The two tracks inside it are fixed by role:
The distinct uplink and downlink tracks prevent a leg from hearing itself. An
attach subscribes to uplink and publishes downlink. attachCaller (the
browser-caller mirror) does the reverse.
Connect options
These are the knobs that the SDK passes to the relay session.attach sets the
media-relevant knobs for you. These knobs are the honest surface if you drop to
the transport client directly.
string
The relay token. The relay control plane verifies it. The SDK sends it as a
?token= query on the WebTransport URL. The Voice SDK forwards your
workspace API key here.string
A base64 SHA-256 certificate fingerprint for a self-signed dev relay.
Leave this unset in production (
relayCertHashBase64 from
gatewayConnectInfo is null there).(state, reason?) => void
A callback for the
ConnectionState machine above.boolean
Refuse to connect unless the browser exposes the standard WebRTC Encoded
Transform API (
RTCRtpScriptTransform). Media-sending browser sessions set
this flag, so the encoded-frame rule holds up front instead of failing later
at capture time. Leave the flag unset for receive-only or non-media sessions.
See
browser audio capture.Fallback honesty. In the browser / TypeScript SDK, a session is
WebTransport-only today. If WebTransport is unavailable, the SDK does not
silently degrade. The QUIC→WebSocket fallback ladder currently ships only in
the native SDK core (Python, Go, Rust, Java, .NET wrappers). The native core
stays on a WebSocket rung when QUIC is blocked.
Sessions vs. calls
Keep the two concepts clearly apart:- A call is the SIP dialog and its lifecycle — originate, ring, answer,
transfer, hangup. You drive a call with the
Calls API (
voice.calls.*), which returnsCallDatakeyed bysid. - A session is the transport connection that carries that call’s audio. The
same
sidaddresses it. You open a session with the Transport / AudioBridge API.
- Originate a call (control plane).
- Take the returned
sid. - Attach a session (data plane) to move audio.
voice.agents.attach tells the engine to connect the bridge
in-process, and no client session opens. See the
runtime session lifecycle for
the engine’s view of that flow.
Related
Transport / AudioBridge
Open and drive the audio session for a call.
Calls
Originate, transfer, and hang up — the call control plane.
Sessions, calls, tracks & streams
The object model: how
call_sid, namespaces, and tracks relate.Errors
The error shapes that the control plane and the session return.

