Skip to main content

Managing participants

List, remove, and mute from your backend server.

Initialize RoomServiceClient

Participant management is done through the room service. Create a RoomServiceClient:

import (
lksdk "github.com/livekit/server-sdk-go"
livekit "github.com/livekit/protocol/livekit"
)
// ...
host := "https://my.livekit.host"
roomClient := lksdk.NewRoomServiceClient(host, "api-key", "secret-key")
pip install livekit-api
from livekit.api import LiveKitAPI
# Will read LIVEKIT_URL, LIVEKIT_API_KEY, and LIVEKIT_API_SECRET from environment variables
async with api.LiveKitAPI() as lkapi:
# ... use your client with `lkapi.room` ...
import { Room, RoomServiceClient } from 'livekit-server-sdk';
const livekitHost = 'https://my.livekit.host';
const roomService = new RoomServiceClient(livekitHost, 'api-key', 'secret-key');

List Participants

List all the participants in a room.

res, err := roomClient.ListParticipants(context.Background(), &livekit.ListParticipantsRequest{
Room: roomName,
})
from livekit.api import ListParticipantsRequest
res = await lkapi.room.list_participants(ListParticipantsRequest(
room=room_name
))
const res = await roomService.listParticipants(roomName);
lk room participants list <ROOM_NAME>

Get details on a Participant

Get detailed information about a participant in a room.

res, err := roomClient.GetParticipant(context.Background(), &livekit.RoomParticipantIdentity{
Room: roomName,
Identity: identity,
})
from livekit.api import RoomParticipantIdentity
res = await lkapi.room.get_participant(RoomParticipantIdentity(
room=room_name,
identity=identity,
))
const res = await roomService.getParticipant(roomName, identity);
lk room participants get --room <ROOM_NAME> <PARTICIPANT_ID>

Updating permissions

You can modify a participant's permissions using the UpdateParticipant API. When there's a change in permissions, connected clients are notified through the ParticipantPermissionChanged event.

This is useful, for example, when transitioning an audience member to a speaker role within a room.

Revoking permissions unpublishes tracks

When you revoke the CanPublish permission from a participant, all tracks they've published are automatically unpublished.

// Promotes an audience member to a speaker
res, err := c.UpdateParticipant(context.Background(), &livekit.UpdateParticipantRequest{
Room: roomName,
Identity: identity,
Permission: &livekit.ParticipantPermission{
CanSubscribe: true,
CanPublish: true,
CanPublishData: true,
},
})
// ...and later move them back to audience
res, err := c.UpdateParticipant(context.Background(), &livekit.UpdateParticipantRequest{
Room: roomName,
Identity: identity,
Permission: &livekit.ParticipantPermission{
CanSubscribe: true,
CanPublish: false,
CanPublishData: true,
},
})
from livekit.api import UpdateParticipantRequest, ParticipantPermission
# Promotes an audience member to a speaker
await lkapi.room.update_participant(UpdateParticipantRequest(
room=room_name,
identity=identity,
permission=ParticipantPermission(
can_subscribe=True,
can_publish=True,
can_publish_data=True,
),
))
# ...and later move them back to audience
await lkapi.room.update_participant(UpdateParticipantRequest(
room=room_name,
identity=identity,
permission=ParticipantPermission(
can_subscribe=True,
can_publish=False,
can_publish_data=True,
),
))
// Promotes an audience member to a speaker
await roomService.updateParticipant(roomName, identity, undefined, {
canPublish: true,
canSubscribe: true,
canPublishData: true,
});
// ...and later move them back to audience
await roomService.updateParticipant(roomName, identity, undefined, {
canPublish: false,
canSubscribe: true,
canPublishData: true,
});
lk room participants update \
--permissions '{"can_publish":true,"can_subscribe":true,"can_publish_data":true}' \
--room <ROOM_NAME> \
<PARTICIPANT_ID>

Updating metadata

You can modify a Participant's metadata whenever necessary. When metadata is changed, connected clients receive a ParticipantMetadataChanged event.

data, err := json.Marshal(values)
_, err = c.UpdateParticipant(context.Background(), &livekit.UpdateParticipantRequest{
Room: roomName,
Identity: identity,
Metadata: string(data),
})
from livekit.api import UpdateParticipantRequest
await lkapi.room.update_participant(UpdateParticipantRequest(
room=room_name,
identity=identity,
metadata=json.dumps({"some": "values"}),
))
const data = JSON.stringify({
some: 'values',
});
await roomService.updateParticipant(roomName, identity, data);
lk room participants update \
--metadata '{"some":"values"}' \
--room <ROOM_NAME> \
<PARTICIPANT_ID>

Move a Participant

Move a participant from one room to a different room.

res, err := roomClient.MoveParticipant(context.Background(), &livekit.MoveParticipantRequest{
Room: roomName,
Identity: identity,
DestinationRoom: destinationRoom,
})
from livekit.api import MoveParticipantRequest
await lkapi.room.move_participant(MoveParticipantRequest(
room="<CURRENT_ROOM_NAME>",
identity="<PARTICIPANT_ID>",
destination_room="<NEW_ROOM_NAME>",
))
await roomService.moveParticipant(roomName, identity, destinationRoom);
lk room participants move --room <CURRENT_ROOM_NAME> \
--identity <PARTICIPANT_ID> \
--destination-room <NEW_ROOM_NAME>

Remove a Participant

RemoveParticipant forcibly disconnects the participant from the room. However, this action doesn't invalidate the participant's token.

To prevent the participant from rejoining the same room, consider the following measures:

  • Generate access tokens with a short TTL (Time-To-Live).
  • Refrain from providing a new token to the same participant via your application's backend.
res, err := roomClient.RemoveParticipant(context.Background(), &livekit.RoomParticipantIdentity{
Room: roomName,
Identity: identity,
})
from livekit.api import RoomParticipantIdentity
await lkapi.room.remove_participant(RoomParticipantIdentity(
room=room_name,
identity=identity,
))
await roomService.removeParticipant(roomName, identity);
lk room participants remove <PARTICIPANT_ID>

Mute or unmute a Participant's Track

To mute a particular Track from a Participant, you must first get the TrackSid using the GetParticipant API, then call the MutePublishedTrack API:

res, err := roomClient.MutePublishedTrack(context.Background(), &livekit.MuteRoomTrackRequest{
Room: roomName,
Identity: identity,
TrackSid: "track_sid",
Muted: true,
})
from livekit.api import MuteRoomTrackRequest
await lkapi.room.mute_published_track(MuteRoomTrackRequest(
room=room_name,
identity=identity,
track_sid="track_sid",
muted=True,
))
await roomService.mutePublishedTrack(roomName, identity, 'track_sid', true);
lk room mute-track \
--room <ROOM_NAME> \
--identity <PARTICIPANT_ID> \
<TRACK_SID>

You can also unmute the track by setting muted to false.

Note

Being remotely unmuted can catch users by surprise, so it's turned off by default.

To allow remote unmute, select the Admins can remotely unmute tracks option in your project settings.

If you're self-hosting, configure room.enable_remote_unmute: true in your config YAML.