Skip to content

API Reference

Complete API documentation for MikroRoom’s HTTP REST endpoints and WebSocket signaling protocol.

  • Development: http://localhost:3000
  • Production: https://yourdomain.com

Check server health and statistics.

GET /health

Response (200 OK):

{
"status": "ok",
"totalRooms": 5,
"totalParticipants": 12,
"peakParticipants": 24,
"uptime": 3600000,
"version": "1.0.0"
}

Fields:

  • status - Server status ("ok")
  • totalRooms - Current active rooms
  • totalParticipants - Current connected participants
  • peakParticipants - Peak participants since server start
  • uptime - Server uptime in milliseconds
  • version - MikroRoom version

Get ICE server configuration for WebRTC.

GET /config

Response (200 OK):

{
"iceServers": [
{ "urls": "stun:stun.cloudflare.com:3478" },
{
"urls": "turn:turn.yourdomain.com:3478",
"username": "mikroroom",
"credential": "password"
}
]
}

Fields:

  • iceServers - Array of STUN/TURN server configurations

Pre-create a room with optional password.

POST /api/rooms
Content-Type: application/json
{
"roomId": "ABC123",
"password": "secret",
"maxParticipants": 8
}

Request Body (all fields optional):

  • roomId - Custom room ID (6 alphanumeric characters)
  • password - Room password for entry
  • maxParticipants - Maximum participants (default: 8)

Response (201 Created):

{
"roomId": "ABC123",
"creatorToken": "550e8400-e29b-41d4-a716-446655440000"
}

Fields:

  • roomId - The created room ID
  • creatorToken - Token for creator privileges (bypass waiting room, become host)

Error Responses:

429 Too Many Requests (rate limit exceeded):

{
"error": "Too many requests. Please try again later."
}

429 Too Many Requests (room limit reached):

{
"error": "Cannot create room. Limit reached or room ID already exists."
}

400 Bad Request (invalid request):

{
"error": "Invalid request body"
}

Connect to WebSocket endpoint for signaling.

const ws = new WebSocket('wss://yourdomain.com/ws');

Endpoint: /ws

All messages are JSON with this base structure:

{
"type": "message-type",
"roomId": "ABC123",
"participantId": "participant-uuid",
"timestamp": 1234567890
}

Messages sent from client to server.

Join or create a meeting room.

{
"type": "join",
"roomId": "ABC123",
"participantId": "",
"name": "John Doe",
"password": "secret",
"isHost": false,
"creatorToken": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": 1234567890
}

Fields:

  • name - Participant’s display name
  • password - Room password (if required)
  • isHost - True if creating new room
  • creatorToken - Creator token from /api/rooms (optional)

Response: Server sends participant-joined message.

Leave the current room.

{
"type": "leave",
"roomId": "ABC123",
"participantId": "your-uuid",
"timestamp": 1234567890
}

Send WebRTC offer to peer.

{
"type": "offer",
"roomId": "ABC123",
"participantId": "your-uuid",
"targetId": "peer-uuid",
"sdp": "v=0\r\no=- ...",
"timestamp": 1234567890
}

Fields:

  • targetId - Recipient participant ID
  • sdp - WebRTC SDP offer

Send WebRTC answer to peer.

{
"type": "answer",
"roomId": "ABC123",
"participantId": "your-uuid",
"targetId": "peer-uuid",
"sdp": "v=0\r\no=- ...",
"timestamp": 1234567890
}

Fields:

  • targetId - Recipient participant ID
  • sdp - WebRTC SDP answer

Send ICE candidate to peer.

{
"type": "ice-candidate",
"roomId": "ABC123",
"participantId": "your-uuid",
"targetId": "peer-uuid",
"candidate": {
"candidate": "candidate:...",
"sdpMid": "0",
"sdpMLineIndex": 0
},
"timestamp": 1234567890
}

Fields:

  • targetId - Recipient participant ID
  • candidate - ICE candidate object

Send text message to room.

{
"type": "chat",
"roomId": "ABC123",
"participantId": "your-uuid",
"text": "Hello everyone!",
"replyTo": "message-id",
"timestamp": 1234567890
}

Fields:

  • text - Message text
  • replyTo - ID of message being replied to (optional)

Update own audio/video state.

