The Python Voice SDK gives your backend two surfaces against ClutchCall Voice. The control plane (voice.calls / voice.agents) originates, transfers, and hangs up calls, and binds server-side agents over the control-plane API. The data plane (voice.audio_bridge) streams call audio in and out over our QUIC/MoQT transport. Use it when the call driver lives on a server rather than in a browser — an outbound dialer, an agent supervisor, or a “tap the audio to my own ASR” pipeline.
The control plane is pure Python (standard-library HTTP, no native dependency). The data plane (voice.audio_bridge) uses our QUIC/MoQT transport through a shared native library. To publish or subscribe to audio, the MoQT FFI must be available at runtime (see Install). The SDK is synchronous and blocking. It does not use asyncio. Uplink frames arrive on a callback you register.

Install and authenticate

1

Install the package

2

Provide the audio transport library (data plane only)

Originating and controlling calls works with the package alone. To stream audio through voice.audio_bridge, point the SDK at the native MoQT transport library and export your API key:
Skip the library if you only originate calls and let a server-side agent handle the audio (agent=... on originate, or voice.agents.attach). The engine wires the bridge for you in that case.
3

Construct the client

Voice(...)

Top-level client. All constructor arguments are keyword-only.
str
required
Control-plane API base URL for your workspace, for example https://engine.clutchcall.dev.
str
required
Voice API key (sent as a bearer token). Keep it server-side.
str
required
Your workspace / organization id. It scopes every request.
str
default:"relay.clutchcall.dev"
MoQT relay host the audio bridge dials for the data plane. Override only for self-hosted / on-prem deployments.
The client exposes three helpers: Every surface raises VoiceError (importable from clutchcall.voice) on a bad argument or a non-2xx control-plane response.

Originate and control calls

v.calls.originate(...)

Places an outbound call against a trunk and returns a Call. Arguments are keyword-only.
str
required
Destination in E.164, e.g. "+15551234567".
str
required
Caller-ID in E.164. (The name is from_ because from is a Python keyword. The SDK sends it as from on the wire.)
str
required
The SIP trunk to originate on. See SIP trunking.
str | None
default:"None"
If set, the engine binds this server-side agent and wires the audio bridge end-to-end. You do not need to open an AudioBridge yourself.
int
default:"30"
The number of seconds to ring before the attempt stops.

The Call object

originate and get return a Call. Its sid is the universal key. The same call_sid names the SIP dialog, the media session, the agent session, the MoQT namespace, and the CDR.
str
Call identifier (call_sid).
str
One of dialing, ringing, in_progress, completed, failed, no_answer.
str
Destination E.164.
str
Caller-ID E.164.
str | None
Originating trunk.
str | None
Bound agent, if any.
Methods:
transfer requires exactly one of to=<E.164> or agent=<id>. If you pass both, or neither, the SDK raises VoiceError. AI ↔ human handoff covers peer-initiated transfer over SIP REFER.

v.agents.attach(call_sid, agent)

Bind a running server-side agent to an existing call. The engine wires the audio bridge for you. Use this when the call already exists (for example, an inbound call) and you want the agent runtime to take the audio.

Bridge call audio

voice.audio_bridge.attach(...) opens a bidirectional audio bridge for one call. It subscribes to the caller’s uplink (voice/<sid>/uplink) and delivers each frame to your on_uplink callback. It also publishes your downlink (voice/<sid>/downlink) back toward the caller through bridge.publish_downlink(...). This is the server / agent side of the bridge: you receive caller audio and send audio to the caller.
str
required
The call.sid to bridge.
The SDK calls this for every caller frame with (frame_bytes, timestamp_us). It runs on the transport’s delivery thread. Keep it fast and hand off heavy work.
"opus" | "pcm16" | "g711_ulaw" | "g711_alaw"
default:"\"opus\""
Wire codec for the downlink you publish. See Codecs.
int
default:"48000"
Sample rate of the audio you publish (48 kHz for Opus).
int
default:"1"
Channel count (mono).
int
default:"20"
Frame duration in ms.
AudioBridge.publish_downlink(frame, *, timestamp_us=None) sends one frame toward the caller. If you omit timestamp_us, the SDK stamps it from a monotonic clock. Hold the AudioBridge reference for the call’s lifetime. If the garbage collector collects it, the session closes.
The Python data plane today ships the server/agent-side attach only (subscribe uplink, publish downlink). The caller-side helpers exposed by the TypeScript SDK — attachCaller, publishUplink, onDownlink — are not yet part of the Python surface. If you need to originate audio as the caller from Python (for example, a synthetic caller), use the TypeScript SDK for now.

Codecs and audio format

codec accepts "opus" | "pcm16" | "g711_ulaw" | "g711_alaw". Voice is audio-only. There are no video codecs. Phone legs are G.711 (µ-law / A-law) on the wire. Browser and app legs are Opus (48 kHz mono, 20 ms frames). The engine transcodes to and from its internal PCM representation, so you publish and receive in the codec you pass to attach. For the full track / namespace model see Sessions, calls, tracks & streams.

Full example: originate, attach, tap

Originate a call, let a server-side agent run the ASR/LLM/TTS loop, and tap the uplink in parallel to write a transcript-friendly frame log.
This mirrors the voice_agent_attach.py example shipped with the SDK. Because the SDK is blocking, run long-lived taps under a thread or process you control. Drive shutdown from a signal, as above.

TypeScript SDK

The primary SDK, including the caller-side audio surface.

Agent control events

The human-agent control channel and its event model.

Calls API

The control-plane call routes the SDK wraps.

Outbound call cookbook

An end-to-end outbound walkthrough.

Stream to your ASR

Tap the uplink into your own speech pipeline.

Agent runtime

What a bound server-side agent does with the audio.