This section documents the legacy voice-RPC wire format. It’s kept for
reference and backwards compatibility — new code should use the
modality clients over MoQT instead. The Voice
modality (
clutchcall.voice, @@clutchcall/sdk/voice, etc.) replaces
every method_id RPC documented here with a typed surface that runs over
the same MoQT relay mesh as streams, robotics, games, and data.See Architecture for how the legacy envelope and
MoQT coexist today.ClutchCallClient.dial, hangup,
barge, push_audio, …) wraps it; nothing is hidden. If you have a QUIC
client and a serializer for little-endian primitives, you can talk to the
gateway directly.
Read these in order
Envelope Format
Byte layout of a single RPC frame on the wire — length prefix, method id,
serde envelope body, field encoding. → Envelope Format
Method IDs
The full table of
method_id constants and their request/response DTOs.
→ Method IDsTypes
Field-level breakdown of every DTO (
OriginateRequest, CallEvent, etc).
→ TypesAudio Frames
How outbound and inbound
AudioFrame envelopes are framed on uni-streams.
→ Audio FramesEvents
Server-pushed
CallEvent semantics, ordering, and reconnect behaviour.
→ EventsEndpoint
Stream model
Connection setup uses one bidirectional stream for the initial JWT handshake (the SDK does this for you). After that:| Stream type | Direction | Carries |
|---|---|---|
| Bidirectional | client → server | A single RPC envelope; close-on-write |
| Unidirectional | client → server | AudioFrame stream (mic → trunk) |
| Unidirectional | server → client | CallEvent and AudioFrame (trunk → app) |
Versioning
Each serde envelope carries a 1-byteversion and a 1-byte compat_version.
The gateway accepts envelopes whose compat_version ≤ server_current_version.
Adding fields is backwards-compatible; removing or reordering them is not —
do that with a new method id, not a version bump.
