Livqeno Docs

Join your first room

Create a client from the mint response, join, publish media, and watch participants arrive.

Your backend has minted a token. This is everything the client does with it.

Connect and join

import { createRTCClient } from '@ravenkash/rtc';
 
// Whatever your own endpoint returns from raven.tokens.create().
const credentials = await fetch('/join-room', { method: 'POST' }).then((r) => r.json());
 
const client = createRTCClient(credentials);
const room = await client.join(credentials.roomId);

createRTCClient accepts the mint response directly — token, endpoint, iceServers and telemetryUrl are read from it and the rest ignored.

Pass the room id or its name — the token carries both and either matches. Pass anything else and you get ROOM_NOT_FOUND immediately, client-side, before a connection is attempted.

Publish media

await room.enableCamera();
await room.enableMicrophone();

Both return the LocalTrack they published, or undefined if the track was already on. Neither throws when the token lacks publish — the server refuses the publish and you get an error event, so check permissions when you mint rather than when you publish.

Listen for participants

room.on('participantJoined', (participant) => {
  console.log(`${participant.identity} joined`);
});
 
room.on('trackSubscribed', (track, participant) => {
  const el = track.attach();
  document.getElementById(participant.identity)?.append(el);
});
 
room.on('participantLeft', (participant) => {
  document.getElementById(participant.identity)?.replaceChildren();
});

trackSubscribed is the one that matters for rendering: it fires when a remote track is actually available to play, which is later than trackPublished.

All 17 room events are listed in Events.

Leave

await room.leave();

Stops local tracks, closes the connection, and tells the room. Call it on unmount or page-hide; a dropped socket is eventually cleaned up server-side, but an explicit leave means everyone else sees participantLeft at once.

Next steps