Skip to the content.
← Back to Home Documentation Index

API Reference

Complete reference for configuration, endpoints, and programmatic usage.


Table of Contents


Configuration

Server Configuration

Configuration is provided via environment variables:

1
2
3
4
# Basic configuration
export ADDR=:8080
export WS_ALLOWED_ORIGINS=localhost,yourdomain.com
export RTC_CONFIG_JSON='{"iceServers":[{"urls":"stun:stun.l.google.com:19302"}]}'

ICE/TURN Configuration

The RTC_CONFIG_JSON variable accepts a JSON object matching the RTCIceServer format:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
  "iceServers": [
    {
      "urls": ["stun:stun.l.google.com:19302"]
    },
    {
      "urls": ["turn:turn.example.com:3478"],
      "username": "user",
      "credential": "pass"
    }
  ],
  "iceTransportPolicy": "all",
  "bundlePolicy": "balanced"
}

Environment Variables

Variable Type Default Description
ADDR string :8080 HTTP server listen address
WS_ALLOWED_ORIGINS string * Comma-separated allowed origins. Use * for all
RTC_CONFIG_JSON JSON Public STUN ICE/TURN server configuration

ADDR

Specifies the network address for the HTTP server.

1
2
3
4
5
6
7
8
# IPv4 on all interfaces
ADDR=0.0.0.0:8080

# IPv6
ADDR=[::]:8080

# Unix socket (advanced)
ADDR=unix:/var/run/webrtc.sock

WS_ALLOWED_ORIGINS

Controls WebSocket origin validation.

1
2
3
4
5
6
7
8
# Single origin
WS_ALLOWED_ORIGINS=example.com

# Multiple origins
WS_ALLOWED_ORIGINS=localhost,example.com,app.example.com

# Allow all (development only)
WS_ALLOWED_ORIGINS=*

RTC_CONFIG_JSON

Configures WebRTC ICE/TURN servers.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Public STUN only (default)
export RTC_CONFIG_JSON='{"iceServers":[{"urls":"stun:stun.l.google.com:19302"}]}'

# With TURN server
export RTC_CONFIG_JSON='{
  "iceServers": [
    {"urls": "stun:stun.l.google.com:19302"},
    {
      "urls": "turn:turn.example.com:3478",
      "username": "webrtc",
      "credential": "secret"
    }
  ]
}'

HTTP Endpoints

Static Files

Method Path Description
GET / Main application (index.html)
GET /styles.css Stylesheet
GET /app.js Main JavaScript bundle
GET /app.*.js Modular JavaScript files

API Endpoints

Method Path Description
GET /healthz Health check endpoint
GET /ws WebSocket upgrade endpoint

Health Check

1
curl http://localhost:8080/healthz

Response: ok (HTTP 200)

Used by load balancers and monitoring systems.

WebSocket

1
const ws = new WebSocket('ws://localhost:8080/ws');

See Signaling Protocol for message format.


WebSocket Protocol

Connection

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
const ws = new WebSocket(`${protocol}//${window.location.host}/ws`);

ws.onopen = () => {
  // Connection established
};

ws.onmessage = (event) => {
  const message = JSON.parse(event.data);
  // Handle message
};

ws.onclose = () => {
  // Connection closed
};

ws.onerror = (error) => {
  // Handle error
};

Message Types

See Signaling Protocol for complete message specification.

Control Messages:

WebRTC Messages:

Error Messages:


JavaScript API

Global State

The frontend exposes a global state object:

1
2
3
4
5
// Read-only inspection
console.log(state.myId);        // Your client ID
console.log(state.roomId);      // Current room
console.log(state.roomState);   // 'idle' | 'connecting' | 'joined' | 'calling'
console.log(state.peers);       // Map of peer connections

Functions

Connection

1
2
3
4
5
// Join a room
connect(roomId, myId);

// Leave current room
disconnect();

Calling

1
2
3
4
5
6
7
8
// Call a peer
callPeer(peerId);

// Hang up on a peer
hangupPeer(peerId);

// Hang up all peers
hangupAll();

Media Controls

1
2
3
4
5
6
7
8
9
10
11
// Toggle mute
toggleMute();

// Toggle camera
toggleCamera();

// Start screen share
startScreenShare();

// Stop screen share
stopScreenShare();

Recording

1
2
3
4
5
// Start recording
startRecording();

// Stop recording (triggers download)
stopRecording();

Chat

1
2
// Send chat message to all connected peers
sendChat(text);

Events

Hook into application events:

1
2
3
4
5
6
// Listen for state changes (example pattern)
const originalSetState = setRoomState;
setRoomState = function(newState) {
  console.log('State changed:', newState);
  originalSetState(newState);
};

Limits and Performance

Server Limits

Limit Value Configurable
Max rooms 1000 No
Max clients per room 50 No
Max room ID length 64 chars No
Max client ID length 64 chars No
Message buffer size 64 No
Send timeout 2 seconds No
Max message size 1 MB No

Performance Characteristics

Metric Expected Value
Connection setup < 100ms (local)
Message relay latency < 10ms (same DC)
Concurrent rooms 1000
Total concurrent clients 50,000 (1000 × 50)
Memory per client ~50 KB
CPU usage (idle) Minimal
CPU usage (active) Low (mostly I/O)

Browser Limits

Browser Max Concurrent Peers Notes
Chrome ~50 Hardware dependent
Firefox ~50 Hardware dependent
Safari ~20 More conservative

Recommendation: For rooms > 10 participants, consider SFU architecture instead of Mesh.


Error Codes

See Signaling Protocol for protocol error codes.

HTTP Status Codes

Status Meaning
200 Success
400 Bad request (WebSocket)
403 Forbidden (origin not allowed)
426 Upgrade Required (WebSocket expected)
500 Internal server error

TypeScript Definitions

For TypeScript projects:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// types/webrtc.d.ts

interface Message {
  type: string;
  room?: string;
  from?: string;
  to?: string;
  sdp?: RTCSessionDescriptionInit;
  candidate?: RTCIceCandidateInit;
  members?: string[];
  code?: string;
  error?: string;
}

interface Peer {
  id: string;
  pc: RTCPeerConnection;
  polite: boolean;
  makingOffer: boolean;
  ignoreOffer: boolean;
  pendingCandidates: RTCIceCandidateInit[];
  dc?: RTCDataChannel;
}

interface AppState {
  myId: string;
  ws: WebSocket | null;
  roomId: string;
  roomState: 'idle' | 'connecting' | 'joined' | 'reconnecting' | 'calling';
  localStream: MediaStream | null;
  screenStream: MediaStream | null;
  usingScreen: boolean;
  muted: boolean;
  cameraOff: boolean;
  peers: Map<string, Peer>;
  recorder: MediaRecorder | null;
  recordedChunks: Blob[];
}