hi, i am getting this error while cold transfer "...
# ask-ai
f
hi, i am getting this error while cold transfer " β†’ TwirpError: TwirpError(code=deadline_exceeded, message=twirp error unknown: request timed out, status=408)" what could be the issue? Khurram arshad [1:07 AM] this my code using for cold transfer async def transfer_call_tool(participant_identity: str, transfer_to: str, room_name: str) -> None: from aiohttp import ClientTimeout timeout = ClientTimeout(total=30) # 30 seconds async with api.LiveKitAPI(timeout=timeout) as livekit_api: # Create transfer request transfer_request = TransferSIPParticipantRequest( participant_identity=participant_identity, room_name=room_name, transfer_to=transfer_to, play_dialtone=True ) print(f"***********//////********************Transfer request: {transfer_request}, {room_name}, {transfer_to}") print("///////////////----------",transfer_request.dict) print(transfer_request.participant_identity) print(transfer_request.room_name) print(transfer_request.transfer_to) print(transfer_request.play_dialtone) print("πŸ“€ Sending transfer request to LiveKit:") print(f"URL: {livekit_api.sip.transfer_sip_participant.name}") print(f"Payload: {transfer_request}") # Transfer caller res = await livekit_api.sip.transfer_sip_participant(transfer_request) print("Response:", res) print(f"Successfully transferred participant {participant_identity} to {transfer_to}") @function_tool(name="transfer_call", description="Transfer the call to a human agent after greeting the user") async def transfer_call(ctx: RunContext, name: str) -> dict: job_ctx = get_job_context() room_name = job_ctx.room.name transfer_to = "sip:106@IP:PORT" # Send message to user await ctx.session.generate_reply( instructions=f"{name}, I'm now transferring you to a human agent." ) print("---- Participants in room ----") for identity, participant in job_ctx.room.remote_participants.items(): print(f"Identity: {identity}, Kind: {participant.kind}, Metadata: {participant.metadata}") print("All remote participants:", job_ctx.room.remote_participants) # Find the SIP participant to transfer sip_participant = next( (p for p in job_ctx.room.remote_participants.values() if p.kind == 3), None ) print("8888888888888888888888", sip_participant) print("9999999999999999999999", job_ctx) if not sip_participant: raise Exception("===================>>>>>>>>>No SIP participant found to transfer") # await transfer_call_tool(sip_participant.identity, transfer_to, room_name) # return "Call transferred" try: # response = await job_ctx.api.sip.create_sip_participant( # api.CreateSIPParticipantRequest( # sip_trunk_id="ST_QHjpLGXwxrGp", # sip_call_to="106", # room_name=room_name, # participant_identity=sip_participant.identity, # participant_name="Human Agent", # krisp_enabled=True # ) # ) # print("10101010101010101", response.participant_id) # await ctx.session.say(f"I'm transferring you to a human agent now. Please hold while we connect you.") # return None, f"I've transferred you to a human agent at . Please hold while we connect you." await transfer_call_tool(sip_participant.identity, transfer_to, room_name) return {"status": "transferred", "message": f"Transferred to {transfer_to}"} except TwirpError as e: print(f"Transfer failed: {e.code=} {e.status=} {e.message=}") print("🚨 Unexpected error during transfer:") print(f" β†’ {type(e).name}: {str(e)}") # Drop the call: disconnect the SIP participant # Optionally say goodbye before hanging up await ctx.session.generate_reply(instructions="I’m sorry, cannot connect you right now. Goodbye.") # Short delay to speak message await asyncio.sleep(3) # Drop the call async with api.LiveKitAPI() as livekit_api: await livekit_api.room.remove_participant( remove=api.RoomParticipantIdentity( room=room_name, identity=sip_participant.identity ) ) return {"status": "dropped", "message": "Call dropped after failed transfer"} # # Optional: you can log this or notify the user # await ctx.session.generate_reply( # instructions=f"{name}, I tried transferring you but the agent was not available. Let me continue helping you here." # ) # # Optional: you can also re-route to another SIP endpoint here # return {"status": "fallback", "message": "Transfer failed, resumed bot"} except Exception as e: print("Unexpected error during transfer:", str(e)) await ctx.session.generate_reply( instructions=f"Something went wrong while transferring you. I'm still here to help!" ) return {"status": "error", "message": str(e)}
t
Thanks for reaching out, Khurram. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
f
sure
t
The error TwirpError(code=deadline_exceeded, message=twirp error unknown: request timed out, status=408) during cold transfer indicates that the SIP transfer request exceeded its timeout period before it could complete. This generally means LiveKit did not receive a timely response from your SIP provider. Common causes include: β€’ Your SIP provider is taking too long to process the REFER request, or there may be network latency. β€’ SIP REFER is not properly enabled or configured on your SIP trunk (this is required for transfer operations). β€’ Poor network connectivity between LiveKit and your SIP provider. Potential solutions: β€’ Increase the timeout in your client codeβ€”for example, set
timeout = aiohttp.ClientTimeout(total=60)
in Python. β€’ Verify that SIP REFER is enabled on your SIP trunk (and for Twilio, "Enable PSTN Transfer" should be active). β€’ Check with your SIP provider to ensure they process REFER requests as expected and there is no unnecessary delay on their end. The 408 status code points to a SIP-level timeout, suggesting the issue is more likely with the SIP infrastructure or configuration than with LiveKit's systems directly. Monitoring SIP provider logs for REFER handling may help pinpoint the delay. If you need detailed troubleshooting steps based on your SIP provider/platform, let me know which provider you are using and any further relevant details about your setup. Sources: pkg/service/sip.go | sipclient.go | packages/livekit-server-sdk/src/SipClient.ts | Agents telephony integration | LiveKit Docs | agent.py | livekit-protocol/livekit/protocol/sip.pyi | livekit/livekit_sip.pb.go
f
SIP provider says no request or call is landing to their Server
t
Hey there! πŸ‘‹ Looks like you're running into a tricky SIP transfer issue. Don't worry, we'll work through this together. If your SIP provider isn't seeing a REFER or transfer request and you're getting a TwirpError code=deadline_exceeded, it probably means the transfer is timing out before the SIP REFER message can be sent. The good news? This is usually something we can fix on the application side. Let's troubleshoot step by step: β€’ Check your SIP participant's call state - make sure they're in an active call and not disconnected. β€’ Verify the SIP call ID - this is super important for making transfers work smoothly. β€’ Do a quick parameter check: Confirm your
room_name
isn't empty,
participant_identity
is correct (SIP, not WebRTC), and the
transfer_to
destination looks good. β€’ Double-check that SIP REFER is enabled with your provider and in your trunk settings. β€’ Turn on debug logging in your LiveKit server - this will help us see exactly what's happening during the transfer. β€’ Watch out for duplicate transfer attempts - these can sometimes cause hiccups. β€’ Network connections: Make sure LiveKit can reach your SIP provider and your firewall/NAT settings are set up correctly. It sounds like the transfer might be getting stuck because LiveKit isn't connecting your request to an active SIP session. Let's dig into the details and get this sorted out! If you can share the participant identity, room name, and the SIP state right before the transfer, I can help you pinpoint the exact issue. We've got this! πŸ’ͺ Sources: Agents telephony integration | LiveKit Docs | pkg/sip/service.go | pkg/service/sip.go | sip-refer/agent.py
f
how to check "SIP call ID"
t
Hey there! Need to grab the SIP call ID for a participant in LiveKit? No worriesβ€”I've got you covered. You'll want to peek at the participant's attributes, specifically the
sip.callID
that uniquely tags each SIP call session. Python example:
Copy code
if participant.kind == rtc.ParticipantKind.PARTICIPANT_KIND_SIP:
    call_id = participant.attributes.get('sip.callID')
    print(f"SIP Call ID: {call_id}")
