Remote Participants

Last updated Oct 19, 2026 This guide explains how to access participant data, display videos, handle events, and manage participant permissions in your RealtimeKit meetings.

Prerequisites

This page assumes you've already initialized the SDK and understand the meeting object structure. Refer to Initialize SDK and Meeting Object Explained if needed.

WebMobile

ReactWeb ComponentsAngular

The participant object contains all information related to a particular participants, including information about the grid and each participants media streams, name, and state variables. It is accessible via meeting.participants.

Properties

Metadata properties

  • id - The participantId of the participant (aka peerId)
  • userId - The userId of the participant
  • name - The participant's name
  • picture - The participant's picture (if any)
  • customParticipantId - An arbitrary ID that can be set to identify the participant
  • isPinned - Set to true if the participant is pinned
  • presetName - Name of the preset associated with the participant

Metadata properties

  • id - Session-specific identifier generated when the participant joins meeting session (also known as peerId)
  • userId - Permanent identifier of the participant generated when adding the participant to a meeting
  • name - Display name of the participant
  • picture - String URL to the participant's display picture (if any)
  • customParticipantId - Custom identifier that can be set while adding participant to a meeting by customer
  • isHost - Boolean value whether this participant has host privileges
  • isPinned - Whether this participant is currently pinned in the meeting
  • presetName - Name of the preset applied to this participant while adding to meeting
  • stageStatus - Indicates the participant's current stage status (applicable only in stage-enabled meetings)

Metadata properties

  • id - Session-specific identifier generated when the participant joins meeting session (also known as peerId)
  • userId - Permanent identifier of the participant generated when adding the participant to a meeting
  • name - Display name of the participant
  • picture - String URL to the participant's display picture (if any)
  • customParticipantId - Custom identifier that can be set while adding participant to a meeting by customer
  • isHost - Boolean value whether this participant has host privileges
  • isPinned - Whether this participant is currently pinned in the meeting
  • presetName - Name of the preset applied to this participant while adding to meeting
  • stageStatus - Indicates the participant's current stage status (applicable only in stage-enabled meetings)

Media properties

  • videoEnabled - Set to true if the participant's camera is on
  • audioEnabled - Set to true if the participant is unmuted
  • screenShareEnabled - Set to true if the participant is sharing their screen
  • videoTrack - The video track of the participant
  • audioTrack - The audio track of the participant
  • screenShareTracks - The video and audio tracks of the participant's screen share

Media properties

  • videoEnabled - Whether the participant's camera is currently enabled
  • audioEnabled - Whether the participant's microphone is currently unmuted
  • screenshareEnabled - Whether the participant is currently sharing their screen

Access participant properties

// Number of participants joined in the meeting
console.log(meeting.participants.count);

// Number of pages available in paginated mode
console.log(meeting.participants.pageCount);

// Maximum number of participants in active state
console.log(meeting.participants.maxActiveParticipantsCount);

// ParticipantId of the last participant who spoke
console.log(meeting.participants.lastActiveSpeaker);

Use the useRealtimeKitSelector hook to access properties:

// Number of participants joined in the meeting
const participantCount = useRealtimeKitSelector((m) => m.participants.count);

// Number of pages available in paginated mode
const pageCount = useRealtimeKitSelector((m) => m.participants.pageCount);

// Maximum number of participants in active state
const maxActiveCount = useRealtimeKitSelector(
    (m) => m.participants.maxActiveParticipantsCount,
);

// ParticipantId of the last participant who spoke
const lastActiveSpeaker = useRealtimeKitSelector(
    (m) => m.participants.lastActiveSpeaker,
);
// Number of participants joined in the meeting
val participantCount = meeting.participants.joined.size

// Access pagination properties
val maxNumberOnScreen = meeting.participants.maxNumberOnScreen
val currentPageNumber = meeting.participants.currentPageNumber
val pageCount = meeting.participants.pageCount
val canGoNextPage = meeting.participants.canGoNextPage
val canGoPreviousPage = meeting.participants.canGoPreviousPage
// Number of participants joined in the meeting
let participantCount = meeting.participants.joined.count

// Access pagination properties
let maxNumberOnScreen = meeting.participants.maxNumberOnScreen
let currentPageNumber = meeting.participants.currentPageNumber
let pageCount = meeting.participants.pageCount
let canGoNextPage = meeting.participants.canGoNextPage
let canGoPreviousPage = meeting.participants.canGoPreviousPage

Use the useRealtimeKitSelector hook to access properties:

// Number of participants joined in the meeting
const participantCount = useRealtimeKitSelector((m) => m.participants.count);

// Number of pages available in paginated mode
const pageCount = useRealtimeKitSelector((m) => m.participants.pageCount);

// Maximum number of participants in active state
const maxActiveCount = useRealtimeKitSelector(
    (m) => m.participants.maxActiveParticipantsCount,
);

// ParticipantId of the last participant who spoke
const lastActiveSpeaker = useRealtimeKitSelector(
    (m) => m.participants.lastActiveSpeaker,
);

Access participant object

You can fetch a participant from the participant maps.

const participant = meeting.participants.joined.get(participantId);

// Access participant properties
console.log(participant.name);
console.log(participant.videoEnabled);
console.log(participant.audioEnabled);
// Get a specific participant
const participant = useRealtimeKitSelector((m) =>
    m.participants.joined.get(participantId),
);

