publishDownlink(frame).
Each call pushes a single encoded audio frame, typically a 20 ms Opus
packet, onto the voice/<sid>/downlink track. The engine paces the frame to
the caller’s leg. On a PSTN call, the engine transcodes to G.711 for you.
This is the send side of the
bring-your-own ASR/TTS pattern.
For the receive side, which feeds caller speech into your recognizer, see
Stream Audio to ASR.
Push TTS chunks as they arrive
Open the bridge withattach(). Then forward each synthesized chunk straight
to publishDownlink. attach() always subscribes uplink too. For this reason,
pass an onUplink callback even if you only care about playback here. A no-op
is fine, or wire it to your ASR.
- TypeScript
- Python
publishDownlink expects an encoded frame in the codec that you asked for
in attach(). With codec: "opus", push Opus packets. With codec: "pcm16",
push raw PCM16. Send one frame per call, one 20 ms tick at a time. Do not send
a whole utterance in a single buffer. This keeps playback smooth and lets
barge-in cut the audio off cleanly.Feed a model that emits raw PCM
Many realtime and TTS models give you 16-bit PCM rather than Opus. Ask forpcm16. The bridge then transcodes both directions. You push exactly what the
model gives you.
- TypeScript
- Python
Time playback yourself
When you omit the timestamp,publishDownlink stamps each frame with a
monotonic clock. This is fine for live streaming. If you replay buffered audio
or splice clips, pass a microsecond timestamp so that frames land in order.
- TypeScript
- Python
Related
Stream Audio to ASR
The uplink companion: feed caller speech to your recognizer.
BYO ASR / LLM / TTS
Run the full custom-brain loop end to end.
Hand off to a human
Escalate the live call and keep the same sid.
Python SDK
Full AudioBridge signatures for Python.

