VDO.Ninja Developer API Sandbox

Your API Key: Loading...

Connecting...

Your Ninja Link: Loading...

You can append VDO.Ninja parameters to this link, treating it like a normal VDO.Ninja link.

Companion Module IFrame API Docs
WebSocket API
HTTP API
Server-Sent Events
HTTP POST
Camera Controls
MIDI Integration
Guest Controls
API Reference
WebSocket API Request Builder
Common Controls (WebSocket)
Layout Controls (WebSocket)

WebSocket API Code Example

JavaScript
// Connect to WebSocket API
const socket = new WebSocket("wss://api.vdo.ninja:443");

// Track connection state
socket.onopen = function() {
  console.log("Connected to VDO.Ninja API");
  // Join with your API ID
  socket.send(JSON.stringify({ "join": "YOUR_API_ID" }));
};

// Handle messages
socket.onmessage = function(event) {
  if (event.data) {
    const data = JSON.parse(event.data);
    console.log("Received:", data);
  }
};

// Reconnection logic (crucial for production)
socket.onclose = function() {
  console.log("Connection closed, attempting to reconnect...");
  setTimeout(() => {
    // Implement reconnection logic here
  }, 1000);
};

// Example commands
function sendCommand(action, value = null, value2 = null, target = null) {
  const msg = { action };
  if (value !== null) msg.value = value;
  if (value2 !== null) msg.value2 = value2;
  if (target !== null) msg.target = target;
  
  if (socket.readyState === WebSocket.OPEN) {
    socket.send(JSON.stringify(msg));
  } else {
    console.error("Socket not connected");
  }
}

// Command examples:
// sendCommand("mic", "toggle");
// sendCommand("camera", false);
// sendCommand("soloVideo", "toggle");
// sendCommand("layout", 2);

// Camera control examples:
// sendCommand("zoom", 0.1);              // Relative zoom in 10%
// sendCommand("zoom", 0.75, "abs");      // Absolute zoom to 75%
// sendCommand("pan", -0.1);              // Relative pan left 10%
// sendCommand("focus", 0.1);             // Relative focus far 10%
// sendCommand("focus", 0.5, "abs");      // Absolute focus to 50%

// For directors - target a guest:
// sendCommand("mic", "toggle", null, "1");          // Toggle guest 1's mic
// sendCommand("zoom", 0.1, null, "2");              // Zoom guest 2's camera in
HTTP GET API Request Builder
https://api.vdo.ninja/YOUR_API_ID/action/target/value
Common Controls (HTTP)
Group Controls (HTTP)

HTTP API Code Example

JavaScript
// HTTP GET API Example
function sendHTTPRequest(apiID, action, target = "null", value = "null") {
  // Construct URL
  const url = `https://api.vdo.ninja/${apiID}/${action}/${target}/${value}`;
  
  // Send request
  fetch(url)
    .then(response => {
      if (!response.ok) {
        throw new Error(`HTTP error! Status: ${response.status}`);
      }
      return response.text();
    })
    .then(data => {
      // Handle response (could be text or JSON)
      try {
        const jsonData = JSON.parse(data);
        console.log("Response JSON:", jsonData);
      } catch (e) {
        console.log("Response text:", data);
      }
    })
    .catch(error => {
      console.error("Error:", error);
    });
}

// Usage examples:
// sendHTTPRequest("YOUR_API_ID", "mic", "null", "toggle");
// sendHTTPRequest("YOUR_API_ID", "camera", "null", "false");
// sendHTTPRequest("YOUR_API_ID", "joinGroup", "null", "1");

// Camera control examples (relative adjustments only via HTTP):
// sendHTTPRequest("YOUR_API_ID", "zoom", "null", "0.1");    // Zoom in 10%
// sendHTTPRequest("YOUR_API_ID", "zoom", "null", "-0.1");   // Zoom out 10%
// sendHTTPRequest("YOUR_API_ID", "pan", "null", "-0.1");    // Pan left 10%
// sendHTTPRequest("YOUR_API_ID", "focus", "null", "0.1");   // Focus far 10%

// For directors targeting a specific guest
// sendHTTPRequest("YOUR_API_ID", "mic", "1", "toggle");     // Target guest in slot 1
// sendHTTPRequest("YOUR_API_ID", "zoom", "2", "0.1");       // Zoom guest 2's camera in
Server-Sent Events (SSE) Listener

