Warm Transfer Implementation

Hey team, has anyone been able to implement warm transfer robustly on self hosted livekit? Per Support for MoveParticipant in self-hosted LiveKit the native documented way isn’t supported for self-hosted Livekit

What is your use case? Native warm transfer isn’t supported in self-hosted, but there could be workarounds based on your use case.

Just want to warm mimic warm transfer experience for customers over the phone. Is there a standard way to do that with self hosted Livekit

There is no standard way, but you could build it. For e.g. you could have the person join the same room as the Agent and the Caller.

Alright just making sure

How would one set up a multi home mesh? Feature Request: Move and Forward Participant APIs on self hosted deployments · Issue #4203 · livekit/livekit · GitHub

My use case involves summarizing the call to the supervisor before merging the calls, as per warm transfer flow.
However I am unable to figure out how to not have the caller listen to the tracks between the agent and supervisor without having to keep them in separate rooms OR if there is a way to merge the participants into one room afterwards?

Its non trivial, but I believe integration points are present in livekit code.

Potentialy Agent joins a different room with the Supervisor, while on the call with the user? Also you can have track level permissions so only the specific user can subscribe to that track.

The behavior we’re looking for is a separate agent talks with the transfer destination to see whether or not they are available, and if user says yes, complete the transfer, otherwise (not available or voicemail) failover to original agent with a fallback message like “looks like they were unavailable, I can help you take a message” etc

You could do that with a single room, ensuring the tracks are appropriately muted. Dial the supervisor, and ensure its track subscription is only to the approprate agent. You could also try a separate room or and agent dispatch. Definitely trickier but doable.

I just dont understand why Livekit doesnt have a native implementation for this on self hosted lol…

Because the implementation they have requires the multi-homing mesh design, which isn’t available on the self hosted version.


I solved it using a single room, an additional controller, and an MOH bot—approximately 1,300 lines of code. It works very well.

I fixed this by using muting; everything happens in one LiveKit room, because the self-hosted livekit-server doesn’t implement the MoveParticipant RPC that the SDK’s Cloud-only WarmTransferTask relies on.

Flow:

  1. Hold the caller — the caller isn’t moved anywhere; they’re put “on hold” via mute/unsubscribe (audio between caller and the rest of the room is cut, so they hear nothing of the consultation).
  2. Dial the target — the transfer target (e.g. supervisor) is dialed as a new SIP participant into the same room.
  3. Private consultation — the agent talks to the target while the caller stays isolated via the subscription/mute state.
  4. Complete or cancel:
    • Complete: re-subscribe/unmute so caller and target are connected to each other, and the agent bows out.
    • Cancel (target declines / no answer): drop the target’s SIP leg, restore the caller’s audio, and the agent resumes the call.

So instead of moving people between rooms (Cloud’s approach), it simulates the same UX by toggling who can hear whom inside a single room.

This is all in the dashboard LiveKit Dashboard - Self-Hosted Voice AI Admin Panel | Tronic

Multi-Cluster nodes still wouldn’t work for this I dont think.

https://youtu.be/AW2jJ_L93tM?si=m0Q9CiWMsRyRJWCr