busy-account-75322
12/24/2025, 8:18 AMlivekit-server-sdk.
What we tested
We tested SIP cold transfer in two ways:
1. Using LiveKit CLI (v2.4.12)
2. Using Node.js livekit-server-sdk (SipClient.transferSipParticipant)
Observed behavior
Using LiveKit CLI
When performing a SIP transfer via the CLI, the transfer command appears to wait for the actual transfer outcome.
In cases where the destination party does not answer or rejects the call, the CLI command returns an error that can be unwrapped into a SIP status (e.g. busy, no-answer, etc.).
This aligns with the CLI implementation:
/`/ TransferSIPParticipant will wait for call to be transferred and that can take some time.`
// Default deadline is too short, thus, we must set a higher deadline for it.
ctx, cancel = context.WithTimeout(ctx, 30*time.Second)
return s.sipClient.TransferSIPParticipant(ctx, in)
and the presence of:
func SIPStatusFrom(err error) *livekit.SIPStatus
which allows extracting SIP-level failure details.
Using Node.js livekit-server-sdk
When calling:
sipClient.transferSipParticipant(roomName, identity, transferTo)
The promise resolves successfully as soon as the transfer request is accepted, even if:
• The destination does not answer,
• The call is rejected.
• or the SIP transfer ultimately fails.
No SIP status (busy / no-answer / failed) is returned or surfaced via the Node.js SDK call, which makes it difficult to determine whether the transfer actually succeeded.
Questions:
1. Is the difference in behavior between livekit-cli and livekit-server-sdk (Node.js) intentional?
2. Is there a supported way in the Node.js SDK to:
• await the SIP transfer outcome (answered / busy / no-answer), or
• extract SIP failure details similar to SIPStatusFrom in the Go client?
3. If not, what is the recommended pattern for server-side applications using the Node.js SDK to reliably track SIP transfer results?busy-account-75322
12/29/2025, 8:13 AM