Where to find: β€’ In most SDKs, the SIP participant's
attributes
dictionary/object will have
sip.callID
and
sip.callStatus
. β€’ Via the LiveKit management API: retrieve SIP participant info for
sip_call_id
in the response. β€’ With LiveKit CLI tools, SIP call IDs are shown in participant info and diagnostics output. Pro tip: If you're troubleshooting a transfer issue, double-check this value for the participant. If
sip.callID
is missing or empty, the system might get a bit stuck, so you'll want to resolve that first. We're here to help make things smooth! Sources: telephony/sip_lifecycle.py | protobufs/rpc/io.proto | cmd/lk/sip.go | pkg/service/sip.go | SIP participant | LiveKit Docs
f
how to import rtc in rtc.ParticipantKind.PARTICIPANT_KIND_SIP
t
Hey there! Want to work with SIP participants in LiveKit's Python SDK? No worries, I've got a super simple way to do that. Just import the rtc module like this:
Copy code
from livekit import rtc

# Then you can check participant kind:
if participant.kind == rtc.ParticipantKind.PARTICIPANT_KIND_SIP:
    # Handle SIP participant
    pass
This approach is totally standard and you'll see it used all over the LiveKit Python SDK documentation and examples. Pretty straightforward, right? Happy coding! 😊 Sources: livekit-agents/livekit/agents/job.py | livekit-protocol/livekit/protocol/models.py | evaluating-agents/agent_to_test.py
f
yes i am able to get SIP Call ID---------------------------->>>>>>>>>>>>>>>>>: SCL_7Wit6cAPLcip
t
Hey there! I totally get how frustrating SIP transfer errors can be. I've got some friendly steps to help you troubleshoot that pesky deadline_exceeded issue. β€’ *First things first, make sure your SIP call is still active*β€”we want that connection going strong right when you're trying to transfer. β€’ *Double-check your SIP REFER settings*β€”especially for Twilio users, both "Enable PSTN Transfer" and SIP REFER need to be turned on. β€’ Take a peek at your *LiveKit SIP service logs*β€”they're like a detective's notebook that can reveal what might be going wrong behind the scenes. β€’ *Try playing with timeout settings*β€”sometimes networks can be a bit sluggish, so increasing the timeout might just do the trick. β€’ Experiment by *transferring to different destinations*β€”this can help us figure out if it's a specific number causing trouble. β€’ *Do a network health check*β€”make sure your firewall and network settings are playing nice with SIP protocols. Between you and me, this error looks like it might be happening on LiveKit's side before it even reaches your provider. The LiveKit logs will be our best friend in solving this mystery! Sources: pkg/service/sip.go | Agents telephony integration | LiveKit Docs | protobufs/rpc/sip.proto | Transferring calls | LiveKit Docs | pkg/sip/service.go
f
these logs i am getting go through these to find the issue ---- Participants in room ---- Identity: sip_2001, Kind: 3, Metadata: All remote participants: {'sip_2001': rtc.RemoteParticipant(sid=PA_NK5YcRS6JrSB, identity=sip_2001, name=Phone 2001)} SIP Call ID---------------------------->>>>>>>>>>>>>>>>>: SCL_7Wit6cAPLcip 8888888888888888888888 rtc.RemoteParticipant(sid=PA_NK5YcRS6JrSB, identity=sip_2001, name=Phone 2001) 9999999999999999999999 <livekit.agents.job.JobContext object at 0x7f55ac2c7dd0> ***********//////********************Transfer request: participant_identity: "sip_2001" room_name: "room-_2001_hptsjEU4qPih" transfer_to: "sip:106@90.250.8.96:5069" play_dialtone: true , room-_2001_hptsjEU4qPih, sip:106@90.250.8.96:5069 ///////////////---------- {'HeadersEntry': <class 'sip.TransferSIPParticipantRequest.HeadersEntry'>, 'DESCRIPTOR': <google._upb._message.Descriptor object at 0x7f55b07cffb0>, '__module__': 'sip', '__slots__': (), '__doc__': None} sip_2001 room-_2001_hptsjEU4qPih sip:106@90.250.8.96:5069 True Transfer failed: e.code='deadline_exceeded' e.status=408 e.message='twirp error unknown: request timed out' 🚨 Unexpected error during transfer: β†’ TwirpError: TwirpError(code=deadline_exceeded, message=twirp error unknown: request timed out, status=408) lk sip outbound list Using default project [LIVEKITPYTHONAPI] β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ SipTrunkID β”‚ Name β”‚ Address β”‚ Transport β”‚ Numbers β”‚ Authentication β”‚ Encryption β”‚ Headers β”‚ Metadata β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ ST_QHjpLGXwxrGp β”‚ My outbound trunk β”‚ 90.250.8.96:5069 β”‚ TCP β”‚ 103 β”‚ β”‚ DISABLE β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
t
Hey there! I noticed something interesting in your logs about the transfer_sip_participant call. It looks like everything seems technically correct on your end, but you're still hitting a deadline_exceeded error without seeing a REFER at your SIP provider. Sounds like there might be a hiccup with your provider's configuration for call transfers: β€’ Your SIP provider/trunk needs to be set up to specifically support SIP REFER requests for call transfers. β€’ If you're using Twilio, you'll want to make sure you've enabled both "Call Transfer" and "PSTN Transfer" on the trunkβ€”otherwise, those transfer requests might just disappear into thin air. β€’ Not sure about your provider's transfer capabilities? It might be worth reaching out to their support to double-check, especially given you're using a TCP connection with encryption turned off. When no REFER message is making it through, even with all your parameters looking good, it usually means something's getting blocked or rejected before it even reaches the provider's SIP system. Your best bet is to dig into those SIP trunk settings or get in touch with your provider's support. If you're on Twilio, you might need to poke around in the admin portal to make sure everything's configured just right. One more thingβ€”just to be extra sure, it might be worth confirming with your provider that REFER is supported over a TCP connection without encryption, since some systems can be pretty particular about their communication protocols. Sources: protobufs/rpc/sip.proto | pkg/service/sip.go | Transferring calls | LiveKit Docs
f
how to check my livekit cloud is hitting SIP provider any logs or some thing?
t
I don't have the answer you're looking for. You could also try asking your question: β€’ in one of the other Slack channels or β€’ to https://deepwiki.com/livekit/livekit_composite which is trained on all LiveKit source code If you find the answer, please post it here to help others!
f
how to turn on? for this "Turn on debug logging in your LiveKit server - this will help us see exactly what's happening during the transfer."
hi