SSE provides a one-way communication channel to receive events from VDO.Ninja without sending requests.

Disconnected

SSE API Code Example

JavaScript
// Server-Sent Events (SSE) Example
function connectToSSE(apiID) {
  // Create EventSource connection
  const eventSource = new EventSource(`https://api.vdo.ninja/sse/${apiID}`);
  
  // Connection opened
  eventSource.onopen = function() {
    console.log("SSE connection established");
  };
  
  // Listen for messages
  eventSource.onmessage = function(event) {
    try {
      const data = JSON.parse(event.data);
      console.log("SSE event:", data);
      
      // Handle different types of events
      if (data.type === "state_update") {
        // Handle state updates
        updateUI(data.state);
      } else if (data.type === "guest_joined") {
        // Handle guest joining
        console.log(`Guest joined: ${data.guestID}`);
      }
      // Add more event handlers as needed
      
    } catch (e) {
      console.error("Error parsing SSE event:", e);
    }
  };
  
  // Handle errors
  eventSource.onerror = function(error) {
    console.error("SSE connection error:", error);
    
    // Close connection
    eventSource.close();
    
    // Implement reconnection logic
    setTimeout(() => {
      console.log("Attempting to reconnect SSE...");
      connectToSSE(apiID);
    }, 3000);
  };
  
  // Return EventSource instance (for later disconnection if needed)
  return eventSource;
}

// Usage:
// const sseConnection = connectToSSE("YOUR_API_ID");
// 
// // To disconnect later:
// // sseConnection.close();
HTTP POST API Request Builder

The HTTP POST method supports all features including the value2 parameter for absolute camera positioning.

HTTP POST API Code Example

JavaScript
// HTTP POST API Example
function sendPOSTRequest(apiID, data) {
  // Construct URL
  const url = `https://api.vdo.ninja/${apiID}`;
  
  // Configure request
  const options = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
  };
  
  // Send request
  fetch(url, options)
    .then(response => {
      if (!response.ok) {
        throw new Error(`HTTP error! Status: ${response.status}`);
      }
      return response.json();
    })
    .then(data => {
      console.log("Response:", data);
    })
    .catch(error => {
      console.error("Error:", error);
    });
}

// Usage examples:
// sendPOSTRequest("YOUR_API_ID", {
//   action: "mic",
//   value: "toggle"
// });
//
// Camera control with absolute positioning:
// sendPOSTRequest("YOUR_API_ID", {
//   action: "zoom",
//   value: 0.75,
//   value2: "abs"  // Sets zoom to exactly 75%
// });
//
// Camera control with relative adjustments:
// sendPOSTRequest("YOUR_API_ID", {
//   action: "pan",
//   value: -0.1    // Pan left by 10%
// });
//
// sendPOSTRequest("YOUR_API_ID", {
//   action: "layout",
//   value: [
//     {"x":0,"y":0,"w":50,"h":100,"slot":0},
//     {"x":50,"y":0,"w":50,"h":100,"slot":1}
//   ]
// });
//
// For directors targeting a specific guest:
// sendPOSTRequest("YOUR_API_ID", {
//   action: "zoom",
//   target: "2", 
//   value: 0.1     // Zoom in guest 2's camera by 10%
// });
Camera Controls (PTZ)

Remote control compatible camera hardware using pan, tilt, zoom, focus, and exposure commands. Supports both relative and absolute positioning.

Zoom

Absolute Zoom (0-2x):
1.0x

Focus

Absolute Focus (0-1):
0.5

Pan & Tilt

Absolute Pan (-1 to +1):
0
Absolute Tilt (-1 to +1):
0

Exposure

Absolute Exposure (0-1):
0.5

Camera Presets

PTZ Controls Code Example

