github.com/clutchcall/clutchcall-sdk/go/pkg/voice. It gives you the
same two primitives as every other language binding: Calls (the control
plane) and AudioBridge (the data plane). It adds Agents to bind a
server-side AI agent to a live call. Every operation keys off one identifier,
a call’s Sid.
The two planes have very different runtime requirements in Go. Know this
before you start:
Calls and Agents are pure Go. They use the control-plane API over plain
net/http, so they build and run anywhere Go does, with no C toolchain.AudioBridge is a cgo binding. It moves encoded audio over MoQT through the
SDK’s native transport. To build code that touches AudioBridge, you need
CGO_ENABLED=1, a C toolchain, and the SDK’s native audio shared library on
your linker/loader path. If you only place and manage calls, or attach an AI
agent and let the engine own the media, you never touch the data plane. In
that case you can build a pure-Go binary.Install
github.com/clutchcall/clutchcall-sdk/go/pkg (the
native MoQT client). You rarely import it directly.
Construct the client
voice.New returns a *Voice scoped to one org. All three arguments are
required. The function returns an error if any argument is empty. Construct
the client once and reuse it. It is safe to share across goroutines.
string
required
Control-plane API host, for example
https://engine.clutchcall.dev. The SDK trims a
trailing slash.string
required
Your API key. The SDK sends it as
Authorization: Bearer <key> on every
control-plane request.string
required
The org (workspace) id that scopes every operation.
Voice struct exposes a few fields you can set after construction:
string
default:"relay.clutchcall.dev"
Host for the AudioBridge MoQT session. Point it at your workspace relay.
*http.Client
default:"http.DefaultClient"
Override to set timeouts, a proxy, or custom transport for control-plane calls.
Calls — the control plane
v.Calls() returns a *Calls. Every method maps to one control-plane RPC and
returns a typed result or an error.
Originate
Originate dials To from From over the trunk you name. If you pass
Agent, the engine attaches that server-side voice agent automatically when
the far end answers. You do not open an AudioBridge yourself.
string
required
Destination in E.164, e.g.
+15551234567.string
required
Caller-ID presented on the outbound leg, in E.164. It must be a number your
trunk is allowed to present.
string
required
The trunk to originate on. See
SIP trunking.
string
Optional agent id. When set, the engine binds this server-side voice agent on
answer and wires the audio bridge end-to-end.
int
default:"30"
The number of seconds to ring before the attempt stops. If you leave the zero
value, the SDK sends
30.Originate returns a *Call, which embeds CallData:
string
The universal call key.
string
Lifecycle state, e.g.
dialing, in_progress, completed.string
Destination number.
string
Caller-ID.
string
Start timestamp.
string
Trunk the call was placed on (omitted when empty).
string
Bound agent id, if any (omitted when empty).
Get
Fetch the current state of a call bysid.
Transfer
Call.Transfer moves a live call. Pass exactly one of To (hand off to a
PSTN number) or Agent (re-attach to a different server-side agent). If you
pass both, or neither, the SDK returns an error before it sends any RPC.
Hangup
Agents — attach an AI agent
v.Agents().Attach binds a server-side voice agent to a call that is already
up. Use it when you originated a bare call (no Agent) and now want the engine
to take over the conversation. Also use it to attach an agent to an inbound
call your backend just learned about.
AudioBridge — the data plane
Use the AudioBridge only when you want the raw encoded frames of a call in your Go process — for example, to feed a custom media pipeline or a runtime the engine does not natively host. When an agent is attached, you do not need it.v.AudioBridge().Attach subscribes to the caller’s audio at the
voice/<sid>/uplink track and opens a publisher on voice/<sid>/downlink for
audio you send back. (See
sessions, calls, tracks & streams
for the track model.)
func(frame []byte, timestampUs uint64)
required
The SDK calls this for every inbound frame from the caller.
frame is the
encoded payload. timestampUs is the frame’s microsecond timestamp. This
callback is required — Attach returns an error without it.voice.Codec
default:"CodecOpus"
One of
CodecOpus, CodecPCM16, CodecG711ULaw, CodecG711ALaw. Voice is
audio-only. There is no video codec here.uint32
default:"48000"
Sample rate of the downlink track.
uint8
default:"1"
Channel count (voice is mono).
uint16
default:"20"
Frame duration in milliseconds.
PublishDownlink stamps each frame with the current time. You give it only
the encoded bytes. Always Close() the bridge when you are done. Close()
tears down the publisher, the subscription, and the underlying MoQT session.
Errors
Control-plane methods return a plainerror. SDK-side validation failures (a
missing field, an invalid Transfer combination) come back as *voice.Error.
Transport and remote failures show the HTTP status or the control-plane error
message. Handle them the usual Go way:
What the Go surface does not include yet
The Go binding is deliberately the core of two primitives plus agents. Some features from other bindings are not inpkg/voice today. Use the core
package or another language where noted:
- No live call-lifecycle event stream in
pkg/voice.OnUplinkdelivers audio, not signalling events. For a native call-event stream (originate, answer, transfer, cleared) use the lower-level core client ingithub.com/clutchcall/clutchcall-sdk/go/pkg, which exposes an event callback over the native QUIC RPC plane. See the SDK events reference. - No human-agent softphone control channel. The browser/desktop agent control channel (login, presence, call-offer accept/reject) currently ships in the JavaScript SDK only.
- No video. Voice tracks are audio-only.
Next steps
Calls API
The full control-plane contract behind
Calls — originate, get, transfer, hangup.Audio bridge
The MoQT track model and frame semantics the AudioBridge rides on.
Attach an agent
Bind a server-side AI agent and let the engine own the media.
Outbound calling
Originate, campaigns, and the paced dialer end to end.

