Tier 1

Just The Basics

Working in minutes
1

Zero-config WebRTC setup

Drop in one script tag (or one ESM import) and call init(). STUN/TURN servers, ICE negotiation, signaling — all handled invisibly. Your app never touches a socket directly.

// Option A — ESM (recommended) import VibeLive from 'https://makedo.com/sdk/makedo-vibelive.esm.min.js'; VibeLive.init({ projectId: 'YOUR_TRIAL_PROJECT_ID' }); // Option B — IIFE (no import needed) // <script src="https://makedo.com/sdk/makedo-vibelive.min.js" onload="initApp()"></script>
2

Anonymous video conferences

Anyone can join with just a name and a room code — no accounts, no passwords, no OAuth flows. Perfect for lightweight embed scenarios and quick prototypes.

VibeLive.init({ projectId: '...' }); await VibeLive.signup('Alice'); // anonymous — no email needed const room = await VibeLive.createRoom('My Room'); // share room.room_code with participants await VibeLive.enterByRoomCode(room.room_code);
3

Go Live / stop streaming

Entering a room puts you in PRE-LIVE — camera preview is available but no WebRTC connection is open yet. Call startLive() when the user is ready to broadcast. The two-step design lets you build waiting rooms, lobby screens, and "ready" confirmations naturally.

VibeLive.startLive(); // connect WebRTC → LIVE VibeLive.stopLive(); // disconnect → back to PRE-LIVE
4

Camera & microphone toggles

One-line on/off for camera and mic. The SDK distinguishes between off (hardware released) and muted (track silenced but still capturing), giving your UI the full signal it needs for accurate indicators.

VibeLive.setVideo(true); // camera on VibeLive.setVideo(false); // camera off (hardware released) VibeLive.setAudio(true); // mic on VibeLive.setAudio(false); // mic off
5

Multi-user concurrent screensharing

Any member — not just the host — can share their screen at the same time. Each screenshare arrives as its own independent stream tile, so multiple screens can be visible simultaneously.

VibeLive.setScreenshare(true); // start sharing your screen VibeLive.setScreenshare(false); // stop sharing // Remote screenshares arrive via: VibeLive.on('remoteStreamStart', (memberId, streamType) => { /* streamType === 'screenshare' */ });
Tier 2

Rooms & Member Awareness

Real-time state, tiles, presence
6

Lobby / PRE-LIVE staging

Members enter a staging area with camera preview before WebRTC connects. Build waiting rooms, "knock to enter" flows, or device-check screens — all without any streaming cost until startLive() is called.

// enterByRoomCode → PRE-LIVE. Camera/mic available, no WebRTC yet. VibeLive.on('channelSelected', (channel) => { showLobbyUI(); // create local tile, show preview }); VibeLive.on('localJoined', () => { showLiveControls(); }); VibeLive.on('localLeft', () => { showLobbyUI(); });
7

Real-time member state

One unified event carries every member's full state — live status, camera, mic, and screenshare — for both local and remote members. Drive all your indicators, placeholders, and visibility from a single event handler. No polling, no duplicated logic.