JavaScript
// Camera Control (PTZ) Example
function sendCameraCommand(apiID, action, value, value2 = null, target = null) {
  // Using WebSocket (preferred for responsive camera control)
  if (socket && socket.readyState === WebSocket.OPEN) {
    const command = { action, value };
    if (value2 !== null) command.value2 = value2;
    if (target !== null) command.target = target;
    
    socket.send(JSON.stringify(command));
  } 
  // Using HTTP POST (supports all features including value2)
  else {
    const url = `https://api.vdo.ninja/${apiID}`;
    const data = { action, value };
    if (value2 !== null) data.value2 = value2;
    if (target !== null) data.target = target;
    
    fetch(url, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data)
    })
    .then(response => response.json())
    .then(data => console.log("Response:", data))
    .catch(error => console.error("Error:", error));
  }
}

// RELATIVE ADJUSTMENTS (change from current position)
// sendCameraCommand("YOUR_API_ID", "zoom", 0.1);        // Zoom in by 10%
// sendCameraCommand("YOUR_API_ID", "zoom", -0.1);       // Zoom out by 10%
// sendCameraCommand("YOUR_API_ID", "focus", 0.1);       // Focus farther by 10%
// sendCameraCommand("YOUR_API_ID", "focus", -0.1);      // Focus nearer by 10%
// sendCameraCommand("YOUR_API_ID", "pan", -0.1);        // Pan left by 10%
// sendCameraCommand("YOUR_API_ID", "pan", 0.1);         // Pan right by 10%
// sendCameraCommand("YOUR_API_ID", "tilt", 0.1);        // Tilt up by 10%
// sendCameraCommand("YOUR_API_ID", "tilt", -0.1);       // Tilt down by 10%
// sendCameraCommand("YOUR_API_ID", "exposure", 0.1);    // Increase exposure by 10%
// sendCameraCommand("YOUR_API_ID", "exposure", -0.1);   // Decrease exposure by 10%

// ABSOLUTE POSITIONING (set to exact values)
// sendCameraCommand("YOUR_API_ID", "zoom", 1.5, "abs");      // Set zoom to 1.5x
// sendCameraCommand("YOUR_API_ID", "focus", 0.75, "abs");    // Set focus to 75%
// sendCameraCommand("YOUR_API_ID", "pan", 0, "abs");         // Center pan
// sendCameraCommand("YOUR_API_ID", "pan", -0.5, "abs");      // Pan 50% left
// sendCameraCommand("YOUR_API_ID", "tilt", 0.25, "abs");     // Tilt 25% up
// sendCameraCommand("YOUR_API_ID", "exposure", 0.8, "abs");  // Set exposure to 80%

// Camera presets using absolute positioning
function setCameraPreset(preset) {
  switch(preset) {
    case 1: // Center position
      sendCameraCommand("YOUR_API_ID", "zoom", 1.0, "abs");
      sendCameraCommand("YOUR_API_ID", "pan", 0, "abs");
      sendCameraCommand("YOUR_API_ID", "tilt", 0, "abs");
      break;
    case 2: // Wide shot
      sendCameraCommand("YOUR_API_ID", "zoom", 0.5, "abs");
      sendCameraCommand("YOUR_API_ID", "pan", 0, "abs");
      sendCameraCommand("YOUR_API_ID", "tilt", 0, "abs");
      break;
    case 3: // Close-up
      sendCameraCommand("YOUR_API_ID", "zoom", 2.0, "abs");
      sendCameraCommand("YOUR_API_ID", "pan", 0, "abs");
      sendCameraCommand("YOUR_API_ID", "tilt", 0, "abs");
      break;
  }
}

// Targeting a specific guest's camera (for directors)
// sendCameraCommand("YOUR_API_ID", "zoom", 0.1, null, "2");       // Zoom guest 2's camera in
// sendCameraCommand("YOUR_API_ID", "pan", -0.5, "abs", "1");      // Set guest 1's pan to 50% left
MIDI Integration

Control VDO.Ninja using MIDI controllers with various mapping options.

MIDI access not initialized
No MIDI message received

Default MIDI Mappings

VDO.Ninja supports several MIDI mapping schemes, which can be configured using the &midiHotkeys parameter.

Standard Mapping (&midiHotkeys=1)
  • G3: Toggle chat
  • A3: Toggle mic
  • B3: Toggle video
  • C4: Toggle screenshare
  • D4: Hangup
  • E4: Raise hand
  • F4: Toggle recording
  • G4: Director audio
  • A4: Director hangup
  • B4: Toggle speaker
