How can I transfer a caller to a specifixlc room t...
# ask-ai
a
How can I transfer a caller to a specifixlc room that already has an agent and another user?
t
Thanks for reaching out, Sanjeev. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Can you clarify how the caller is currently connected? For example, are they connected via a SIP call, a WebRTC session, or another method? Additionally, are you using any specific APIs or SDKs to manage the rooms and participants?
a
They are connected via sip call to Room B . I wan to transfer them to a specific room that was already created dynamically
t
If you want to transfer a SIP participant from one room to another dynamically created room in LiveKit, you can easily do this using the
transferSipParticipant
method. Here’s a friendly step-by-step on how to make it happen: 1. Use the
transferSipParticipant
Method:
This handy method lets you move a SIP participant to a different room. You’ll just need to provide: ◦ `roomName`: The name of the room where the participant is right now. ◦ `participantIdentity`: The identity of the participant you want to transfer. ◦ `transferTo`: The SIP URL or phone number where you want to send the participant. For a dynamic room, this should be the SIP endpoint of that room. 1. Example Usage:
await sipClient.transferSipParticipant('current-room', participant.identity, '<sip:dynamic-room@livekit.io>');
2. Make Sure the Destination Room Exists: Double-check that the dynamic room is already created or can be created by your app. The
transferTo
parameter needs to point to a valid SIP endpoint for that dynamic room. 3. Permissions: Don’t forget, you’ll need the right room admin permissions to pull off this transfer smoothly. 4. Optional: Want to add a little polish? You can play a dial tone during the transfer by turning on the
playDialtone
option. For even more details, feel free to check out the LiveKit SIP documentation. I’m here if you have any more questions! Sources: packages/livekit-server-sdk/src/SipClient.ts | cmd/lk/sip.go | Transferring calls | LiveKit Docs | SIP APIs | LiveKit Docs
a
Does every livekit room have a sip end point?
t
Just a heads-up: not every LiveKit room comes with a SIP endpoint by default. SIP integration is a handy optional feature that lets people join LiveKit rooms through phone calls, but it does need a bit of setup. Here’s what you’ll want to do to get SIP working for your LiveKit rooms: 1. Configure SIP trunks: Grab a phone number and set up a SIP trunking provider. Then, create an inbound trunk and a dispatch rule to handle incoming calls. 2. Set up dispatch rules: These are what route calls to the right rooms. Without them, SIP participants won’t be able to connect. 3. Use your project’s SIP endpoint: Every project has its own SIP URI (like
sip:vjnxecm0tjk.sip.livekit.cloud
), which works at the project level, not for individual rooms. If you want a hand with setting up SIP integration or figuring out dispatch rules, just give me a shout—I’m here to help! Sources: SIP Integration | livekit/livekit_composite | DeepWiki | SIP inbound trunk | LiveKit Docs | LiveKit Server Components | livekit/livekit_composite | DeepWiki | SIP trunk setup | LiveKit Docs | SIP overview | LiveKit Docs
a
It in above response you asked me to set the sup parameter to room-name@livekit.io . Can you transfer calls to a specific room ?
t
Hey there! Just a quick note — the docs don’t explicitly say you can transfer SIP calls to a room using the format
<mailto:room-name@livekit.io|room-name@livekit.io>
. But good news: the
TransferSIPParticipant
API does let you transfer SIP participants to valid SIP URIs or phone numbers. So, if you’re aiming to transfer a call to a specific room, you’ll want to make sure the destination is a valid SIP endpoint. One way to do this is by setting up dispatch rules that can dynamically route calls to the rooms you want. Another option is using the
transfer_to
parameter to point to a valid SIP URI that matches your target room. If you’d like a hand setting up those dispatch rules or want to chat about other ways to make this work, just give me a shout—I’m here to help! Sources: SIP overview | LiveKit Docs | packages/livekit-server-sdk/src/SipClient.ts | livekit/livekit_sip.pb.go | test/integration/sip_test.go
a
Yes what is a valid SIP parameter for a room that I can transfer
t
If you want to transfer a SIP participant to a specific room in LiveKit, you’ll just need to use the
TransferSIPParticipant
API and provide a valid SIP URI as the
transfer_to
parameter. Here are some examples of valid SIP URI formats to give you an idea: •
tel:+15105550100
(telephone number) •
<sip:+15105550100@sip.telnyx>.com
(SIP URI) •
<sip:+15105550100@my-livekit-demo.pstn>.twilio.com
(SIP URI) Here’s a quick example of how you might transfer a participant:
Copy code
await sipClient.transferSipParticipant('current-room', participant.identity, '<sip:+15105550100@sip.telnyx>.com');
If you’d like a hand setting up a SIP URI for a specific room or have any questions, just let me know—I’m here to help! Sources: Transferring calls | LiveKit Docs
a
yes - I want help in setting up SIP URI's for a specific room
t
Setting up SIP URIs for specific rooms in LiveKit is pretty straightforward! Just follow these steps: 1. Create an Inbound SIP Trunk: This is where you tell LiveKit how to accept incoming calls. Start by creating a JSON file with your trunk details, like this: `{ "trunk": { "name": "My Inbound SIP Trunk", "numbers": ["+15105550100"] } }`Then, run this CLI command:
lk sip inbound create inbound-trunk.json
2. Create a Dispatch Rule: This helps route calls to the right rooms. You’ve got a couple of options here: Then just use this CLI command:
lk sip dispatch create dispatch-rule.json
Direct Room Assignment:
Copy code
{
  "dispatch_rule": {
    "rule": {
      "dispatchRuleDirect": {
        "roomName": "specific-room"
      }
    }
  }
}
Dynamic Room Creation with Prefix:
Copy code
{
  "dispatch_rule": {
    "rule": {
      "dispatchRuleIndividual": {
        "roomPrefix": "meeting-"
      }
    }
  }
}
1. Optional: You can add a PIN for extra room security or link agents to handle incoming calls if that fits your setup. If you want to dive deeper, check out the LiveKit SIP documentation. And hey, if you have any questions or need a hand, just let me know—I’m here to help!
a
My trunk has
dispatchRuleIndividual
. I want each caller to have their own room. So should I update the trunk when every single call comes in to add the phone number?
t
Hey there! Good news—you don’t need to update the SIP trunk for every single call when you’re using
dispatchRuleIndividual
. This handy rule takes care of creating a new room for each caller based on their phone number, plus it adds an optional prefix and a random suffix to keep things unique. For example, if your dispatch rule looks like this:
Copy code
{
  "rule": {
    "dispatchRuleIndividual": {
      "roomPrefix": "call-"
    }
  },
  "name": "My dispatch rule"
}
When a call comes in from
+15551234567
, LiveKit will automatically spin up a room named something like
call-+15551234567-abc123
(that random suffix keeps things fresh!). It pulls the phone number right from the SIP call headers, so you don’t have to worry about manually updating the trunk. If you’d like a hand setting this up or have any questions, just let me know—I’m here to help! Sources: SIP dispatch rule | LiveKit Docs | sip/sip_test.go
a
ok. Now I want transfer another caller using the transfer_sip_participant where the transfer_to is sipcall-+15551234567-abc123@agentperformancedev-362y4m63.livekit.cloud. Is this correct?
t
Hey there! It looks like the format you shared,
<sip:call-+15551234567-abc123@agentperformancedev-362y4m63.liveki>t.cloud
, isn’t quite matching the standard SIP URI format that LiveKit expects for the
transfer_to
parameter. No worries though! Here’s a quick rundown of the correct format: • Standard SIP URI:
sip:user@host
, where
host
is the SIP server domain or IP address. • Telephone Numbers: Use the
tel:
scheme with the E.164 format, like
tel:+15551234567
. Here are some examples that should work well: •
tel:+15551234567
<sip:+15551234567@sip.exampl>e.com
<sip:user@sip.liveki>t.cloud
If you’re trying to transfer to an internal LiveKit SIP participant, just double-check that you’re using the right SIP URI format along with the correct authentication and trunk setup. And of course, if you want me to walk you through it or have any other questions, I’m here to help! Sources: Transferring calls | LiveKit Docs
a
here is teh actual Sip address i tried to transfer - sbx-j4ktb7-Z58cQnzH3kaGKjynXTQ7sh@agentperformancedev-362y4m63.livekit.cloud
t
Hey there! The SIP address you shared,
sbx-j4ktb7-Z58cQnzH3kaGKjynXTQ7sh@agentperformancedev-362y4m63.livekit.cloud
, can definitely be used with the
transfer_sip_participant
function. Just a quick tip: it needs to be formatted as a proper SIP URI by adding the
sip:
prefix. Here’s how it should look:
Copy code
<sip:sbx-j4ktb7-Z58cQnzH3kaGKjynXTQ7sh@agentperformancedev-362y4m63.liveki>t.cloud
And here’s an example of how you’d use it:
Copy code
const transferTo = "<sip:sbx-j4ktb7-Z58cQnzH3kaGKjynXTQ7sh@agentperformancedev-362y4m63.liveki>t.cloud";
await sipClient.transferSipParticipant('room-name', 'participant-identity', transferTo);
Just a heads up—make sure your SIP provider trunks are set up to allow call transfers so everything goes smoothly. If you hit any snags or have more questions, I’m here to help! Sources: livekit-agents/livekit/agents/job.py | Transferring calls | LiveKit Docs
a
I got this error: {"message": "transferring call to sbx-j4ktb7-ATcT9KY7wTUQuyiuh3yzVX@agentperformancedev-362y4m63.livekit.cloud", "level": "INFO", "name": "outbound-caller", "pid": 17218, "job_id": "AJ_dsBzyirKweL2", "timestamp": "2025-08-04T003103.729732+00:00"} {"message": "error transferring call: TwirpError(code=canceled, message=twirp error unknown: call transfer failed, status=408)", "level": "ERROR", "name": "outbound-caller", "pid": 17218, "job_id": "AJ_dsBzyirKweL2", "timestamp": "2025-08-04T003118.161148+00:00"}
t
Hey there! The error
call transfer failed, status=408
means that the SIP request timed out during the transfer process. This usually happens when the transfer destination doesn’t respond in time or can’t be reached. Here are some friendly steps to help you fix this: 1. Increase the Timeout: Try setting a longer timeout for the transfer using the
ringing_timeout
parameter. For example:
Copy code
transfer_request = proto_sip.TransferSIPParticipantRequest(
    participant_identity=participant_identity,
    room_name=room_name,
    transfer_to=transfer_to,
    play_dialtone=True,
    ringing_timeout=duration_pb2.Duration(seconds=30)  # Increase timeout
)
2. Double-Check the Transfer Destination: Make sure the destination is: ◦ A valid and reachable SIP URI or phone number ◦ Formatted correctly (like
sip:user@host
or
tel:+1234567890
) ◦ Not busy or set to do-not-disturb ◦ Ready to accept incoming calls 1. Check Your Network Connection: Confirm that: ◦ Your SIP trunk can connect properly to the destination ◦ No firewalls or network issues are blocking SIP traffic ◦ Your SIP provider supports REFER requests needed for transfers 1. Keep an Eye on Transfer Status: Use error handling to smoothly manage any transfer hiccups and keep your users informed. If you want, I’m here to help you walk through any of these steps—just let me know! Sources: protobufs/livekit_sip.proto | pkg/sip/inbound.go
a
The transfer destination is a Livekit Room. where sbx-j4ktb7-ATcT9KY7wTUQuyiuh3yzVX is the room-name that was created: Wh is ist not working? Should I change the trunk or dispatch rule? Please see my trunk and dispatch rule { "sipTrunkId": "ST_YYBW4eKowJB3", "name": "Twilio trunk", "numbers": [ "+19497718422" ], "headersToAttributes": { "x-User-to-User": "call-data" }, "krispEnabled": true } { "sipDispatchRuleId": "SDR_rtHK4zpJZHSD", "rule": { "dispatchRuleIndividual": { "roomPrefix": "call" } }, "trunkIds": [ "ST_YYBW4eKowJB3" ], "name": "twilio Dispatch Rule" }
t
The 408 error means the transfer process timed out, and this can happen for a few different reasons. Looking at your trunk and dispatch rule setup, here are some common causes and how you might fix them: 1. SIP Provider Transfer Configuration: Double-check that your SIP provider trunk is set up to allow call transfers. If you're using Twilio SIP trunks, you can enable call transfers with this command:
Copy code
twilio api trunking v1 trunks update --sid <twilio-trunk-sid> \
--transfer-mode enable-all \
--transfer-caller-id from-transferee
2. Timeout Configuration: Transfers usually time out after 30 seconds by default. If your SIP provider takes longer to handle the transfer, make sure the transfer destination is reachable and responds promptly. It’s also a good idea to check if your SIP provider has any specific timeout settings. 3. Transfer Destination Issues: Check that the
transfer_to
value is: ◦ Formatted correctly (for example,
sip:room-name@host
) ◦ Reachable and set up to accept incoming calls 1. Test with a Simple Destination: Try transferring to a phone number or SIP URI that you know works. This can help narrow down where the problem might be. 2. Network Connectivity: Make sure there aren’t any network hiccups between LiveKit and your SIP provider, and that the SIP REFER method is supported and configured correctly. If you want, I’m here to help walk you through any of these steps—just let me know! Sources: protobufs/livekit_sip.proto | Transferring calls | LiveKit Docs | pkg/service/sip.go