github.com/telequick/telequick-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) — plus Agents to bind a
server-side AI agent to a live call. Everything keys off one identifier, a
call’s Sid.
The two planes have very different runtime requirements in Go, and it is worth
knowing this up front:
Calls and Agents are pure Go — they speak 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, so building code that touches AudioBridge needs
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 and can
build a pure-Go binary.Install
github.com/telequick/telequick-sdk/go/pkg (the
native MoQT client) under the hood; you rarely import it directly.
Construct the client
voice.New returns a *Voice scoped to one org. All three arguments are
required — it returns an error if any is empty. Construct it once and reuse it;
it is safe to share across goroutines.
Control-plane API host, e.g.
https://engine.telequick.dev. A trailing slash is
trimmed for you.Your API key. It is sent as
Authorization: Bearer <key> on every
control-plane request.The org (workspace) id every operation is scoped to.
Voice struct exposes a few fields you can set after construction:
Host for the AudioBridge MoQT session. Point it at your workspace relay.
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. Pass Agent and the
engine attaches that server-side voice agent automatically when the far end
answers — you don’t open an AudioBridge yourself.
Destination in E.164, e.g.
+15551234567.Caller-ID presented on the outbound leg, in E.164. Must be a number your trunk
is allowed to present.
The trunk to originate on. See
SIP trunking.
Optional agent id. When set, the engine binds this server-side voice agent on
answer and wires the audio bridge end-to-end.
Seconds to ring before giving up. Left at the zero value, the SDK sends
30.Originate returns a *Call, which embeds CallData:
The universal call key.
Lifecycle state, e.g.
dialing, in_progress, completed.Destination number.
Caller-ID.
Start timestamp.
Trunk the call was placed on (omitted when empty).
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) — passing
both, or neither, returns an error before any RPC is sent.
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, or to attach an agent to an inbound call your backend
just learned about.
AudioBridge — the data plane
Reach for the AudioBridge only when you want the raw encoded frames of a call in your Go process — for example to feed a bespoke media pipeline or a runtime the engine doesn’t natively host. When an agent is attached, you don’t 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.)
Called for every inbound frame from the caller.
frame is the encoded payload;
timestampUs is the frame’s microsecond timestamp. Required — Attach errors
without it.One of
CodecOpus, CodecPCM16, CodecG711ULaw, CodecG711ALaw. Voice is
audio-only — there is no video codec here.Sample rate of the downlink track.
Channel count (voice is mono).
Frame duration in milliseconds.
PublishDownlink stamps each frame with the current time for you — you hand it
just the encoded bytes. Always Close() the bridge when you’re done; it 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 surface 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 two-primitives-plus-agents core. A few things present in other bindings are not inpkg/voice today — reach for 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/telequick/telequick-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.