Alternate Mapping (&midiHotkeys=2)
  • G1: Toggle chat
  • A1: Toggle mic
  • B1: Toggle video
  • C2: Toggle screenshare
  • D2: Hangup
  • E2: Raise hand
  • F2: Toggle recording
  • G2: Director audio
  • A2: Director hangup
  • B2: Toggle speaker
CC-Based Controls (&midiHotkeys=3)

Uses note C1 with different velocity values:

  • C1 + velocity 0: Toggle chat
  • C1 + velocity 1: Toggle mic
  • C1 + velocity 2: Toggle video
  • C1 + velocity 3: Toggle screenshare
  • C1 + velocity 4: Hangup
  • C1 + velocity 5: Raise hand
  • C1 + velocity 6: Toggle recording
  • C1 + velocity 7: Director audio
  • C1 + velocity 8: Director hangup
  • C1 + velocity 9: Toggle speaker
Advanced MIDI Controls

CC 110 Commands:

  • Value 20: Zoom in (+10%)
  • Value 21: Zoom out (-10%)
  • Value 22: Pan left (-10%)
  • Value 23: Pan right (+10%)
  • Value 24: Tilt up (+10%)
  • Value 25: Tilt down (-10%)
  • Value 26: Exposure up (+10%)
  • Value 27: Exposure down (-10%)
  • Value 28: Focus near (-10%)
  • Value 29: Focus far (+10%)
  • Value 30-32: Camera presets 1-3

CC 80-84 (Absolute Control):

  • CC80: Zoom (0-127 → 0-2x)
  • CC81: Pan (0-127 → -1 to +1)
  • CC82: Tilt (0-127 → -1 to +1)
  • CC83: Exposure (0-127 → 0-1)
  • CC84: Focus (0-127 → 0-1)

MIDI API Code Example

JavaScript
// MIDI Integration Example
function initializeMIDI() {
  // Check if Web MIDI API is supported
  if (!navigator.requestMIDIAccess) {
    console.error("Web MIDI API not supported in this browser");
    return Promise.reject("MIDI not supported");
  }
  
  // Request MIDI access
  return navigator.requestMIDIAccess({ sysex: false })
    .then(midiAccess => {
      console.log("MIDI Access granted");
      
      // Get MIDI inputs
      const inputs = midiAccess.inputs.values();
      const devices = [];
      
      // Setup devices
      for (let input = inputs.next(); input && !input.done; input = inputs.next()) {
        devices.push(input.value);
        setupMIDIDevice(input.value);
      }
      
      // Listen for device connection/disconnection
      midiAccess.onstatechange = function(e) {
        console.log("MIDI state change:", e.port.name, e.port.state);
      };
      
      return { midiAccess, devices };
    })
    .catch(error => {
      console.error("Failed to get MIDI access:", error);
      throw error;
    });
}

function setupMIDIDevice(inputDevice) {
  // Set up MIDI message handler
  inputDevice.onmidimessage = function(message) {
    // Extract MIDI data
    const command = message.data[0];
    const note = message.data[1];
    const velocity = message.data[2];
    
    console.log(`MIDI message - Command: ${command}, Note: ${note}, Velocity: ${velocity}`);
    
    // Handle Note On messages (144 = Note On, channel 1)
    if (command === 144 && velocity > 0) {
      handleNoteOn(note, velocity);
    }
    // Handle Note Off messages (128 = Note Off, channel 1)
    else if (command === 128 || (command === 144 && velocity === 0)) {
      handleNoteOff(note);
    }
    // Handle Control Change messages (176 = CC, channel 1)
    else if (command === 176) {
      handleControlChange(note, velocity);
    }
  };
}

