suppose for telephony i am using Twilio and is the...
# ask-ai
n
suppose for telephony i am using Twilio and is there any way to get it's callSid (consider as Livekit RoomName) in LiveKit Room after inbound call initiated
t
Thanks for reaching out, Darshak. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
You're asking whether a Twilio inbound call's Call SID can be available in a LiveKit room and whether you can use it as the LiveKit room name. Here's the concise answer and next steps. What you can do now • Twilio's Call SID is exposed on the SIP participant as the attribute
sip.twilio.callSid
. You can read it from the participant inside the LiveKit room (example: Node.js
participant.attributes['sip.twilio.callSid']
, Python
participant.attributes.get('sip.twilio.callSid')
). What you cannot do directly • You cannot use the Twilio
callSid
in LiveKit dispatch rules to name a room at the moment the call is dispatched, because dispatch rules run before Twilio assigns the Call SID. Workarounds / recommended approaches • Correlation after connect: Let the call connect, read
sip.twilio.callSid
from the SIP participant, and store/map that Call SID to the LiveKit room ID/name in your backend (for logging, analytics, or linking records). • Pre-create room with external coordination: If you need the room name to equal the Call SID, have your backend create the LiveKit room in advance with a name derived from the Call SID. This requires capturing the Call SID from Twilio (via your Twilio webhook) before connecting the SIP leg to LiveKit, then instructing Twilio to join that pre-created room (or direct your SIP gateway to use the pre-created room name). If you want, tell me: • Which SDK/language you're using (Node, Python, Go, etc.) • Whether you control the Twilio webhook flow or SIP gateway setup I can then give a short code example or a step-by-step for the approach you prefer. Sources: SIP participant | LiveKit docs | SIP dispatch rule | LiveKit docs | SIP overview | LiveKit docs
n
Copy code
class RemoteTrackPublication(TrackPublication):
    def __init__(self, owned_info: proto_track.OwnedTrackPublication):
        super().__init__(owned_info)
        self._subscribed = False

    @property
    def track(self) -> Optional[RemoteTrack]:
        return cast(Optional[RemoteTrack], self._track)

    @property
    def subscribed(self) -> bool:
        return self._subscribed

    def set_subscribed(self, subscribed: bool):
        req = proto_ffi.FfiRequest()
        req.set_subscribed.subscribe = subscribed
        req.set_subscribed.publication_handle = self._ffi_handle.handle
        FfiClient.instance.request(req)
explain what is subscribed for a local participant >?
t
You're asking what
subscribed
means for a local participant in the provided
RemoteTrackPublication
class. Short answer: it indicates whether the local participant is actively receiving media for that remote track. Key points •
subscribed
is a boolean on the local side that shows whether you are currently receiving media from the remote participant's published track. • A
RemoteTrackPublication
exists as soon as a remote participant publishes a track (metadata visible even if you don't receive media). • When `subscribed == False`: you know the track exists but you are not receiving its media;
publication.track
will be None. • When you call `set_subscribed(True)`: the SDK sends a request to start receiving media for that publication (signaling to the server), WebRTC negotiation completes, and a
RemoteTrack
is created and assigned to
publication.track
. • Use cases: conserve bandwidth by subscribing only to tracks you need, implement selective subscription (e.g., active speaker), or toggle media on/off dynamically. If you want, I can: • Show a short code example (your language) for subscribing and handling the created
RemoteTrack
. • Explain events/callbacks you should listen to for when the
track
becomes available. Which would you prefer? Sources: client-sdk-js | livekit/livekit_composite | DeepWiki | Subscribing to tracks | LiveKit docs | Rooms, participants, and tracks | LiveKit docs | client-sdk-android | livekit/livekit_composite | DeepWiki
n
for voice._ParticipantAudioOutput() what is track.sid ?
t
In
voice._ParticipantAudioOutput()
,
track.sid
is the server-assigned unique identifier (SID) for that media track. It uniquely identifies the specific audio track published in the LiveKit room and is used to: • reference the track in signaling and internal logic, • map playback/output to the correct participant track, • manage subscriptions, muting, or other per-track operations, • correlate server-side actions (egress, analytics) with the exact track. If you want, tell me which SDK/language and what you’re doing in
voice._ParticipantAudioOutput()
and I’ll give a short code example showing how to use
track.sid
. Sources: Rooms, participants, and tracks | LiveKit docs | client-sdk-unity | livekit/livekit_composite | DeepWiki
n
python
t
Got it — Python. Below is a concise example and explanation showing how to use
track.sid
in a Python context (e.g., inside
voice._ParticipantAudioOutput()
), plus common uses. Explanation •
track.sid
is the server-assigned unique identifier for the published track. • Use it to identify which audio track to play/output, to map events to tracks, or to control subscriptions/muting/egress for that exact track. Minimal Python example
Copy code
def participant_audio_output(participant, publication):
    # publication is a RemoteTrackPublication
    if publication.track is None:
        print("Not subscribed; no media yet")
        return

    track = publication.track            # RemoteTrack
    sid = track.sid                      # server-assigned track SID
    print(f"Outputting audio for participant {participant.sid}, track SID={sid}")

    # Example: attach track to an audio sink (pseudo-code)
    audio_sink = AudioOutputDevice()
    audio_element = track.attach()       # returns a playback object
    audio_sink.play(audio_element)

    # Use sid for logging or correlating with backend
    backend.log_playback(participant_sid=participant.sid, track_sid=sid)
Common patterns • Logging/analytics: store
track.sid
to correlate playback and server-side records. • Selective output: look up the publication by
sid
to toggle output for a specific track. • Egress/control: send
track.sid
to backend APIs that perform recording/egress for that exact track. If you share the snippet of your
voice._ParticipantAudioOutput()
function, I can adapt this example to your code. Would you like that?
n
{"level": "ERROR", "name": "transcriber", "message": "Failed to mute track: code=failed_precondition msg=TwirpError(code=failed_precondition, message=twirp error unknown: remote unmute not enabled, status=412)
t
You're seeing: Failed to mute track ... remote unmute not enabled (status=412). What it means • The server rejected the remote mute/unmute operation because remote unmute is disabled for the room/project. How to fix • If you're on LiveKit Cloud: enable "Admins can remotely unmute tracks" in Project Settings. • If self-hosted: set
room.enable_remote_unmute: true
in your LiveKit server config YAML. • Ensure the caller has the
roomAdmin
grant in their access token when calling the mute/unmute API. Example (Python) to unmute after enabling:
Copy code
await lkapi.room.mute_published_track(
    MuteRoomTrackRequest(
        room=room_name,
        identity=identity,
        track_sid="track_sid",
        muted=False,
    )
)
If you've already enabled remote unmute and still get this error, tell me: • whether you're on Cloud or self-hosted, • the API call you're making (code snippet), and I’ll help diagnose further. Sources: Managing participants | LiveKit docs