// Access participant properties
const participantName = participant?.name;
const isVideoEnabled = participant?.videoEnabled;
const isAudioEnabled = participant?.audioEnabled;
// Find a participant by peer ID
val participant = meeting.participants.joined.firstOrNull { it.id == participantId }

// Access participant properties
participant?.let {
    println("Participant: ${it.name}")
    println("Video: ${it.videoEnabled}")
    println("Audio: ${it.audioEnabled}")
}
// Find a participant by peer ID
if let participant = meeting.participants.joined.first(where: { $0.id == participantId }) {
    // Access participant properties
    print("Participant: \(participant.name)")
    print("Video: \(participant.videoEnabled)")
    print("Audio: \(participant.audioEnabled)")
}
// Get a specific participant
const participant = useRealtimeKitSelector((m) =>
    m.participants.joined.get(participantId),
);

// Access participant properties
const participantName = participant?.name;
const isVideoEnabled = participant?.videoEnabled;
const isAudioEnabled = participant?.audioEnabled;

Participant Maps

All participants are stored under meeting.participants. These do not include the local user.

The meeting.participants object contains the following maps:

  • joined - All participants currently in the meeting (excluding the local user)
  • waitlisted - All participants waiting to join the meeting
  • active - All participants whose media is subscribed to (participants that should be displayed on screen)
  • pinned - All pinned participants in the meeting

If you are building a video/audio grid, use the active map. To display a list of all participants, use the joined map.

Each participant in these maps is of type RTKParticipant.

All participants are stored under meeting.participants. These do not include the local user.

The meeting.participants object contains the following lists:

  • joined - All participants currently in the meeting (excluding the local user)
  • waitlisted - All participants waiting to join the meeting
  • active - All participants whose media is subscribed to (participants that should be displayed on screen)
  • pinned - All pinned participants in the meeting
  • screenShares - All participants who are sharing their screen

If you are building a video/audio grid, use the active list. To display a list of all participants, use the joined list.

// Get all joined participants
const joinedParticipants = meeting.participants.joined;

// Get active participants (those on screen)
const activeParticipants = meeting.participants.active;

// Get pinned participants
const pinnedParticipants = meeting.participants.pinned;

// Get waitlisted participants
const waitlistedParticipants = meeting.participants.waitlisted;

Use the useRealtimeKitSelector hook to access participant maps:

import { useRealtimeKitSelector } from "@cloudflare/realtimekit-react";

// Get all joined participants
const joinedParticipants = useRealtimeKitSelector((m) => m.participants.joined);

// Get active participants (those on screen)
const activeParticipants = useRealtimeKitSelector((m) => m.participants.active);

// Get pinned participants
const pinnedParticipants = useRealtimeKitSelector((m) => m.participants.pinned);

// Get waitlisted participants
const waitlistedParticipants = useRealtimeKitSelector(
    (m) => m.participants.waitlisted,
);
// Get all joined participants
val joinedParticipants: List<RtkRemoteParticipant> = meeting.participants.joined

// Get active participants (those on screen)
val activeParticipants: List<RtkRemoteParticipant> = meeting.participants.active

// Get pinned participants
val pinnedParticipants: List<RtkRemoteParticipant> = meeting.participants.pinned

// Get waitlisted participants
val waitlistedParticipants: List<RtkRemoteParticipant> = meeting.participants.waitlisted

// Get screen sharing participants
val screenShareParticipants: List<RtkRemoteParticipant> = meeting.participants.screenShares
// Get all joined participants
let joinedParticipants: [RtkRemoteParticipant] = meeting.participants.joined

// Get active participants (those on screen)
let activeParticipants: [RtkRemoteParticipant] = meeting.participants.active

// Get pinned participants
let pinnedParticipants: [RtkRemoteParticipant] = meeting.participants.pinned

// Get waitlisted participants
let waitlistedParticipants: [RtkRemoteParticipant] = meeting.participants.waitlisted

// Get screen sharing participants
let screenShareParticipants: [RtkRemoteParticipant] = meeting.participants.screenShares

Use the useRealtimeKitSelector hook to access participant maps:

import { useRealtimeKitSelector } from "@cloudflare/realtimekit-react-native";

// Get all joined participants
const joinedParticipants = useRealtimeKitSelector((m) => m.participants.joined);

// Get active participants (those on screen)
const activeParticipants = useRealtimeKitSelector((m) => m.participants.active);

// Get pinned participants
const pinnedParticipants = useRealtimeKitSelector((m) => m.participants.pinned);

// Get waitlisted participants
const waitlistedParticipants = useRealtimeKitSelector(
    (m) => m.participants.waitlisted,
);

View Modes

The view mode indicates whether participants are populated in ACTIVE_GRID mode or PAGINATED mode.

  • ACTIVE_GRID mode - Participants are automatically replaced in meeting.participants.active based on who is speaking or who has their video turned on
  • PAGINATED mode - Participants in meeting.participants.active are fixed. Use setPage() to change the active participants

Set view mode

// Set the view mode to paginated
await meeting.participants.setViewMode("PAGINATED");

// Set the view mode to active grid
await meeting.participants.setViewMode("ACTIVE_GRID");