function handleControlChange(cc, value) {
  // Map control change messages to actions
  
  // CC110 - Advanced commands
  if (cc === 110) {
    switch(value) {
      case 20: sendCommand("zoom", 0.1); break;           // Zoom in
      case 21: sendCommand("zoom", -0.1); break;          // Zoom out
      case 22: sendCommand("pan", -0.1); break;           // Pan left
      case 23: sendCommand("pan", 0.1); break;            // Pan right
      case 24: sendCommand("tilt", 0.1); break;           // Tilt up
      case 25: sendCommand("tilt", -0.1); break;          // Tilt down
      case 26: sendCommand("exposure", 0.1); break;       // Exposure up
      case 27: sendCommand("exposure", -0.1); break;      // Exposure down
      case 28: sendCommand("focus", -0.1); break;         // Focus near
      case 29: sendCommand("focus", 0.1); break;          // Focus far
      case 30: // Camera preset 1
        sendCommand("zoom", 1.0, "abs");
        sendCommand("pan", 0, "abs");
        sendCommand("tilt", 0, "abs");
        break;
      // Add more CC110 values as needed
    }
  }
  // CC80-84: Absolute camera controls
  else if (cc >= 80 && cc <= 84) {
    const normalizedValue = value / 127; // 0-1 range
    
    switch(cc) {
      case 80: // Zoom absolute (0-127 maps to 0-2x zoom)
        sendCommand("zoom", normalizedValue * 2, "abs");
        break;
      case 81: // Pan absolute (0-127 maps to -1 to +1)
        sendCommand("pan", (normalizedValue * 2) - 1, "abs");
        break;
      case 82: // Tilt absolute (0-127 maps to -1 to +1)
        sendCommand("tilt", (normalizedValue * 2) - 1, "abs");
        break;
      case 83: // Exposure absolute (0-127 maps to 0-1)
        sendCommand("exposure", normalizedValue, "abs");
        break;
      case 84: // Focus absolute (0-127 maps to 0-1)
        sendCommand("focus", normalizedValue, "abs");
        break;
    }
  }
}

// Helper function to convert MIDI note number to note name
function getNoteNameFromNumber(noteNumber) {
  const notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
  const octave = Math.floor(noteNumber / 12) - 1;
  const noteName = notes[noteNumber % 12];
  return noteName + octave;
}

// Usage:
// initializeMIDI()
//   .then(midi => console.log("MIDI ready with devices:", midi.devices))
//   .catch(error => console.error("MIDI setup failed:", error));
Guest Controls (Director Mode)

These controls allow directors to manage remote guests via the API.

Guest Mic Volume:
100

Guest Control Code Example

JavaScript
// Guest Control Example (Director Mode)
function controlGuest(apiID, target, action, value = null, value2 = null, method = "websocket") {
  if (method === "websocket") {
    // WebSocket method (supports all features including value2)
    if (socket && socket.readyState === WebSocket.OPEN) {
      const msg = {
        target: target,
        action: action
      };
      
      if (value !== null) msg.value = value;
      if (value2 !== null) msg.value2 = value2;
      
      socket.send(JSON.stringify(msg));
      console.log("Sent guest command via WebSocket:", msg);
    } else {
      console.error("WebSocket not connected");
    }
  } else if (method === "http") {
    // HTTP method (limited - no value2 support)
    const targetStr = target || "null";
    const valueStr = value !== null ? value : "null";
    const url = `https://api.vdo.ninja/${apiID}/${action}/${targetStr}/${valueStr}`;
    
    fetch(url)
      .then(response => response.text())
      .then(data => console.log("Guest command response:", data))
      .catch(error => console.error("Error sending guest command:", error));
  }
}

// Basic guest control examples:
// controlGuest("YOUR_API_ID", "1", "mic", "toggle");      // Toggle mic for guest 1
// controlGuest("YOUR_API_ID", "2", "camera", false);      // Turn off camera for guest 2
// controlGuest("YOUR_API_ID", "3", "addScene", 1);        // Add guest 3 to scene 1
// controlGuest("YOUR_API_ID", "1", "sendDirectorChat", "You're live in 10 seconds");
// controlGuest("YOUR_API_ID", "2", "volume", 85);         // Set guest 2 volume to 85%
// controlGuest("YOUR_API_ID", "4", "forward", "room123"); // Transfer guest 4 to room123

// Camera control for specific guests:
// Relative adjustments
// controlGuest("YOUR_API_ID", "1", "zoom", 0.1);          // Zoom guest 1's camera in by 10%
// controlGuest("YOUR_API_ID", "2", "pan", -0.1);          // Pan guest 2's camera left by 10%
// controlGuest("YOUR_API_ID", "3", "focus", 0.1);         // Focus guest 3's camera farther

