You have a Pipecat bot: a pipeline of frame processors wired to ASR, an LLM, and TTS. You want it to answer real phone calls and browser sessions over ClutchCall’s transport. You do not want to operate a media server or negotiate ICE/DTLS/SRTP. This recipe assembles that end to end. You build a small host process. The process takes a live call, subscribes to the caller’s audio, runs the audio through a Pipecat pipeline, and streams the agent’s replies back. All of this runs over QUIC/MoQT on the single :443 plane.
A packaged Pipecat adapter now ships: pipecat-telequick. It is a drop-in TeleQuickTransport over the external-agent QUIC plane, with one pipeline per routed call. Start from Pipecat + ClutchCall Transport unless you specifically want this recipe’s lower-level path. That path is the audio bridge: caller audio in, agent audio out, over raw MoQT. On that path, you own the thin glue that hands frames to Pipecat. The QuicMoqtTransport wrapper near the end remains an illustrative sketch of that hand-rolled shape, not the shipped package.

What you’re building

Pipecat and ClutchCall sit at different layers. That is why they compose cleanly. Pipecat owns the conversation: the frame pipeline, turn-taking, and your model choices. ClutchCall owns the transport and telephony: the SIP gateway/B2BUA that terminates the carrier trunk, and the media plane that carries the audio over QUIC. The seam between them is a pair of tracks keyed by the call id: an uplink (caller → bot) and a downlink (bot → caller):
The two AudioBridge calls are stock SDK. Everything between them is your Pipecat pipeline. The pipeline is unchanged from any other Pipecat deployment.

Build the app

1

Take the call and attach the audio bridge

Skip agents.attach (that call runs our managed runtime). Open the bridge yourself. Ask for pcm16 at 16 kHz. That is the shape most frame pipelines expect. The bridge transcodes the PSTN (G.711) leg and the runtime’s 8 kHz bus for you in both directions.
2

Wrap the two hooks as a Pipecat transport

Pipecat’s Transport seam needs exactly two things: a producer of input audio frames and a consumer of output audio frames. The bridge already gives you both. onUplink is the producer. publishDownlink is the consumer. Wrap them so that the rest of the pipeline runs unchanged.
Illustrative — you own this class today. The transport below is your glue code around the real audio bridge, not an installable package. Class and frame names track Pipecat’s public shape. When you write this class for real, pin your Pipecat version and match its exact transport base classes.
3

Assemble the pipeline

Drop the two wrappers on the ends of an ordinary Pipecat pipeline. The STT, LLM, and TTS processors are stock Pipecat. Pick the providers that you already use.
4

Run the call, then tear down cleanly

Run the pipeline for the life of the call. When the conversation ends, close the bridge before you hang up. Both tracks then tear down cleanly.
Keep the bridge reference alive for the whole call. If the garbage collector removes it mid-call, both tracks drop and the audio goes silent.

Where this is headed

A first-class integration would collapse the two wrapper classes above into a single Pipecat Transport. That transport would bind directly to our media-over-QUIC primitives. You would construct it with the call id. You would drop transport.input() / transport.output() onto the pipeline. You would write no onUplink/publishDownlink glue.
Design sketch — not shipped. QuicMoqtTransport does not exist as a package. It shows the intended shape of a future adapter only.
The only real work that such an adapter adds is the seam that our own runtime already handles. The adapter must do three things:
  • resample between Pipecat’s frame rate and the runtime’s 8 kHz PCM16 audio bus,
  • keep the room-scoped MoQT namespaces valid, and
  • carry Opus rather than PCM on browser legs.
None of this is exotic. It is not packaged yet, so today you own the wrapper.

Other on-ramps that ship today

If you do not want to write even the wrapper, two seams already let a Pipecat bot take live calls:
Pipecat already speaks WebSocket audio. ClutchCall accepts a bespoke WebSocket audio sender as a media leg. Point Pipecat’s WebSocket server transport at that on-ramp. Route the trunk’s inbound rule to your endpoint. The SIP gateway terminates the carrier while Pipecat drives the conversation, with no ClutchCall code in the bot. This is the same path as migrating a custom WebSocket audio sender.
You can want Pipecat only for the pipeline: cascaded ASR → LLM → TTS, turn-taking, tools. ClutchCall’s runtime already ships that pipeline as a configured DAG with transport, telephony, and barge-in built in. You can bring only your models via provider credentials. That is often less work than a port of a Pipecat pipeline onto an adapter that does not exist yet.

Pipecat + Transport

The full conceptual framing and the on-ramps that ship today.

Bridge a Pipecat Agent

The single-snippet version of the audio-bridge seam that this recipe uses.

LiveKit Agent with ClutchCall Transport

The sibling recipe for a LiveKit agent over the same transport.

Keep Your Existing Runtime

Adopt only the transport and keep your own agent loop.