VibeLive.on('memberStateChange', (memberId, state) => { // state: { live, video: 'ON'|'MUTED'|'OFF', audio: '...', screenVideo: '...' } updateIndicators(memberId, state); }); // Also available synchronously: const state = VibeLive.getMemberState(memberId);
8

Automatic tile lifecycle

Register a tile element once and the SDK handles everything: stream attachment, member exit cleanup, screenshare end, room leave, and kick. Tiles are auto-removed from the DOM — your code never needs a teardown path for remote media.

// Register once after creating your tile element: VibeLive.registerTile(memberId, 'camera', tileElement); VibeLive.registerTile(memberId, 'screenshare', tileElement); // SDK auto-finds <video> inside, attaches srcObject, removes on exit. // Opt-out: keep the element for a fade/exit animation, then clean up manually. VibeLive.init({ projectId, tileAutoRemove: false }); // SDK stops the stream but skips element.remove(). Call unregisterTile() when done.
9

Member directory

Fetch display names and statuses for everyone in the room. Use this to populate a participants list, name labels on tiles, or a roster sidebar — with one async call after entering.

const members = await VibeLive.getMembers(); // → [{ id, displayName, displayStatus }, ...] const one = VibeLive.getMember(memberId); // → { displayName, displayStatus } (synchronous, from local cache)
10

Network quality monitoring

Advanced

Opt-in per-connection quality scoring — good / fair / poor / lost — derived from RTT, jitter, packet loss, and freeze rate. Fires events when quality changes for you or for any remote member. Can auto-render a status bar on affected tiles with no extra code.

VibeLive.init({ projectId: '...', features: { connectionQuality: true, // enable events + getters showMemberQuality: true, // auto-render bar on remote tiles showLocalQuality: true, // auto-render bar on your own tile } }); VibeLive.on('memberQuality', (memberId, s) => { // s: { level: 'poor', reason: 'audio-loss', metrics: { ... } } showQualityBadge(memberId, s.level); });
11

Host can remove members

Advanced

The host can kick any member from the room. The SDK surfaces the event cleanly on the removed member's end so your app can show a message and clean up gracefully.

// On the removed member's device: VibeLive.on('kicked', (error) => { alert(error?.message || 'You were removed from this room.'); VibeLive.exitRoom(); }); // Kick API available to hosts via VibeLive console or server-side call
12

Sound effects on member join / exit

Play chimes, notification sounds, or custom audio cues when members arrive or leave — just hook your own AudioContext into the SDK's presence events.

VibeLive.on('remoteJoined', (memberId) => { playChime('join'); }); VibeLive.on('remoteLeft', (memberId) => { playChime('exit'); });
Tier 3

Communication

Text chat, messaging, DMs, availability & invites
13

Persistent channel text chat

Send messages to the whole room — backed by the database, so history survives after the session ends. Fetch past messages by page and display them in chronological order.

const channelId = VibeLive.channel?.id; await VibeLive.sendMessage(channelId, 'Hello everyone!'); const history = await VibeLive.getMessages(channelId, { count: 20, page: 0 }); // → [{ pid, content, content_type, owner_id, owner_username, // sender_member_id, sender_display_name, // target_type, target_id, uts }, ...] newest-first
14

Real-time message push

Incoming messages from other members arrive instantly over the SDK's WebSocket — no polling required. Register one handler and it fires for both channel-wide messages and private DMs addressed to you.

VibeLive.setOnMessage((msg) => { // msg: { pid, content, content_type, owner_id, owner_username, // sender_member_id, sender_display_name, target_type, target_id, uts } appendToChat(msg); });
15

Private member-to-member DMs

Send and retrieve private messages between two members — scoped to their shared channel. Threads are persistent and paginated, separate from channel-wide chat.

// Send privately to one member: await VibeLive.sendMessage(channelId, 'Hey, just you', memberId); // Fetch the private thread: const thread = await VibeLive.getMessages(channelId, { memberId, count: 20 });
16

Per-tile private DM UI (zero-code)

One flag at room creation injects a complete, ready-made DM interface directly onto every remote camera tile — chat toggle, slide-out input, conversation history, live updates. No additional app code required.

const room = await VibeLive.createRoom('Standup', { enableTileMessaging: true }); // Every remote camera tile now has a 💬 button built-in. // Works alongside your own sendMessage() / setOnMessage() UI — no conflict.
17

Project-wide availability signal

Coming Soon

Let users broadcast that they're open to connect right now — scoped to a project context, with a configurable TTL and optional profile hints. Other users in the same project can list who's available and reach out via invite. Updates are pushed over WebSocket as availabilityUpdate events (added / changed / removed) — no polling. Optional role and attributes fields feed pluggable matchmaking strategies (see feature 19a).

await VibeLive.setAvailable({ open: true, ttlSeconds: 3600, useProfile: '', seeking: '', role: 'customer', attributes: { age_bucket: '25-34' } // optional, for matchmaking }); const open = await VibeLive.getAvailableUsers({ count: 20 }); // → [{ user_id, username, availability: { open, ttlEndMs, seeking, role, attributes, ... } }, ...] VibeLive.on('availabilityUpdate', (upd) => { /* upd.type: 'added' | 'changed' | 'removed' */ });
18

Direct invites to a room

Coming Soon

Invite a specific user to a room you own. They receive a real-time inviteReceived event with a TTL and message; you receive an inviteResponse when they accept, decline, or let it expire. On accept, the SDK can auto-enter them into the room.

// Sender: await VibeLive.sendInvite({ channel_id, user_id, message: 'join me?', ttlSeconds: 120 }); VibeLive.on('inviteResponse', ({ status, member_id }) => { /* accepted | declined | expired */ }); // Recipient: VibeLive.on('inviteReceived', async (invite) => { await VibeLive.acceptInvite({ member_id: invite.member_id }); // auto-enters room });
19

One-shot room creation with invites

Coming Soon

Create a fresh room and invite a list of users in a single call. Each invitee receives the same inviteReceived event and can accept independently — handy for one-tap "start a chat with these people" flows.

const room = await VibeLive.createRoomWithInvites({ title: 'Coffee chat', invites: [ { user_id: 'u_abc', message: 'free now?', ttlSeconds: 120 }, { user_id: 'u_def' } ] });
19a

Server-side auto-match (autoInvite)

Coming Soon

When a project flips autoMatchEnabled=true, the server becomes a producer of invites: any user who calls setAvailable({ open: true }) enters a project-scoped pool and the matchmaker pairs them up automatically. Each invitee gets the same inviteReceived event used for manual invites, with an extra match block describing the strategy and peers — so existing invite-aware apps light up with zero code changes. Pluggable strategies (random_pair ships; bucketed / role-aware to follow) read each user's optional role and attributes declared via setAvailable or init({ autoMatch }).

// One-time per-app: declare role + tags that the matchmaker can read. VibeLive.init({ projectId, autoMatch: { role: 'customer', attributes: { topic: 'support' } } }); await VibeLive.setAvailable({ open: true }); // pool entry; server matches & invites VibeLive.on('inviteReceived', (inv) => { if (inv.match) { // auto-matched — inv.match = { strategy, reason, peers, metadata } /* render "Match found: Alice" prompt */ } }); // Server enable (project-level, jsonb config on the context row): // autoMatchEnabled = "true" // autoMatchStrategy = "random_pair" (default) // autoMatchMaxSize = "2" (clamped 2..8)
19b

Decline cooldowns

Coming Soon

When a user declines an invite, the matchmaker records a short cooldown between the decliner and every other invitee/inviter in that room, so the same pair isn't re-matched on the next pool tick. Cooldowns are pair-symmetric, project-scoped, and TTL'd. Discovery is unaffected — declined users still appear in getAvailableUsers and can be invited manually. Applies to both auto-matched and hand-sent invites.

// Server config (jsonb on the context row): // autoMatchDeclineCooldownSeconds = "300" // default 5 min; clamp 1..86400 // Behavior is transparent to apps — no SDK change needed. Decliners // remain in the availability pool; only auto-pairing is suppressed.
19c

Auto-matchmaking of available users

Coming Soon

When two or more users in a project context are simultaneously available, the server can automatically create a room and invite them — no app code required. Group size is configurable (2–8). Gated behind a project config flag so it stays off by default.

// Project config (set via console or admin API): // autoMatchEnabled: true // autoMatchMaxSize: 2 // capped at 2..8 // When N available users are detected, server creates a room // and emits 'inviteReceived' to each. Standard invite API handles the rest.
Tier 4

Security

Codes, keys, domains, whitelists
20

Room codes — private by default

Every room gets a short, shareable code on creation. Only people with the code can enter. Share it however you like — link, QR code, email — and revoke access by rotating the code from your console.

const room = await VibeLive.createRoom('Team Sync'); console.log(room.room_code); // e.g. "XK3B" // Participants join with: await VibeLive.enterByRoomCode('XK3B');
21

Idle member cleanup & liveness checks

The server automatically removes members who go silent for too long (~5 minutes). Your app can intercept the liveness check to prompt the user and keep their session alive.

VibeLive.on('livelinessCheck', () => { // Optional: prompt user, then ack if (confirm('Still there?')) VibeLive.ackLiveliness(); // Safe to omit entirely — server auto-removes after timeout. });
22

Domain origin restrictions

Coming Soon

Lock your project key so it only works when embedded on specific domains. Prevents your project from being used by other sites even if someone extracts your key from the source.

// Configured via VibeLive developer console → Project Settings → Allowed Origins // e.g. https://yourapp.com, https://staging.yourapp.com
23

Email verification for users

Coming Soon

Require users to verify a real email address before entering a room — independently of whether that address is whitelisted. Use this when you want identity accountability without restricting who can join. Fully anonymous entry (allowsGuests) and email-verified entry are separate, combinable settings.

// Console: Project / Room Settings → Require Email Verification // Users without a verified email are redirected to verify before entry. // Compatible with open rooms (no whitelist) or whitelisted rooms.
24

Email whitelists

Coming Soon

Restrict room entry to a pre-approved list of email addresses or domains. Only users whose verified email matches the whitelist can join, keeping rooms closed to uninvited participants.

// Console: Room Settings → Email Whitelist → Add addresses or domains // Supports individual addresses (user@co.com) and domain wildcards (@co.com)
25

Project key rotation

Coming Soon

Rotate your project's API key without downtime. Old keys expire on a configurable grace period so you can update your deploys before access is revoked.

// Console: Project Settings → Rotate Key // New key issued; old key valid for N hours (configurable)
Tier 5

Access Control & Configuration

Hierarchical config, multi-room, advanced use
26

Account / project / room config hierarchy

Enable or disable features at any scope. Room-level settings override project defaults; project defaults override account defaults. Configure text chat, anonymous entry, room creation permissions, domain restrictions, tile messaging, and more without touching code.

// Example config keys (set via console or createRoom options): // enableTileMessaging — per-tile DM UI // allowsGuests — anonymous (no-email) member entry // requireCode — enforce room code on join // domainRestrictions — allowed embedding origins // enableRoomCreation — whether non-host members can createRoom()
26a

Create a room with options

Coming Soon

createRoom(title, options) accepts a full set of options that control who can enter, how long sessions run, and which features are active. Flat DB columns (allowsGuests, maxSize) apply immediately; config flags are stored as room-level JSONB that cascades from room → project → default. Omit any option to inherit the project-level default.

const room = await VibeLive.createRoom('My Room', { // Flat DB columns allowsGuests: true, // allow anonymous (no-email) entry maxSize: 12, // max simultaneous members // Session lifecycle statusOnMeetingEnd: 'open', // 'open' | 'closed' | 'pending' | 'disabled' | 'archived' maxLength: 60, // session cap in minutes (cannot exceed plan limit) // Feature flags (cascade: room → project → default) enableTileMessaging: false, enableTextChat: true, allowScreensharing: true, allowLurkers: false, allowFileSharing: false, useEmailWhitelist: false, // coming soon }); // → { id, room_code, title }
26b

Configure rooms — full option reference

Coming Soon

All createRoom() options, their storage layer, cascade path, and current status. Flat DB columns take effect immediately on the channels row. JSONB config keys cascade room → project → hardcoded default, so omitting an option inherits the project-level setting without any extra work.

// ── Flat DB columns ──────────────────────────────────────────────────────── // Option Type Default Notes // allowsGuests boolean true Allow anonymous (no-email) entry // maxSize integer 8 Max simultaneous members in room // ── JSONB config (cascade: room → project → default) ─────────────────────── // Option Type Default Notes // statusOnMeetingEnd string 'open' Room status once last member exits or // session is force-ended. One of: // 'open' | 'closed' | 'pending' | // 'disabled' | 'archived' // maxLength integer — Session cap in minutes. Cannot exceed // plan-tier ceiling. No limit if absent. // enableTileMessaging boolean false SDK per-tile DM UX on camera tiles // enableTextChat boolean true Text chat sidebar // allowScreensharing boolean true Screen-share button visible & functional // allowLurkers boolean false Members may join without publishing media // hideWatermark derived Hidden automatically when project owner sub_status = builder // allowFileSharing boolean false Allow members to share files in room // ── Coming soon ──────────────────────────────────────────────────────────── // useEmailWhitelist boolean false Restrict entry to whitelisted emails
27

Limit room creation to hosts

Coming Soon

Prevent guests and standard members from creating new rooms. Only project managers or designated hosts can spin up rooms — useful for controlled event or classroom deployments.

// Console: Project Settings → Room Creation → Hosts only // createRoom() will reject with PERMISSION_DENIED for non-host members
28

Per-member feature permissions

Coming Soon

Restrict screensharing or video broadcasting to specific members only. Host a panel discussion where only speakers can share video while viewers watch — with the same SDK on both ends.

// Per-member flags (future API): // member.canVideo — allowed to broadcast camera // member.canScreenshare — allowed to screenshare // Violations return PERMISSION_DENIED on setVideo() / setScreenshare()
29

Room & user directory

Coming Soon

Account owners can retrieve lists of their rooms and users — either as client-side JS calls (within an authenticated session) or via server-side API calls using their project key. Useful for building admin dashboards, room pickers, and member management UIs.

// Client-side (authenticated session): const rooms = await VibeLive.getRooms(); // → [{ id, title, room_code, member_count, created_at }, ...] const users = await VibeLive.getUsers(); // → [{ id, username, display_name, last_seen }, ...] // Server-side: GET /api/v1/rooms (Authorization: Bearer PROJECT_KEY) // GET /api/v1/users (Authorization: Bearer PROJECT_KEY)
30

Independent multi-room instances

Advanced

Run multiple independent room connections on the same page simultaneously — each with its own state, event handlers, and tile set. Useful for monitoring dashboards, sidebars, and multi-feed layouts.

const room1 = VibeLive.createInstance({ projectId: '...' }); const room2 = VibeLive.createInstance({ projectId: '...' }); await room1.signup('Alice'); await room1.enterByRoomCode('AAA1'); await room2.signup('Alice'); await room2.enterByRoomCode('BBB2');
31

Device selection

Advanced

Let users choose which camera and microphone to use from all available devices — essential for multi-camera setups, external mics, and accessibility requirements.

const devices = await VibeLive.getDevices(); // → { cameras: [...], microphones: [...] } await VibeLive.setCamera(deviceId); await VibeLive.setMicrophone(deviceId);
32

React integration

Advanced

Use the SDK's event model cleanly inside React component lifecycle. Subscribe in useEffect, manage state with useState, and avoid the common ESM/IIFE scoping issues that trip up React setups.

// useEffect cleanup pattern: useEffect(() => { VibeLive.on('memberStateChange', handleState); return () => VibeLive.off('memberStateChange', handleState); }, []);
Tier 6

Platform & Reporting

Capacity, analytics, AI features
34

Up to 12 members, up to 24-hour sessions

Rooms support up to 12 concurrent live members and stay active for up to 24 hours without reconnecting. Members can freely join and leave within that window.

// No configuration needed — enforced automatically per project plan.
35

Watermark / branding control

Coming Soon

Remove the "Powered by VibeLive" overlay on paid plans. Replace it with your own branding, or suppress it entirely for white-label deployments.

// Builder plan: watermark suppressed automatically // Or configure via: VibeLive.init({ projectId, showWatermark: false })
36

Console activity views & reporting

Coming Soon

See who joined each room, when, how long they stayed, and what they did — from the VibeLive developer console without writing any logging code yourself.

// Developer console → Project → Activity // Exportable as CSV; also accessible via server-side reporting API
37

File sharing

Coming Soon

Share files directly within a room — stored and accessible to all room members. Rooms become a lightweight document exchange layer alongside the video stream.

// Future API (aspirational): // await VibeLive.uploadFile(channelId, file); // const files = await VibeLive.getFiles(channelId);
38

Background music

Coming Soon

Mix ambient audio or background music into the outgoing stream — useful for meditation sessions, virtual events, and waiting room experiences.

// Future API (aspirational): // await VibeLive.setBackgroundAudio(audioBuffer, { volume: 0.3, loop: true });
39

Transcription & meeting summaries

Coming Soon

Automatically transcribe meetings and generate AI summaries — retrievable after the session ends via the messages API or a dedicated transcript endpoint.

// Future API (aspirational): // const transcript = await VibeLive.getTranscript(channelId); // const summary = await VibeLive.getSummary(channelId);
40

Sub-interval extraction

Coming Soon

Tag named segments within a meeting (agenda items, topics, breaks) and extract per-interval summaries and transcripts after the fact. Useful for long standup calls, interviews, and structured workshops.

// Future API (aspirational): // await VibeLive.startInterval('Q3 Planning'); // await VibeLive.endInterval(); // const intervals = await VibeLive.getIntervals(channelId);
41

Test / mock mode

Coming Soon

Simulate multiple remote members joining, speaking, and leaving — with no real devices or network — so you can build and test your UI without a second browser or person.

// Future API (aspirational): // VibeLive.init({ projectId, testMode: true }); // VibeLive.simulateJoin('MockUser1'); // VibeLive.simulateStateChange('MockUser1', { video: 'ON', audio: 'MUTED' });
42

Starter & Builder plans

Coming Soon

Tiered access unlocks features progressively. Starter covers core video, text chat, and room management. Builder adds watermark removal, domain restrictions, key rotation, reporting, and AI features.

// Features gated by plan are clearly marked in this guide. // Upgrade at vibelive.site → Account → Plan.