// Absolute positioning (WebSocket only)
// controlGuest("YOUR_API_ID", "1", "zoom", 1.5, "abs");   // Set guest 1's zoom to 1.5x
// controlGuest("YOUR_API_ID", "2", "pan", 0, "abs");      // Center guest 2's pan
// controlGuest("YOUR_API_ID", "3", "tilt", -0.25, "abs"); // Tilt guest 3's camera 25% down
// controlGuest("YOUR_API_ID", "4", "exposure", 0.8, "abs"); // Set guest 4's exposure to 80%
VDO.Ninja API Reference

Complete reference for all supported API commands, parameters, and response formats.

API Overview

The VDO.Ninja API supports multiple communication methods:

  • WebSocket API: Real-time bidirectional communication (preferred for most uses)
  • HTTP GET API: Simple REST-style requests, compatible with hotkey systems
  • HTTP POST API: For complex data structures like layout objects and supports value2 parameter
  • Server-Sent Events (SSE): One-way communication channel for receiving updates
  • MIDI Integration: Control via MIDI devices using various mapping schemes

For integrations with BitFocus Companion, check out the official Companion module.

For custom embeds, refer to the IFrame API Documentation.

Command Reference

The following tables list all available commands, their parameters, and what they do.

Self Controls

Action Target Value Details
speaker null true/false/toggle Control local speaker (audio playback)
mic null true/false/toggle Control local microphone
camera null true/false/toggle Control local camera (same as video)
video null true/false/toggle Control local camera (alternate command)
volume null true/false/0-100 Control playback volume of all audio tracks (true=100%, false=0%)
record null true/false Start/stop recording the local video stream
bitrate null true/false/integer Control video bitrate (true=reset, false=pause, integer=kbps)
panning null true/false/0-180 Control stereo panning (90=center)
reload null null Reload the current page
hangup null null Disconnect current session
togglehand null null Toggle raised hand status
togglescreenshare null null Toggle screen sharing
forceKeyframe null null Force keyframe ("rainbow puke fix")
sendChat null string Send chat message to all connected users
getDetails null null Get detailed state information
soloVideo null true/false/toggle Highlight video for all guests (director only)

Layout Controls

Action Value Details
layout integer/object/array Switch to layout by index (0=auto-mix, 1-8=custom layouts) or set custom layout with object

Group Controls

Action Value Details
group 1-8 Toggle in/out of specified group
joinGroup 1-8 Join specified group
leaveGroup 1-8 Leave specified group
viewGroup 1-8 Toggle preview of specified group
joinViewGroup 1-8 Preview specified group
leaveViewGroup 1-8 Stop previewing specified group

Camera Control (PTZ)

Action Value Value2 Details
zoom decimal (-1 to 1 relative, 0-2 absolute) "abs" or "true" (optional) Adjust zoom. Relative: positive=in, negative=out. Absolute: 0-2x zoom when value2="abs"
focus decimal (-1 to 1 relative, 0-1 absolute) "abs" or "true" (optional) Adjust focus. Relative: positive=far, negative=near. Absolute: 0-1 range when value2="abs"
pan decimal (-1 to 1) n/a Adjust pan (always absolute). -1=full left, 0=center, 1=full right
tilt decimal (-1 to 1 relative or absolute) "abs" or "true" (optional) Adjust tilt. Relative: positive=up, negative=down. Absolute: -1 to 1 range when value2="abs"
exposure decimal (-1 to 1 relative, 0-1 absolute) "abs" or "true" (optional) Adjust exposure. Relative: positive=brighter, negative=darker. Absolute: 0-1 range when value2="abs"

Guest Controls (Director Mode)

