<Speak>, <Play>,
<GetDigits>, <Dial>. Plivo executes those verbs against the call.
ClutchCall inverts that model. Your code runs as an external agent. The
external agent is a worker. The worker dials one outbound QUIC/WebTransport
session to the engine. It authenticates with a media app key/secret. It
registers under an agent handle. The engine routes calls to the worker through
a VENDOR_BRIDGE agent config. It hands each live call to your function.
Audio flows in both directions as 20 ms pcm16 frames at 8 kHz.
You do not need Flask, a public URL, or ngrok. You do not return XML for a
remote executor to interpret. Your process is the executor.
What maps to what
Port the voice quickstarts
The runnable starter is a port of Plivo’s Python voice quickstarts (greet_caller.py, receive_calls.py, forward_calls.py,
text_to_speech.py). It ships in the provider starters repo next to the
telequick-agents SDK.
1
Install the SDK
2
Replace the answer URL with a handler
Plivo’s greet-the-caller flow (answer,
<Speak> a greeting, hang up)
becomes one coroutine:greet_caller.py
send_transcript lands the turn in the platform transcript store. It
fires the voice.transcript.ready webhook. Plivo’s XML model never had
this piece.3
Create the external agent and route a DID
The console’s External agents create flow (
agent.clutchcall.dev)
does three tasks:- It reserves the agent handle.
- It mints the media key/secret.
AgentConfig.from_env()reads them fromTELEQUICK_MEDIA_KEY/TELEQUICK_MEDIA_SECRET. - It writes the
VENDOR_BRIDGEconfig.
4
Port the REST calls
Management operations use an The
mpk_ API key (console → Settings → API
keys) against POST /mcp. The SDK wraps it. Plivo’s
calls.create(..., answer_url=...) becomes originate with an agent.
On answer, the engine connects the callee to your worker:originate_call.py
forward_calls.py flow (<Dial>) is voice.calls.transfer with the
call’s sid. voice.calls.hangup ends a leg. For lifecycle events
(answer/hangup callbacks), register a signed webhook with
webhooks.create {vertical:'voice', url, eventTypes}. Check deliveries
with telequick_agents.webhooks.verify_signature.Troubleshooting
The greeting plays at the wrong speed
The greeting plays at the wrong speed
Your WAV is not 8 kHz mono 16-bit PCM.
send_audio is a raw passthrough
at the call’s sample rate. Resample the file offline. Do not send
44.1 kHz samples onto an 8 kHz leg.The call hangs up before the greeting finishes
The call hangs up before the greeting finishes
A return from the handler ends the call (Plivo’s implicit end-of-XML).
send_audio queues audio. Wait for playout, or for the caller, before
you return.The worker registers, but inbound calls never arrive
The worker registers, but inbound calls never arrive
vendor_room in the agent config must exactly match the handle that the
worker registered (TELEQUICK_AGENT). The DID must route to that agent.
Presence is tied to the live session. Check for a ready line after the
most recent reconnect.Related
LiveKit integration
The external-agent seam in depth: the same worker pattern with a full
agent framework on top.
Run a LiveKit Agent on the Transport
The end-to-end external-agent recipe: register a worker, route a number,
take a call.
SIP Trunking
Bring your numbers over, or point a Plivo SIP trunk at the platform.
Telnyx integration
The same port for Call Control’s command/webhook model.