{
"type": "participant-updated",
"roomId": "ABC123",
"participantId": "your-uuid",
"isMuted": true,
"isVideoOff": false,
"isHandRaised": false,
"timestamp": 1234567890
}

Fields:

  • isMuted - Audio muted state
  • isVideoOff - Video disabled state
  • isHandRaised - Hand raised state

Raise hand for attention.

{
"type": "raise-hand",
"roomId": "ABC123",
"participantId": "your-uuid",
"timestamp": 1234567890
}

Lower raised hand.

{
"type": "lower-hand",
"roomId": "ABC123",
"participantId": "your-uuid",
"timestamp": 1234567890
}

Perform moderator actions (requires moderator privilege).

{
"type": "moderator-action",
"roomId": "ABC123",
"participantId": "your-uuid",
"targetId": "target-uuid",
"action": "mute",
"timestamp": 1234567890
}

Actions:

  • mute - Mute participant
  • unmute - Unmute participant
  • kick - Remove participant from room
  • make-moderator - Grant moderator privileges

Lock room to require moderator approval (moderator only).

{
"type": "room-locked",
"roomId": "ABC123",
"participantId": "your-uuid",
"timestamp": 1234567890
}

Unlock room (moderator only).

{
"type": "room-unlocked",
"roomId": "ABC123",
"participantId": "your-uuid",
"timestamp": 1234567890
}

Admit user from waiting room (moderator only).

{
"type": "admit-user",
"roomId": "ABC123",
"participantId": "your-uuid",
"targetId": "waiting-user-uuid",
"timestamp": 1234567890
}

Reject user from waiting room (moderator only).

{
"type": "reject-user",
"roomId": "ABC123",
"participantId": "your-uuid",
"targetId": "waiting-user-uuid",
"reason": "Room is full",
"timestamp": 1234567890
}

Messages sent from server to client.

New participant joined the room.

{
"type": "participant-joined",
"roomId": "ABC123",
"participantId": "new-participant-uuid",
"name": "Jane Doe",
"isModerator": false,
"isMuted": false,
"isVideoOff": false,
"timestamp": 1234567890
}

Fields:

  • participantId - New participant’s ID
  • name - Participant’s display name
  • isModerator - Moderator status
  • isMuted - Audio state
  • isVideoOff - Video state

Participant left the room.

{
"type": "participant-left",
"roomId": "ABC123",
"participantId": "departed-uuid",
"timestamp": 1234567890
}

Participant’s state changed.

{
"type": "participant-updated",
"roomId": "ABC123",
"participantId": "participant-uuid",
"isMuted": true,
"isVideoOff": false,
"isHandRaised": false,
"timestamp": 1234567890
}

User is in waiting room or new user waiting.

{
"type": "waiting-room",
"roomId": "ABC123",
"participantId": "waiting-uuid",
"name": "Waiting User",
"timestamp": 1234567890
}

Server error message.

{
"type": "error",
"roomId": "",
"participantId": "",
"message": "Room is full",
"code": "ROOM_FULL",
"timestamp": 1234567890
}

Error Codes:

  • ROOM_FULL - Room has reached max participants
  • INVALID_PASSWORD - Incorrect room password
  • ROOM_NOT_FOUND - Meeting doesn’t exist
  • UNAUTHORIZED - Action requires moderator privileges

Rate limits per IP address:

  • WebSocket connections: 10 per minute
  • Room creation: 10 per minute

Response on limit exceeded:

  • WebSocket: Connection closed
  • HTTP: 429 status code

MikroRoom allows cross-origin requests:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type

For production, configure specific origins in reverse proxy.

MikroRoom includes security headers:

X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
// Connect to WebSocket
const ws = new WebSocket('wss://yourdomain.com/ws');
// Join room
ws.send(JSON.stringify({
type: 'join',
roomId: 'ABC123',
participantId: '',
name: 'John Doe',
timestamp: Date.now()
}));
// Handle messages
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
switch (message.type) {
case 'participant-joined':
console.log(`${message.name} joined`);
break;
case 'chat':
console.log(`${message.participantId}: ${message.text}`);
break;
case 'error':
console.error(message.message);
break;
}
};
// Send chat
ws.send(JSON.stringify({
type: 'chat',
roomId: 'ABC123',
participantId: 'your-uuid',
text: 'Hello!',
timestamp: Date.now()
}));