Action Target Value Value2 Details
forward guest slot/ID room name n/a Transfer guest to specified room
addScene guest slot/ID 0-8 or scene name n/a Toggle guest in/out of specified scene
muteScene guest slot/ID scene (optional) n/a Toggle guest's mic in scenes
mic guest slot/ID true/false/toggle n/a Control guest's microphone
camera guest slot/ID true/false/toggle n/a Control guest's camera
video guest slot/ID true/false/toggle n/a Control guest's camera (alternate command)
hangup guest slot/ID null n/a Disconnect guest
soloChat guest slot/ID null n/a Toggle one-way solo chat with guest
soloChatBidirectional guest slot/ID null n/a Toggle two-way solo chat with guest
speaker guest slot/ID null n/a Toggle guest's speaker
display guest slot/ID null n/a Toggle guest's display (ability to see video)
group guest slot/ID 1-8 n/a Toggle guest in/out of specified group
forceKeyframe guest slot/ID null n/a Trigger keyframe for guest (fix rainbow artifacts)
soloVideo guest slot/ID null n/a Toggle highlighting guest's video
sendChat guest slot/ID message text n/a Send private chat message to guest
sendDirectorChat guest slot/ID message text n/a Send message and overlay it on guest's screen
volume guest slot/ID 0-200 n/a Set guest's microphone volume
startRoomTimer guest slot/ID seconds n/a Start countdown timer for guest
pauseRoomTimer guest slot/ID null n/a Pause timer for guest
stopRoomTimer guest slot/ID null n/a Stop timer for guest
mixorder guest slot/ID -1 or 1 n/a Adjust guest's position in the mixer (-1=up, 1=down)
zoom guest slot/ID decimal (see Camera Control) "abs" or "true" (optional) Control guest's camera zoom
focus guest slot/ID decimal (see Camera Control) "abs" or "true" (optional) Control guest's camera focus
pan guest slot/ID decimal -1 to 1 n/a Control guest's camera pan (absolute only)
tilt guest slot/ID decimal (see Camera Control) "abs" or "true" (optional) Control guest's camera tilt
exposure guest slot/ID decimal (see Camera Control) "abs" or "true" (optional) Control guest's camera exposure

Response Formats

Responses from the API depend on the method used:

  • HTTP GET: Responses include simple text values like true, false, null, fail, or a specific value. For object responses like getDetails, you'll receive JSON.
  • WebSocket: Responses are JSON objects containing the result along with the original request parameters and any custom data fields you included.
  • HTTP POST: Responses are JSON objects with similar structure to WebSocket responses.
  • SSE: Events are JSON objects containing state updates and other notifications.

Camera Control Details

The camera control commands support both relative and absolute positioning:

  • Relative adjustments: Changes are applied from the current position. Use decimal values like 0.1 for +10% or -0.1 for -10%.
  • Absolute positioning: Set exact values by adding value2: "abs" (WebSocket/POST) or using compatible ranges.
Camera Control Examples
// Camera Control Value Ranges:
// zoom: Relative -1 to 1, Absolute 0 to 2 (0=minimum zoom, 2=2x zoom)
// focus: Relative -1 to 1, Absolute 0 to 1 (0=near, 1=far)
// pan: Always absolute -1 to 1 (-1=left, 0=center, 1=right)
// tilt: Relative -1 to 1, Absolute -1 to 1 (-1=down, 0=center, 1=up)
// exposure: Relative -1 to 1, Absolute 0 to 1 (0=dark, 1=bright)

// WebSocket Examples:
// Relative: {"action": "zoom", "value": 0.1}                    // Zoom in 10%
// Absolute: {"action": "zoom", "value": 1.5, "value2": "abs"}   // Set zoom to 1.5x

// HTTP POST Examples:
// Relative: POST body: {"action": "focus", "value": -0.1}
// Absolute: POST body: {"action": "exposure", "value": 0.8, "value2": "abs"}

// Note: HTTP GET only supports relative adjustments

Custom Layout Format

When using the layout command, you can provide a custom layout object or array:

Layout Object Example
// Single layout example
{
  "action": "layout",
  "value": [
    {"x": 0, "y": 0, "w": 50, "h": 100, "slot": 0},
    {"x": 50, "y": 0, "w": 50, "h": 100, "slot": 1}
  ]
}

// Using URL parameter to define multiple layouts
// ?layouts=[[{"x":0,"y":0,"w":100,"h":100,"slot":0}],[{"x":0,"y":0,"w":50,"h":100,"slot":0},{"x":50,"y":0,"w":50,"h":100,"slot":1}]]

// Layout properties:
// x, y: Position (percentage of container)
// w, h: Width and height (percentage of container)
// slot: Guest slot number (0-indexed)
// c: Crop to fit (true/false)
// z: Z-index (layer)

// To switch layouts:
// {"action": "layout", "value": 0} // Auto-mix
// {"action": "layout", "value": 1} // First custom layout
// {"action": "layout", "value": 2} // Second custom layout
API Request/Response Logger