The Go Voice SDK lives in package 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

The AudioBridge also uses the core package at 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.
The 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 by sid.

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.
See AI ↔ human handoff for the end-to-end warm-handoff flow.

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.
After the attach, the engine drives ASR/LLM/TTS (or a speech-to-speech provider) and owns both audio legs. You do not open an AudioBridge. Configure what the agent does in the runtime docs.

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.)
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.
AudioBridge.Attach (and everything it returns) is the cgo path. It requires CGO_ENABLED=1, a C toolchain at build time, and the SDK’s native audio shared library at run time. The rest of this page (Calls, Agents) is pure Go.
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 plain error. 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 in pkg/voice today. Use the core package or another language where noted:
  • No live call-lifecycle event stream in pkg/voice. OnUplink delivers audio, not signalling events. For a native call-event stream (originate, answer, transfer, cleared) use the lower-level core client in github.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.