Data messages

With LiveKit maintaining room state, you can use it to pass around custom application data. We have a flexible system that enables you to pass messages from both the backend, and between participants.

Participant metadata

LiveKit participants feature a metadata field, which allows you to store application-specific data. This can encompass various participant-related information, such as a URL to a participant's avatar or other unique participant attributes.

Metadata is encoded in the access token that participants use to connect to the room.

With our server SDKs, you can update any participant's metadata from your backend. LiveKit will broadcast metadata changes to all participants in the room. You can receive these updates by listening to the MetadataUpdated callback/event.

Example: Updating metadata from server API

import { RoomServiceClient } from 'livekit-server-sdk';
const client = new RoomServiceClient("myhost", "api-key", "my secret")
const data = JSON.stringify({
some: "values",
client.updateParticipant("myroom", "participant-identity", data)

Example: Updating metadata from client

When canUpdateOwnMetadata permission is granted, a participant could also update their own name and metadata from client SDKs.

const data = JSON.stringify({
some: "values",
room.localParticipant.setName('new name')

Room metadata

Similar to Participant metadata, Rooms also feature a metadata field where you can store data specific to your application. This can be used to store data about the Room that is visible to all participants.

You can set Room metadata using the CreateRoom API, and updated with the UpdateRoomMetadata API.

When there's a change in the Room metadata, a RoomMetadataChanged event is triggered, notifying all participants within the room.

Data messages

From both server and clients, LiveKit lets you publish arbitrary data messages to any participants in the room via the LocalParticipant.publishData API. Room data is published to the SFU via WebRTC data channels; and LiveKit server would forward that data to one or more participants in the room.

From the server side, this API is exposed on RoomService as SendData

Since the data is sent via UDP, you have a flexibility in regard to the reliability of delivery. We support both reliable and lossy. In reliable mode, your packets will be retransmitted until they are received. For use-cases such as in-room chat, this is preferable.

When using lossy delivery, we suggest keeping data packets small (under network MTU of 1.4k). If a message is packetized into multiple packets, and a single packet doesn't arrive, your client will not receive the message at all.

const strData = JSON.stringify({some: "data"})
const encoder = new TextEncoder()
const decoder = new TextDecoder()
// publishData takes in a Uint8Array, so we need to convert it
const data = encoder.encode(strData);
// publish lossy data to the entire room
room.localParticipant.publishData(data, {reliable: false})
// publish reliable data to a set of participants
room.localParticipant.publishData(data, {reliable: true, destinationIdentities: ['my-participant-identity']})
// receive data from other participants
room.on(RoomEvent.DataReceived, (payload: Uint8Array, participant: Participant, kind: DataPacket_Kind) => {
const strData = decoder.decode(payload)