Skip to main content
The library reads who is calling, places outbound calls, and gives the model a tool that transfers the caller to a person. Your SIP trunk or carrier stays yours.

Take a call in

Read the caller’s number into the call’s state once the call starts.
state.call.calling_number is the caller, and state.call.called_number is your number. On Pipecat, set the pipeline’s sample rates to 8000, because a phone line carries 8 kHz audio.

Call someone

On LiveKit, dispatch the job with phone_number in its metadata. dial waits until someone answers, and hangs up on a voicemail. On Pipecat, your app asks the carrier to place a call that streams to the bot. With a Daily room, call dial_out(transport, worker, "sip:+34910000000@trunk.example").

Transfer to a person

Describe where the caller goes, then give the model a tool for it. The model calls the tool with no arguments, so it never sees the number.
agent.py
line is the call’s phone line. Build one per call:
  1. The tool says “Putting you through now, one moment.” The caller cannot cut the transfer off.
  2. On success, the call ends with the reason transferred.
  3. When nobody answers, the model hears why and keeps helping the caller. Pass on_unavailable="hangup" to end the call instead.
On LiveKit Cloud, Transfer(..., mode="warm") calls the person first and briefs them while the caller hears hold music.

Voicemail

hangup, the default, ends the call at once. leave_message has the model say a short message first.

What each route supports

For DTMF and IVR, use the framework’s own tools: GetDtmfTask on LiveKit, IVRNavigator on Pipecat.

Where to go next

Phone calls reference

Every argument, each route in detail, and warm transfers.

The call's life

Opening, greeting and ending the call.

Handoffs

Give the call to another agent instead of a person.

Phone calls on Unmute

The agent.yaml side of transfers and escalations.