Skip to main content

Join a Room from a Client

Learn how to install a VideoSDK client SDK, authenticate with an access token, join a room, respond to participant and media events, and handle leaving or reconnecting.

If you want to understand how roomId and access tokens work before implementing the client flow, see How a client connects to VideoSDK.

Install the SDK

Choose the SDK for your platform.

npm install @videosdk.live/react-sdk

For the complete setup, see the React quick start.

Server SDKs for Node.js, Go, and Rust run on your backend. The Python SDK is used for AI agents. See Server SDK and AI agents.

Generate an access token

Before a client can join a room, your backend must generate an access token.

The token determines which room and participant the client can connect as, and which permissions they receive.

For an explanation of token grants, see How a client connects to VideoSDK.

There is no REST endpoint that generates a token. Sign the JWT on your server using your VideoSDK API key and secret.

const jwt = require("jsonwebtoken");
const { v4: uuid } = require("uuid");

const token = jwt.sign(
{
apikey: process.env.VIDEOSDK_API_KEY,
permissions: ["allow_join"],
roomId,
participantId: "user-123",
},
process.env.VIDEOSDK_SECRET,
{
algorithm: "HS256",
expiresIn: "2h",
jwtid: uuid(),
}
);

For development, you can generate a temporary token from the VideoSDK dashboard.

For complete token configuration, including payload fields, permissions, and alternative signing methods, see Authentication and tokens.

Join a room

To join, provide:

  • The roomId.
  • The access token generated by your backend.
  • A display name.
  • Whether the microphone starts enabled.
  • Whether the camera starts enabled.

You can also provide your own participantId so it maps to a user in your application. If you omit it, VideoSDK generates one automatically.

import {
MeetingProvider,
useMeeting,
} from "@videosdk.live/react-sdk";

function App() {
return (
<MeetingProvider
config={{
meetingId: roomId,
name: "C.V. Raman",
micEnabled: true,
webcamEnabled: true,
}}
token={token}
>
<MeetingView />
</MeetingProvider>
);
}

function MeetingView() {
const {
join,
localParticipant,
participants,
} = useMeeting({
onMeetingJoined: () => {
console.log("joined");
},
});

return (
<button onClick={() => join()}>
Join
</button>
);
}

Set joinWithoutUserInteraction on MeetingProvider if you want the participant to join automatically instead of explicitly calling join().

After joining:

  • localParticipant represents the current participant.
  • participants contains the remote participants, keyed by participant ID.
  • onParticipantJoined and onParticipantLeft report participant changes.
  • onPresenterChanged reports screen-share changes.
  • useParticipant(participantId) exposes onStreamEnabled and onStreamDisabled.

See Participant events, Media events, and Meeting events.

Respond to room changes

After joining, your application should listen for room events rather than repeatedly polling participant or media state.

The most commonly used events are:

EventUse it for
Participant joinedAdd the participant to your UI.
Participant leftRemove the participant from your UI.
Stream enabledRender newly published microphone, camera, or screen-share media.
Stream disabledRemove or update the corresponding media element.
Presenter changedUpdate the UI when screen sharing starts or stops.
Connection state changedShow connecting, connected, or reconnecting state.
ErrorHandle authentication, device, or SDK failures.

See Participant management and Stream management for detailed participant and media handling.

Leave a room

Call leave() when the local participant wants to disconnect.

The local client receives onMeetingLeft, while the remaining participants receive onParticipantLeft.

Use end() instead when you want to end the active session for everyone in the room.

leave();

Different exit conditions include a reason code so your application can distinguish between a normal departure and a forced or network-related disconnect.

ReasonCodeMeaning
WEBSOCKET_DISCONNECTED1001The socket disconnected, typically because a network interruption could not be recovered.
REMOVE_PEER1002A moderator or server removed the participant.
REMOVE_PEER_VIEWER_MODE_CHANGED1003The participant was removed because the viewer mode changed.
REMOVE_PEER_MEDIA_RELAY_STOP1004The participant was removed because a media relay stopped.
SWITCH_ROOM1005The participant switched to a different room.

Handle connection states

Use the SDK's connection-state events to keep your interface synchronized with the participant's connection to the room.

For React, onMeetingStateChanged reports the following states:

StateWhat it meansRecommended UI
CONNECTINGThe SDK is attempting to join the room.Show a connecting indicator.
CONNECTEDSignalling is established and the required media channels are active.Show the call interface.
RECONNECTINGThe network connection was interrupted or became unstable. The SDK is attempting to reconnect automatically.Show a reconnecting message while keeping the existing call layout visible.
DISCONNECTEDThe room connection has closed because the participant left or reconnection failed.Show the leave screen or a retry action.
FAILEDThe initial connection attempt failed.Show an error with a retry option.
const { meetingId } = useMeeting({
onMeetingStateChanged: ({ state }) => {
// "CONNECTING"
// "CONNECTED"
// "RECONNECTING"
// "DISCONNECTED"
// "FAILED"
},
});

Handle errors separately

Connection state and SDK errors represent different conditions and should be handled independently.

For example:

  • A temporary Wi-Fi interruption may move the meeting to RECONNECTING.
  • An invalid access token is reported through onError.
  • Camera or microphone failures are also reported through onError.

onError provides a code and message that you can use to determine the appropriate response.

See the error codes reference for the complete list.

Next steps