> This is part 1 of 3 of the full documentation (pages 1–100 of 228).
> The content is paginated: fetch every part to see all of it.
> Next part: https://docs.digitalsamba.com/reference/llms-full.txt/1
> Page index: https://docs.digitalsamba.com/reference/llms.txt

# Introduction

Digital Samba Embedded is a platform which empowers integrators

Explore what Digital Samba Embedded can offer for you:

[SDK - Build video conferencing integrations](/reference/sdk)

[REST API - Manage your rooms and team with server-side REST API calls.](/reference/rest-api)

#### Examples

There are several SDK demos available with example integrations:

* [Simple Videoroom](https://digitalsamba.github.io/embedded-sdk/dist/demo/videoroom.html) - simple demo that showcases basic integration, listening to events and running commands
* [Initial settings](https://digitalsamba.github.io/embedded-sdk/dist/demo/initial-config.html) - examples of setting default settings prior to loading the frame
* [Managed State demo](https://digitalsamba.github.io/embedded-sdk/dist/demo/managed-state.html) - shows how to use exposed state in complex scenarios, listening to events, checking for permissions and accessing stored data.


# SDK

The **Digital Samba Embedded SDK** is distributed as a publicly available [**npm module**](https://www.npmjs.com/package/@digitalsamba/embedded-sdk).

#### For quick prototyping you can load it with a `<script>` tag from the [unpkg](https://unpkg.com/) public CDN:

{% code lineNumbers="true" %}

```javascript
<script crossorigin src="https://unpkg.com/@digitalsamba/embedded-sdk"></script>
const sambaFrame = DigitalSambaEmbedded.createControl({ url: YOUR_ROOM_URL });
sambaFrame.load();
```

{% endcode %}

#### For production integrations it is recommended to use **npm** and a bundler like [webpack](https://webpack.js.org/).

```
npm install @digitalsamba/embedded-sdk
```

#### Usage with NPM

Add our SDK to the dependency list using your preferred package manager:

`npm install @digitalsamba/embedded-sdk`

or

`yarn install @digitalsamba/embedded-sdk`

After installation, use it in your application code by doing the following:

{% code lineNumbers="true" %}

```javascript
import DigitalSambaEmbedded from '@digitalsamba/embedded-sdk';
const sambaFrame = DigitalSambaEmbedded.createControl({ url: YOUR_ROOM_URL });
sambaFrame.load();
```

{% endcode %}

{% hint style="info" %}
For detailed documentation on the initialization process, read about the [DigitalSambaEmbedded](/reference/sdk/digitalsambaembedded-class) class and the initialization [code examples](/reference/sdk/digitalsambaembedded-class#code-examples-of-the-possible-initoptions-combinations).
{% endhint %}

{% hint style="info" %}
Make sure to browse through the available [Methods](/reference/sdk/methods) and [Events](/reference/sdk/events) of the SDK.
{% endhint %}

The SDK is written in **TypeScript**, so type definitions are also available:

```javascript
import { SendMessageType, ReceiveMessageType /* ...etc */ } from '@digitalsamba/embedded-sdk';
```


# DigitalSambaEmbedded class

This is the main class of the [SDK](/reference/sdk). Your journey always starts by initializing this class and then calling its [methods](/reference/sdk/methods) to control your integration. There are also various [events](/reference/sdk/events) to subscribe to with callbacks.

#### There are two approaches to initializing:&#x20;

* Using the constructor which will load **immediately** the specified room based on the [**InitOptions**](#initoptions) and the optional [**InstanceProperties**](#instanceproperties).<br>

  ```javascript
  //instanceProperties is an optional param
  const sambaFrame = new DigitalSambaEmbedded(initOptions, instanceProperties);
  ```
* Using the `createControl` factory method. Later you can load the room by calling the [load](/reference/sdk/methods/load) method. That way creation of the **DigitalSambaEmbedded** class is decoupled from the actual loading of the room which gives you more control during initialization.<br>

  ```javascript
  // notice `createControl` vs constructor call
  const sambaFrame = DigitalSambaEmbedded.createControl(initOptions);

  // ...
  // when necessary, load the room in the frame
  // instanceProperties is optional
  sambaFrame.load(instanceProperties);
  ```

#### InitOptions - look also at the [code examples](#code-examples-of-the-possible-initoptions-combinations)

* `root` - HTMLElement. If specified, target frame will be created as a child tag of `root`. Otherwise the created iframe will be appended to the `body` tag of the page
* `frame` - HTMLIFrameElement to be wrapped. This is useful if you want the room to be loaded in an `iframe` element which already exists. If `frame` is not specified, then an `iframe` element will be created automatically by the SDK
* `url` - full room URL to be applied as the iframe src attribute. Must include https protocol.\
  `https://`**`[teamNameHere]`**`.digitalsamba.com/`**`[roomNameHere]`**
* `team` - team name (string) - used if you do not want to specify the `url` manually
* `room` - room name (string) - used if you do not want to specify the `url` manually
* `token` - optional JWT string [token](/reference/rest-api/tokens) for authentication, mainly for private rooms
* `templateParams`- an optional JSON object configuring custom URL template parameters when opening an embedded content from the content library. These template parameters are very useful to provide per user authentication or identification when embedding external websites.

  ```javascript
  {
     "GEOGEBRA_TOKEN": "..............."
  }
  ```

  \
  Parameters are specified with curly braces in the embedded URLs - e.g. <https://www.anexternalwebsite.com/?gt=**{GEOGEBRA\\_TOKEN}**\\>
  \
  Note **{USERNAME}** is supported as a default built-in param and you don't need to configure it. \
  The name with which the user entered the room will automatically replace the template.\
  <https://www.anexternalwebsite.com/?name=**{USERNAME}>\*\*<br>
* `roomSettings` - an optional JSON object configuring the initial room settings. Read also about the possible [VirtualBackgroundOptions](/reference/sdk/methods/configurevirtualbackground) and how to configure custom [virtualBackgrounds](#virtual-backgrounds-configuration) array.

  <pre class="language-javascript"><code class="lang-javascript"><strong>{
  </strong>  // Overrides the room setting when defined
    joinScreenEnabled: boolean,
    
    //Configures if user's video device will be enabled on entering the room
    videoEnabled: boolean,
    
    //Configures if user's audio device will be enabled on entering the room
    audioEnabled: boolean,
    
    //Configures initial video and audio devices to use on entering the room
    mediaDevices: {
      videoinput: 'label of camera',
      audioinput: 'label of microphone',
      audiooutput: 'label of speaker device'
    },
    
    //Language for the user. Use language code - e.g. en, de-DE, es-ES
    appLanguage: string,
    
    //Name of the user on entering the room
    username: string,
    
    //Custom initials (max 2 letters) for the user tile
    initials: string,
    
    //If 'auto' or 'tiled' layout mode will be used
    layoutMode: string,
    
    //If the toolbar will be visible or not
    showToolbar: boolean,
    
    //If the topbar will be visible or not
    showTopbar: boolean,
    
    //If the captions panel will be visible or not
    showCaptions: boolean,
    
    //The virtual background
    virtualBackground: VirtualBackgroundOptions,
    
    /*
      Allows you to customize the virtual backgrounds available 
      to users in your application. You can provide your own collection
      of backgrounds and optionally replace the default backgrounds
    */
    virtualBackgrounds: [
      Read below how to configure it
    ],
    
    // Replace default backgrounds with custom ones (optional)
    replaceVirtualBackgrounds: false,
    
    //If the frame will be muted on join for the local user
    muteFrame: boolean,
    
    //If a confirmation modal will be shown when you remove (kick) another user
    requireRemoveUserConfirmation: boolean,
    
    /* 
       An optional base domain to use when generating invitation links

       This is useful if you are a integrator where the invitation links 
       are not on your main domain where the meeting UI is loaded.
    */
    baseDomain: string //For example 'your.domain.com',
    
    /* 
       An optional url to use when generating invitation links
       in the advanced invitation modal

       This is useful if you are a integrator where the invitation links 
       are not on your main domain where the meeting UI is loaded.
    */
    publicRoomUrl: string //For example https://your.domain.com/meeting/ABCDEF
  }
  </code></pre>

The following combinations of fields are valid for **initOptions** ([token](/reference/rest-api/tokens) and roomSettings can be used with any of them):

* `url` - will create a frame as a child of the `body` tag and load the room url
* `url + root` - will create a frame as a child of `root` element and load the room url
* `url + frame` - will load the room url in the provided existing frame
* `team + room` - will create a frame as a child of the `body` tag and load the specified room
* `team + room + root` - will create a frame inside `root` element and load the specified room
* `team + room + frame` - will load the specified room in the provided existing frame
* `frame` - will attach to the specified existing frame (assuming you've manually set correct room url as the iframe src)

### Virtual Backgrounds Configuration

The Digital Samba SDK allows you to customize the virtual backgrounds available to users in your application. You can provide your own collection of backgrounds and optionally replace the default backgrounds provided by the SDK.

#### Custom Backgrounds Collection

You can provide a custom collection of virtual backgrounds during SDK initialization:

```javascript
const sambaFrame = DigitalSambaEmbedded.createControl({ 
  url: roomUrl,
  // Other configuration options...
  roomSettings: {

    // Custom backgrounds collection (optional)
    virtualBackgrounds: [
      {
        id: 'custom-bg-1',    // Unique identifier
        type: 'image',        // Type: 'blur', 'image', or 'video'
        value: 'https://example.com/custom-bg-1.jpg', // URL or blur strength
        thumbnail: 'https://example.com/custom-bg-1-thumb.jpg', // Optional for images, required for videos
        label: 'Custom Background 1' // Display name
      }
    ],
  
    // Replace default backgrounds with custom ones (optional)
    replaceVirtualBackgrounds: false
  }
});

sambaFrame.load();
```

#### Background Item Properties

| Property    | Type   | Description                                                                 | Required                      |
| ----------- | ------ | --------------------------------------------------------------------------- | ----------------------------- |
| `id`        | string | Unique identifier for the background.                                       | Yes                           |
| `type`      | string | Type of background: `'blur'`, `'image'`, or `'video'`.                      | Yes                           |
| `value`     | string | For blur: `'balanced'` or `'strong'`. For image/video: URL to the resource. | Yes                           |
| `thumbnail` | string | URL to a thumbnail image. Optional for images, required for videos.         | No for images, Yes for videos |
| `label`     | string | Display name for the background.                                            | No                            |

#### Replacing Default Backgrounds

By default, the SDK provides a set of predefined backgrounds. You can choose to replace them with your custom collection by setting `replaceVirtualBackgrounds` to `true`:

```javascript
const sambaFrame = DigitalSambaEmbedded.createControl({
  url: roomUrl,
  // Other configuration options...
  roomSettings: {
     virtualBackgrounds: [
       // Your custom backgrounds...
     ],
     replaceVirtualBackgrounds: true
  }
});

sambaFrame.load();
```

If `replaceVirtualBackgrounds` is set to `true` but no `virtualBackgrounds` are provided, the default backgrounds will be preserved and an error will be emitted.

The SDK validates all virtual background items to ensure they meet the required format. If validation fails, an error event will be emitted and the invalid backgrounds will be ignored.

#### InstanceProperties - look also at the[ code example](#sample-usage-of-the-optional-instanceproperties-to-set-a-red-border-and-also-report-errors)

* `frameAttributes` - list of attributes to be applied to the target iframe
* `reportErrors` - boolean, false by default. Whether to report misconfiguration or runtime errors to the browser console

#### Code examples of the possible **initOptions** combinations:

{% code lineNumbers="true" %}

```javascript
//SDK will create a frame as a child of the body tag and load the room url
import DigitalSambaEmbedded from '@digitalsamba/embedded-sdk';
const roomUrl = 'https://[TEAM_NAME_HERE].digitalsamba.com/[ROOM_NAME_HERE]';
const sambaFrame = DigitalSambaEmbedded.createControl({ 
    url: roomUrl,
    //Optional room settings
    /*roomSettings: {
        username: 'John Smith'
        layoutMode: 'auto',
        virtualBackground: { blur: 'balanced' },
        .....................
    },*/
    //token: TOKEN_HERE_IF_YOU_ARE_USING_IT
});
sambaFrame.load();
```

{% endcode %}

{% code lineNumbers="true" %}

```javascript
//SDK will create a frame as a child of the parent element and load the room url
import DigitalSambaEmbedded from '@digitalsamba/embedded-sdk';
const parentElement = document.querySelector('USE_CSS_SELECTOR_HERE');
const roomUrl = 'https://[TEAM_NAME_HERE].digitalsamba.com/[ROOM_NAME_HERE]';
const sambaFrame = DigitalSambaEmbedded.createControl({ 
    url: roomUrl, 
    root: parentElement,
    //token: TOKEN_HERE_IF_YOU_ARE_USING_IT
});
sambaFrame.load();
```

{% endcode %}

{% code lineNumbers="true" %}

```javascript
//SDK will load the room url in the specified existing iframe
import DigitalSambaEmbedded from '@digitalsamba/embedded-sdk';
const existingIFrame = document.querySelector('USE_CSS_SELECTOR_HERE');
const roomUrl = 'https://[TEAM_NAME_HERE].digitalsamba.com/[ROOM_NAME_HERE]';
const sambaFrame = DigitalSambaEmbedded.createControl({ 
    url: roomUrl, 
    frame: existingIFrame,
    //token: TOKEN_HERE_IF_YOU_ARE_USING_IT
});
sambaFrame.load();
```

{% endcode %}

{% code lineNumbers="true" %}

```javascript
//SDK will create a frame as a child of the body tag and load the specified room
import DigitalSambaEmbedded from '@digitalsamba/embedded-sdk';
const teamName = 'TEAM_NAME_HERE';
const roomName = 'ROOM_NAME_HERE';
const sambaFrame = DigitalSambaEmbedded.createControl({ 
    team: teamName, 
    room: roomName,
    //token: TOKEN_HERE_IF_YOU_ARE_USING_IT
});
sambaFrame.load();
```

{% endcode %}

{% code lineNumbers="true" %}

```javascript
//SDK will create a frame as a child of the parent element and load the room
import DigitalSambaEmbedded from '@digitalsamba/embedded-sdk';
const parentElement = document.querySelector('USE_CSS_SELECTOR_HERE');
const teamName = 'TEAM_NAME_HERE';
const roomName = 'ROOM_NAME_HERE';
const sambaFrame = DigitalSambaEmbedded.createControl({ 
     team: teamName, 
     room: roomName,
     root: parentElement,
     //token: TOKEN_HERE_IF_YOU_ARE_USING_IT
});
sambaFrame.load();
```

{% endcode %}

{% code lineNumbers="true" %}

```javascript
//SDK will load the room in the specified existing frame
import DigitalSambaEmbedded from '@digitalsamba/embedded-sdk';
const existingIFrame = document.querySelector('USE_CSS_SELECTOR_HERE');
const teamName = 'TEAM_NAME_HERE';
const roomName = 'ROOM_NAME_HERE';
const sambaFrame = DigitalSambaEmbedded.createControl({ 
     team: teamName, 
     room: roomName,
     frame: existingIFrame,
     //token: TOKEN_HERE_IF_YOU_ARE_USING_IT
});
sambaFrame.load();
```

{% endcode %}

{% code lineNumbers="true" %}

```javascript
//SDK will attach to the specified existing frame
//Assuming you've manually preset correct room url as the iframe src
import DigitalSambaEmbedded from '@digitalsamba/embedded-sdk';
const existingIFrame = document.querySelector('USE_CSS_SELECTOR_HERE');
const sambaFrame = DigitalSambaEmbedded.createControl({ 
     frame: existingIFrame,
     //token: TOKEN_HERE_IF_YOU_ARE_USING_IT
});
sambaFrame.load();
```

{% endcode %}

#### **Sample usage of the optional instanceProperties to set a red border and also report errors**:

Note that you can use any initOptions combination from the [previous examples](#code-examples-of-the-possible-initoptions-combinations).

{% code lineNumbers="true" %}

```javascript
import DigitalSambaEmbedded from '@digitalsamba/embedded-sdk';
const roomUrl = 'https://[TEAM_NAME_HERE].digitalsamba.com/[ROOM_NAME_HERE]';
const sambaFrame = DigitalSambaEmbedded.createControl({ url: roomUrl });

//SDK will put a 5px solid red border around the iframe
const instanceProps = { 
   frameAttributes: {style: "border: 5px solid red"}, 
   reportErrors: true 
};
sambaFrame.load(instanceProps);
```

{% endcode %}


# Methods

Methods are essential for controlling the call. You may want to enable or disable cameras, microphones, start screen sharing, control recordings, etc...

Before you start using methods, first you need to initialize the SDK and load the room through the DigitalSambaEmbedded class. After that you can use the **sambaFrame** (or whatever variable name you have chosen) to call methods and control the rooms experience.

{% hint style="danger" %}
Subscribing to the userJoined event is a crucial part. If you try to call methods (apart from load and event subscription) while user hasn't joined the room yet, then calling the methods won't do anything. For example -> you cannot possibly enable user's camera if he hasn't joined the room yet.

Exception: enableVideo(), disableVideo(), toggleVideo(), enableAudio(), disableAudio() and toggleAudio() don't follow this rule. Calling one of these before you've joined silently stores your requested camera/microphone state as the session's join default — applied automatically once you join, with no error and no immediate confirmation. Listen for the `videoEnabled`, `videoDisabled`, `audioEnabled` or `audioDisabled` events after joining if you need to confirm the result.
{% endhint %}

#### Sample quick-start code:

```javascript
const initOptions = {team: 'myTeamNameHere', room: 'myRoomNameHere'};
const sambaFrame = DigitalSambaEmbedded.createControl(initOptions);

sambaFrame.on('userJoined', (event) => {
  const data = event.data;
  if (data.type === 'local') {
     console.log('You have joined the room');     
     //You can freely call methods from now on, since user is inside the room
     //For example you can hide the toolbar if you want
     sambaFrame.hideToolbar();
  } else {
     console.log(data.user.name, 'has joined the room');
  }
});

//Load the room when you need according to your application logic
sambaFrame.load();
```


# addCustomTile()

addCustomTile({name: string, html: string, position: string "first"|"last"})

Adds a custom tile as a **first** or **last** position in the tiles list. You defined the content of the tile with the **html** property. Name is the title of the tile.

{% hint style="info" %}
The custom tile is always shown on the current page at your chosen position (first or last).
{% endhint %}

{% hint style="warning" %}
The method must be called after you have joined the room. It won't do anything if the room hasn't loaded yet.&#x20;
{% endhint %}

In the below example a custom AI tile is added to the stage.

```javascript
sambaFrame.on('userJoined', (event) => {
   const data = event.data;
   if (data.type === 'local') {
     sambaFrame.addCustomTile({
        "name": "AI", 
        "html": '<img src="https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExdjR5YjF5dWQ4d2d2NzI5eHFyYmxyczgydzRuZ2JwZ2F4MTliaGo2bCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/MHMO7iYMt6pJrEpKNB/giphy.gif"/>',
        "position": "last"
     });
   }
});
```

{% hint style="info" %}
This method is often used in conjunction with [removeCustomTile()](/reference/sdk/methods/removecustomtile) and [sendMessageToCustomTile()](/reference/sdk/methods/sendmessagetocustomtile).
{% endhint %}


# removeCustomTile()

removeCustomTile(name: string)

Removes a previously added custom tile.

```javascript
sambaFrame.on('userJoined', (event) => {
   const data = event.data;
   if (data.type === 'local') {
     sambaFrame.addCustomTile({
        "name": "AI", 
        "html": '<img src="https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExdjR5YjF5dWQ4d2d2NzI5eHFyYmxyczgydzRuZ2JwZ2F4MTliaGo2bCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/MHMO7iYMt6pJrEpKNB/giphy.gif"/>',
        "position": "last"
     });
   }
});
 
//Later at some point
sambaFrame.removeCustomTile("AI");
```

{% hint style="info" %}
This method is used in conjunction with the [addCustomTile()](/reference/sdk/methods/addcustomtile) method.
{% endhint %}


# addFrameEventListener()

addFrameEventListener(eventName, target, listener)

Adds a JavaScript event listener to the iframe of the room. This is useful for listening to raw JS events - e.g. keyup or click. You can attach the listener either to the window or to the document.

```javascript
const keyUpEventListener = (payload) => {
   console.log('keyup', payload)
};
sambaFrame.addFrameEventListener('keyup', 'window', keyUpEventListener);

const clickEventListener = (payload) => {
   console.log('click', payload)
};
sambaFrame.addFrameEventListener('click', 'document', clickEventListener);
```

**Sample use case**: \
You may want to end the call if user presses double-space or some other custom key combination.

{% hint style="info" %}
**addFrameEventListener** is often used in conjunction with the [removeFrameEventListener](/reference/sdk/methods/removeframeeventlistener) method.
{% endhint %}


# addImageToWhiteboard()

addImageToWhiteboard(options?: AddImageToWhiteboardOptions)

Adds an image to an already opened whiteboard.&#x20;

```typescript
AddImageToWhiteboardOptions = {
    base64?: string;
    url?: string;
    position?: {
        x: number;
        y: number;
    };
};
```

You can choose between the **base64** representation of the image or an external **url**. Note if you use an external URL, then the external server must have **CORS** properly enabled, otherwise the image won't be downloaded by the browser.

You can optionally set the (x,y) coordinates relative to the upper-left corner. If you don't set any coordinates the image will be automatically centered.

{% code overflow="wrap" %}

```javascript
//Adds a base64 image
sambaFrame.addImageToWhiteboard({
base64: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAADMElEQVR4nOzVwQnAIBQFQYXff81RUkQCOyDj1YOPnbXWPmeTRef+/3O/OyBjzh3CD95BfqICMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMO0TAAD//2Anhf4QtqobAAAAAElFTkSuQmCC'
});
```

{% endcode %}

**Sample use case**: \
You may have a functionality in your application to add images to the whiteboard on the fly.


# addRecordingBookmark()

addRecordingBookmark(bookmark: string)

Adds a bookmark to the recording in progress, marking the current moment with the label you provide. It works exactly like the **Add bookmark** option in the room's recording menu.

```javascript
sambaFrame.addRecordingBookmark('Q&A starts');
```

Leading and trailing whitespace is trimmed from the label, which must then be 1 to 255 characters long.

{% hint style="info" %}
The bookmark is added only while a recording is in progress, recording bookmarks are enabled in the room settings, and the participant has the **recording** permission. Otherwise the call is refused and an [appError](/reference/sdk/events/apperror) is emitted (`not-allowed`, `forbidden-action` or `add-recording-bookmark`). Wait for the [recordingStarted](/reference/sdk/events/recordingstarted) event before calling this method.
{% endhint %}

{% hint style="info" %}
Available starting from `v0.0.58` of `@digitalsamba/embedded-sdk`.
{% endhint %}

**Sample use cases**:

* Mark agenda points as your application moves through them, such as the next topic, a new slide, or the start of Q\&A, so they are easy to find in the recording.

{% hint style="info" %}
**addRecordingBookmark** is often used together with the [startRecording](/reference/sdk/methods/startrecording) and [stopRecording](/reference/sdk/methods/stoprecording) methods.
{% endhint %}


# addTileAction()

addTileAction(name: string, properties: TileActionProperties, listener: function)

Adds a custom action to the 3-dots menu of the tiles. When the user clicks that custom menu item, then the callback listener function will be invoked.

{% hint style="info" %}
The first parameter "**name**" is just an internal identifier so you can remove the custom action later with the [removeTileAction()](/reference/sdk/methods/removetileaction) method if it is needed.
{% endhint %}

{% hint style="info" %}
Valid tile scopes are '**remote**', '**local**', '**custom**', '**screenshare-local**' and '**screenshare-remote**'. Remote means tiles of other (remote) users, while local means tile of local user. Custom is for custom tiles - see [addCustomTile()](/reference/sdk/methods/addcustomtile) method.
{% endhint %}

In the below example a send email action is added to all remote tiles.

<pre class="language-javascript"><code class="lang-javascript"><strong>const onSendEmailClicked = () => {
</strong><strong>   console.log('Send Email callback called');
</strong><strong>};
</strong>
<strong>sambaFrame.addTileAction(
</strong><strong>  'sendEmail', 
</strong><strong>   {"label": 'Send Email', scope: 'remote'}, 
</strong><strong>   onSendEmailClicked 
</strong><strong>);
</strong></code></pre>

{% hint style="info" %}
This method is often used in conjunction with the [removeTileAction()](/reference/sdk/methods/removetileaction) method.
{% endhint %}


# addUICallback()

addUICallback(event: string, callback: function)

Overrides a UI (frontend) interaction using a callback function. The default action of the Samba's frontend will not execute, and instead your callback will override it.

{% hint style="info" %}
For now only **leaveSession** UI callback is supported.
{% endhint %}

In the below example user will be asked by a confirmation popup before leaving the session:

<pre class="language-javascript"><code class="lang-javascript"><strong>const leaveSessionCallback = () => {
</strong><strong>   console.log('Custom leave session logic called');
</strong><strong>   if (confirm('Are you sure you want to leave the session?')) {
</strong>      sambaFrame.leaveSession();
   }
<strong>};
</strong><strong>
</strong><strong>sambaFrame.addUICallback('leaveSession', leaveSessionCallback);
</strong></code></pre>

{% hint style="info" %}
This method is often used in conjunction with the [removeUICallback](/reference/sdk/methods/removeuicallback) method.
{% endhint %}


# allowBroadcast()

allowBroadcast({id: string,  audio?: boolean,  video?: boolean)                                     allowBroadcast(userId: string) - legacy

Grants broadcast permissions to the target user. The target user id is provided as the `id` property.

With the new format, you can specify which broadcast permissions to grant:

* `audio`: When true, allows the user to broadcast audio
* `video`: When true, allows the user to broadcast video

At least one of `audio` or `video` must be true when using the new format.

The target user will be able to turn on camera and/or microphone after this method is called, depending on the granted permissions.

#### Examples

**Grant both audio and video permissions (using new format)**

```javascript
sambaFrame.allowBroadcast({
  id: '9efc7798-a1a4-44bd-9d8d-532fe0feea9d',
  audio: true,
  video: true
});
```

**Grant only audio permission**

```javascript
sambaFrame.allowBroadcast({
  id: '9efc7798-a1a4-44bd-9d8d-532fe0feea9d',
  audio: true,
  video: false
});
```

**Grant only video permission**

```javascript
sambaFrame.allowBroadcast({
  id: '9efc7798-a1a4-44bd-9d8d-532fe0feea9d',
  audio: false,
  video: true
});
```

**DEPRECATED legacy format (grants both audio and video)**

```javascript
sambaFrame.allowBroadcast('9efc7798-a1a4-44bd-9d8d-532fe0feea9d');
```

**Sample use case**: \
Have a custom participants panel in your integration and want moderators to be able to grant specific broadcast permissions to particular users, so they can turn on camera and/or microphone.

This is particularly useful in webinar scenarios where particular roles do not have broadcast permissions by default, and you want to give some participants the ability to speak (audio only) while others can both speak and be seen (audio and video).


# allowScreenshare()

allowScreenshare(userId: string)

Grants screen share permissions to the target user. The target user id is provided as a parameter.

The target user will be able to share screen after this method is called.&#x20;

```javascript
sambaFrame.allowScreenshare('9efc7798-a1a4-44bd-9d8d-532fe0feea9d');
```

**Sample use case**: \
Have a custom participants panel in your integration and want moderators to be able to grant screenshare permissions to particular users. It will be mostly useful in webinar scenarios where particular roles do not have screenshare permissions by default.


# changeBrandingOptions()

changeBrandingOptions({paletteMode, primaryColor, toolbarColor, roomBackgroundColor})

Changes the color branding of the room

```javascript
//Changes the palette mode type - dark or light. 
//The palette mode determines mainly the background color of the panels
sambaFrame.changeBrandingOptions({'paletteMode': 'dark'});

//Makes the primary color green - hex code of green color is #00ff00
//Primary color of the theme determines the color of main actions and highlighting
sambaFrame.changeBrandingOptions({'primaryColor': '#0000ff'});

//Makes the toolbar background color green - hex code of green color is #00ff00
sambaFrame.changeBrandingOptions({'toolbarColor': '#00ff00'});

//Makes the room background color red - hex code of red color is #ff0000
sambaFrame.changeBrandingOptions({'roomBackgroundColor': '#ff0000'});
```

**Sample use cases**:&#x20;

* You may want to customize the look & feel of your rooms to match your brand.


# changeLayoutMode()

changeLayoutMode(mode: 'tiled' | 'auto')

Changes the layout mode according to the provided param - "**tiled**" or "**auto**" (automatic).

```javascript
//Changes the layout mode to automatic
sambaFrame.changeLayoutMode('auto');

//Changes the layout mode to tiled
sambaFrame.changeLayoutMode('tiled');
```

{% hint style="info" %}
There are two layout modes provided inside the room - `Tiled Mode (`**`tiled`**`)` and `Automatic Mode (`**`auto`**`)`.

In `Automatic Mode` the current active speaker is being displayed in a larger tile and also fine-grain controls like pinning and fullscreen are hidden from the layout.
{% endhint %}

**Sample use cases**:&#x20;

* You may want to change the room layout mode on the fly during the call.
* You may have developed a mode switcher outside the Samba iframe and want to control the layout inside the room.

{% hint style="info" %}
The related event is [layoutModeChanged](/reference/sdk/events/layoutmodechanged), if you want to be informed when the layout mode has been changed.
{% endhint %}


# changeRole()

changeRole(userId: string, role: string)

Changes the role of an existing user. The target user's id and new role are provided as parameters.

```javascript
//Promote a user to a moderator
sambaFrame.changeRole('9efc7798-a1a4-44bd-9d8d-532fe0feea9d', 'moderator');

//Demote later the moderator to attendee
sambaFrame.changeRole('9efc7798-a1a4-44bd-9d8d-532fe0feea9d', 'attendee');
```

**Sample use case**: \
Have a custom participants panel in your integration and want power users to be able to change roles of other participants.

{% hint style="info" %}
This method is often used with the [roleChanged](/reference/sdk/events/rolechanged) event, which is emitted after a role of a user changes.
{% endhint %}


# changeToolbarPosition()

changeToolbarPosition(side: 'left' | 'bottom' | 'right')

Changes the position of the toolbar - **left**, **bottom** or **right**

```javascript
//Places the toolbar at the left side of the page
sambaFrame.changeToolbarPosition('left');

//Places the toolbar at the bottom of the page
sambaFrame.changeToolbarPosition('bottom');

//Places the toolbar at the right side of the page
sambaFrame.changeToolbarPosition('right');
```

**Sample use cases**:&#x20;

* You may want to control the toolbar position dynamically during the conference

{% hint style="info" %}
**showToolbar** is often used in conjunction with the [hideToolbar](/reference/sdk/methods/hidetoolbar) method.
{% endhint %}


# closeLibraryFile()

closeLibraryFile(id?: string)

Closes a concrete library file. If the file is not opened, then nothing will happen.

```javascript
sambaFrame.closeLibraryFile();
```

**Sample use case**: \
You may have buttons in your integration to control file opening and closing.

Used in conjunction with [openLibraryFile()](/reference/sdk/methods/openlibraryfile).


# closeWhiteboard()

closeWhiteboard(id?: string)

Closes the concrete whiteboard. If no id is specified, it just closes the current opened one.

If the whiteboard is already closed, then nothing will happen.

```javascript
//Closes the current locally opened whiteboard
sambaFrame.closeWhiteboard();

//Closes a concrete whiteboard
sambaFrame.closeWhiteboard('c0771004-c9fc-4308-be4f-6264d8e486af');
```

**Sample use case**: \
You may have a button in your application to control the whiteboard visibility.

Used in conjunction with [openWhiteboard().](/reference/sdk/methods/openwhiteboard)


# createWhiteboard()

createWhiteboard: ({personal: boolean, folderId: string})

Creates and opens a new whiteboard, and immediately persists it in the personal or room library.

You can optionally specify a parent library folder id. If folder is not specified, then whiteboard will be part of the default root library folder.

```javascript
//Creates the whiteboard in the room library
sambaFrame.createWhiteboard({personal: false});

//Creates the whiteboard in the personal library
sambaFrame.createWhiteboard({personal: true});

//Creates the whiteboard in the room library inside a concrete folder
sambaFrame.createWhiteboard({
    personal: false,
    folderId: '6d987ab4-9df2-45f2-a076-eec503cc6799'
});
```

**Sample use case**: \
You may have a button in your application to create a whiteboard on the fly.


# configureCaptions()

configureCaptions({ fontSize, spokenLanguage })

Changes the captions settings according to the provided params. You are able to change the font size of the captions (**small**, **medium**, **large**) and also the spoken language of the user. There is no autodetection of the speaking language, so if user is speaking in some other language than the default English, then the spoken language needs to be set for the captions to be proper.

```javascript
//Changes the captions font size to large
sambaFrame.configureCaptions({fontSize: 'large'});

//Changes the spoken language of the local user to German
sambaFrame.configureCaptions({spokenLanguage: 'de'});

//Changes the spoken language of all room users to German
sambaFrame.configureCaptions({spokenLanguage: 'de', applySpokenLanguageToAll: true});

```

| Language name | Code to use as spokenLanguage param |
| ------------- | ----------------------------------- |
| Dutch         | nl                                  |
| English       | en                                  |
| French        | fr                                  |
| German        | de                                  |
| Italian       | it                                  |
| Portuguese    | pt                                  |
| Romanian      | ro                                  |
| Spanish       | es                                  |
| Swedish       | sv                                  |

**Sample use cases**:&#x20;

* You may want to control captions appearance and language with custom buttons or dropdowns outside the DigitalSamba room interface.

{% hint style="info" %}
The related events are [captionsFontSizeChanged](/reference/sdk/events/captionsfontsizechanged) and [captionsSpokenLanguageChanged](/reference/sdk/events/captionsspokenlanguagechanged) if you want to be informed when the captions settings have been changed.
{% endhint %}


# configureVirtualBackground()

configureVirtualBackground(options: VirtualBackgroundOptions)

Enables or modifies (if already enabled) the virtual background for local user with given options. Either `blur`, `image` or `imageUrl` field needs to be specified.

For a video background you must specify both `videoUrl` and `thumbnailUrl`. The `thumbnailUrl` is the preview image in the virtual background selector.

{% hint style="warning" %}
We don't post-process or modify the video background file. You must ensure you provide a reasonable sized video background (e.g. a few MBs at most).
{% endhint %}

The **enforce** param is optional and if set to true, then it will make it impossible for the local user to manually change the virtual background once entered inside the room.

```typescript
VirtualBackgroundOptions {
    enforce?: boolean;
    blur?: 'balanced' | 'strong';
    image?: string;
    imageUrl?: string;
    videoUrl?: string;
    thumbnailUrl?: string;
}
```

Possible predefined values for image are:\
"**office**", "**office2**", "**beach**", "**fireworks**", "**bookshelf**", "**forest**", "**mountain**", "**savannah**"

```javascript
//Enables strong blur of the background for the local user
sambaFrame.configureVirtualBackground({blur: 'strong'});

/*Enables balanced blur of the background for the local user and enforces it,
  so the user cannot change it once inside the room*/
sambaFrame.configureVirtualBackground({blur: 'balanced', enforce: true});

//Sets a forest virtual background for the local user
sambaFrame.configureVirtualBackground({image: 'forest'});

//Sets an image from a public url as a virtual background for the local user
sambaFrame.configureVirtualBackground({imageUrl: 'https://someUrlOfAnImageHere'});

//Sets a video from a public url as a virtual background for the local user
sambaFrame.configureVirtualBackground({
    videoUrl: 'https://someUrlOfAVideoHere',
    thumbnailUrl: 'https://someUrlOfTheVideoThumbnailImage'
});
```

**Sample use cases**:

* You may want to control virtual background for the local user dynamically during the meeting.

{% hint style="info" %}
The related events are [virtualBackgroundChanged](/reference/sdk/events/virtualbackgroundchanged) and [virtualBackgroundDisabled](/reference/sdk/events/virtualbackgrounddisabled)\
if you want to be informed when the virtual background settings have been changed.
{% endhint %}

## When the background is not applied

This method does not return a promise and does not throw — it is a one-way command to the room. Not every participant's device can run a virtual background, and applying one can fail. When that happens the participant keeps their **raw camera**.

To detect it, listen for [appError](/reference/sdk/events/apperror) with `name: 'virtual-bg'` and a `data.reason` of `'unsupported'` or `'failed'`:

```javascript
sambaFrame.on('appError', (event) => {
  const error = event.data;
  if (error.name !== 'virtual-bg' || !error.data?.reason) return;

  // error.data.reason                  -> 'unsupported' | 'failed'
  // error.data.virtualBackgroundConfig -> the background you requested
  console.warn('Virtual background not applied:', error.data.reason);
});
```

{% hint style="warning" %}
With `enforce: true` the virtual background panel is hidden from the participant, so a refused device is invisible to everyone in the session unless your application listens for this event.
{% endhint %}

See [appError](/reference/sdk/events/apperror) for the full payload, and for the timing caveats — an `unsupported` report can arrive up to \~30 seconds after this call and before the participant joins, and a `failed` report can occur more than once per session.


# disableAudio()

Disables (turns off) user's microphone.

```javascript
sambaFrame.disableAudio();
```

**Sample use cases**:&#x20;

* Have a custom toolbar in your integration and want user to control microphone from it.
* You may want to mute the user based on your application needs.

{% hint style="info" %}
The related event is [audioDisabled](/reference/sdk/events/audiodisabled), if you want to be informed when user disables microphone.
{% endhint %}


# disableVideo()

Disables (turns off) user's camera.

```javascript
sambaFrame.disableVideo();
```

**Sample use cases**:&#x20;

* Have a custom toolbar in your integration and want user to control camera from it.
* You may want to turn off user's camera based on a concrete situation in your application.

{% hint style="info" %}
The related event is [videoDisabled](/reference/sdk/events/videodisabled), if you want to be informed when user disables camera.
{% endhint %}


# disableVirtualBackground()

Removes (if already enabled) the virtual background for the local user.

```javascript
sambaFrame.disableVirtualBackground();
```

**Sample use cases**:&#x20;

* You may want to control virtual background for the local user dynamically during the meeting.

{% hint style="info" %}
The related events are [captionsFontSizeChanged](/reference/sdk/events/captionsfontsizechanged) and [captionsSpokenLanguageChanged](/reference/sdk/events/captionsspokenlanguagechanged) if you want to be informed when the captions settings has been changed.
{% endhint %}


# disallowBroadcast()

disallowBroadcast(userId: string)

Revokes the broadcast permissions for the target user. The target user id is provided as a parameter.

{% hint style="warning" %}
This method only takes effect if [allowBroadcast](/reference/sdk/methods/allowbroadcast) was previously called for that user.
{% endhint %}

```javascript
sambaFrame.disallowBroadcast('9efc7798-a1a4-44bd-9d8d-532fe0feea9d');
```

**Sample use case**: \
Have a custom participants panel in your integration and want moderators to be able to revoke broadcast permissions for particular users. It will be mostly useful in webinar scenarios where particular roles do not have broadcast permissions by default and these permissions are granted and revoked on the fly during the webinar.


# disallowScreenshare()

disallowScreenshare(userId: string)

Revokes the screenshare permissions for the target user. The target user id is provided as a parameter.

{% hint style="warning" %}
This method only takes effect if [allowScreenshare](/reference/sdk/methods/allowscreenshare) was previously called for that user.
{% endhint %}

```javascript
sambaFrame.disallowScreenshare('9efc7798-a1a4-44bd-9d8d-532fe0feea9d');
```

**Sample use case**: \
Have a custom participants panel in your integration and want moderators to be able to revoke screenshare permissions for particular users. It will be mostly useful in webinar scenarios where particular roles do not have screenshare permissions by default and these permissions are granted and revoked on the fly during the webinar.


# enableAudio()

Enables (turns on) user's microphone.

```javascript
sambaFrame.enableAudio();
```

**Sample use case**: \
Have a custom toolbar in your integration and want user to control microphone from it.

{% hint style="info" %}
The related event is [audioEnabled](/reference/sdk/events/audioenabled), if you want to be informed when a user enables microphone.
{% endhint %}


# enableVideo()

Enables (turns on) user's camera.

```javascript
sambaFrame.enableVideo();
```

**Sample use case**: \
Have a custom toolbar in your integration and want user to control camera from it.

{% hint style="info" %}
The related event is [videoEnabled](/reference/sdk/events/videoenabled), if you want to be informed when a user enables camera.
{% endhint %}


# enableVirtualBackground()

enableVirtualBackground(options: VirtualBackgroundOptions)

Alias for [configureVirtualBackground](/reference/sdk/methods/configurevirtualbackground) - read there for all possible options

```javascript
sambaFrame.enableVirtualBackground({blur: 'balanced'});
```


# endSession()

endSession(true/false)

Ends the session for everyone. By default a confirmation popup is shown, but you can override that with a boolean parameter. If you set the value to **false**, all users are immediately removed from the room and the call ends without any confirmation modals of the action.

```javascript
//End the session, but shows first a confirmation modal
sambaFrame.endSession();

//End the session without showing any confirmation modal
sambaFrame.endSession(false);
```

{% hint style="warning" %}
This method ends the whole call and everyone is removed from the room.

For only the local user to leave the session - use the [leaveSession](/reference/sdk/methods/leavesession) method instead.
{% endhint %}

**Sample use case**: \
You want moderators to be able to end calls by clicking a custom button in your integration.


# featureEnabled()

featureEnabled(feature: string)

Returns if a concrete feature is available inside the room - e.g. **chat** or **screenshare**.

```javascript
//Prints a boolean value if chat feature is available or not
console.log('Chat feature status:', sambaFrame.featureEnabled('chat'));
```

Read about the [features](/reference/sdk/properties/features) property for the full list of possible features.


# hideCaptions()

Hides the captions (automatic subtitles) panel at the bottom of the screen.

```javascript
sambaFrame.hideCaptions();
```

**Sample use case**: \
Have a completely custom toolbar in your integration and you want user to be able to show/hide captions panel from a custom button in your toolbar.

{% hint style="info" %}
Often used in conjunction with [showCaptions](/reference/sdk/methods/showcaptions) method.
{% endhint %}


# hideToolbar()

Hides the application toolbar completely.

```javascript
sambaFrame.hideToolbar();
```

**Sample use case**: \
Have a completely custom toolbar in your integration and you don't want the user to see the default Digital Samba toolbar inside the room.

{% hint style="info" %}
Often used in conjunction with the [showToolbar](/reference/sdk/methods/showtoolbar) method.
{% endhint %}


# hideTopbar()

Hides the application topbar completely.

```javascript
sambaFrame.hideTopbar();
```

**Sample use case**: \
You want to show/hide conditionally the topbar - e.g. you may not want to see the topbar at all.

{% hint style="info" %}
Often used in conjunction with the [showTopbar](/reference/sdk/methods/showtopbar) method.
{% endhint %}


# leaveSession()

Leaves the session, so the user is no longer participating in the call.

```javascript
sambaFrame.leaveSession();
```

**Sample use case**: \
Have a custom toolbar in your integration and want user to leave the session by clicking your own specific hang up call button.


# listUsers()

Returns an array of the current users inside the room.

<pre class="language-javascript"><code class="lang-javascript">let users = sambaFrame.listUsers();
console.log('There are', users.length, 'users inside the room:');
console.log(users);

/*Here is how the array looks like:
<strong>[
</strong>    {
        "id": "08c82f56-c670-4d36-bfe3-87a8cd0f7f29",
        "name": "John",
        "avatarColor": "#90c695",
        "role": "moderator",
        "kind": "local"
    },
    {
        "id": "15a0b10d-5f0f-47a9-9889-1d92651aa6d8",
        "name": "Lucas",
        "avatarColor": "#3498db",
        "role": "moderator",
        "deviceType": "desktop",
        "kind": "remote"
    }
]*/
</code></pre>

**Sample use case**: \
You want to have a list of the current users participating in the room.

{% hint style="info" %}
Look at the [usersUpdated](/reference/sdk/events/usersupdated) event if you want to subscribe to an always up-to-date array of the users inside the room.
{% endhint %}


# load()

load(props?: InstanceProperties)

Loads the room inside the iframe. Typically you need to invoke this method only once. The `props` param is optional.

The **load()** method is the delayed form of initialization - you first call **createControl** of the SDK and then you can load the room later based on your application needs.

{% hint style="info" %}
Read more about SDK initialization process in the [DigitalSambaEmbedded class](/reference/sdk/digitalsambaembedded-class) section
{% endhint %}

#### InstanceProperties signature

* `frameAttributes` - list of attributes to be applied to the target iframe
* `reportErrors` - boolean, false by default. Whether to report misconfiguration or runtime errors to console

#### Sample code -> it will put a 5px red border around the iframe (using the html style attribute):

```javascript
const initOptions = {team: 'myTeamNameHere', room: 'myRoomNameHere'};
const sambaFrame = DigitalSambaEmbedded.createControl(initOptions);
//..................................................................

//Some time later load the room
sambaFrame.load({
  frameAttributes: {style: "border: 5px solid red"},
  reportErrors: false
});
```


# lowerHand()

lowerHand(userId?: string)

Lowers the hand of the local user if no **userId** param is provided.&#x20;

Otherwise lowers the hand of the user with the specified user id.

Of course if the hand of the user wasn't raised previously, calling the **lowerHand** method won't have any effect.

```javascript
//Lowers the hand of the local user
sambaFrame.lowerHand();

//Lowers the hand of the user with the specified user id
sambaFrame.lowerHand('9efc7798-a1a4-44bd-9d8d-532fe0feea9d');
```

Corresponding [handLowered](/reference/sdk/events/handlowered) event will be emitted.

**Sample use cases**:&#x20;

* Have a custom toolbar in your integration and make user to be able to raise and then lower hand from it.
* Make moderators be able to lower hand of users from your custom participants panel

{% hint style="info" %}
**lowerHand** is often used in conjunction with the [raiseHand](/reference/sdk/methods/raisehand) method.
{% endhint %}


# muteFrame()

Mutes locally all sounds coming from the video conference frame. Note that this doesn't affect other (remote) users. The method behaves like muting your browser tab - affects only local user.

```javascript
sambaFrame.muteFrame();
```

**Sample use cases**:&#x20;

* Having the conference loaded in the background and muted from user until a certain event happens.

{% hint style="info" %}
**muteFrame** is often used in conjunction with the [unmuteFrame](/reference/sdk/methods/unmuteframe) method.
{% endhint %}


# maximizeLocalTile()

Maximizes user's local (own) tile. Note that this doesn't affect other (remote) users.\
If user's tile is already maximized, then calling this method has no effect.

```javascript
sambaFrame.maximizeLocalTile();
```

**Sample use cases**:&#x20;

* Having the local (own) tile minimized and wanting to maximize it.

{% hint style="info" %}
**maximizeLocalTile** is often used in conjunction with the [minimizeLocalTile](/reference/sdk/methods/minimizelocaltile) method.
{% endhint %}


# maximizeUser()

maximizeUser(userId: string, tile = 'media' | 'screenshare')

Maximizes (fullscreens) the tile of a concrete user. You can specify if you want to fullscreen the **media** tile (video/audio) or **screenshare** tile of the user. If tile param is not specified, the default value is **media**.

<pre class="language-javascript"><code class="lang-javascript">//Maximizes the media tile of the user
<strong>sambaFrame.maximizeUser('9efc7798-a1a4-44bd-9d8d-532fe0feea9d');
</strong>
//Maximizes the screenshare tile of the user
sambaFrame.maximizeUser('9efc7798-a1a4-44bd-9d8d-532fe0feea9d', 'screenshare');
</code></pre>

**Sample use cases**:&#x20;

* Wanting to maximize (fullscreen) tile or screenshare of a concrete user

{% hint style="info" %}
**maximizeUser** is often used in conjunction with the [minimizeUser](/reference/sdk/methods/minimizeuser) method.
{% endhint %}


# minimizeLocalTile()

Minimizes user's local (own) tile. Note that this doesn't affect other (remote) users.\
If user's tile is already minimized , then calling this method has no effect.

```javascript
sambaFrame.minimizeLocalTile();
```

**Sample use cases**:&#x20;

* Having the local (own) tile maximized and wanting to minimize it.

{% hint style="info" %}
**minimizeLocalTile** is often used in conjunction with the [maximizeLocalTile](/reference/sdk/methods/maximizelocaltile) method.
{% endhint %}


# minimizeContent()

Minimizes the content no matter if fullscreened or pinned.

<pre class="language-javascript"><code class="lang-javascript"><strong>sambaFrame.minimizeContent();
</strong></code></pre>

**Sample use cases**:&#x20;

* Wanting to minimize the currently fullscreened or pinned content

{% hint style="info" %}
**minimizeContent** is often used in conjunction with the [maximizeUser](/reference/sdk/methods/maximizeuser) and [pinUser](/reference/sdk/methods/pinuser) methods.
{% endhint %}


# minimizeUser()

Minimizes (reverts fullscreen) the currently maximized (fullscreened) user content.

<pre class="language-javascript"><code class="lang-javascript"><strong>sambaFrame.minimizeUser();
</strong></code></pre>

**Sample use cases**:&#x20;

* Wanting to minimize the currently maximized content.

{% hint style="info" %}
**minimizeUser** is often used in conjunction with the [maximizeUser](/reference/sdk/methods/maximizeuser) method.
{% endhint %}


# off()

off(event: string, callback: function)

Unsubscribe from an [event](/reference/sdk/events). There was a previous subscription made with [on](/reference/sdk/methods/on).

#### Sample unsubscription code

```javascript
const modeChangedCallback = (event) => {
 //.....................................
};

sambaFrame.on('layoutModeChanged', modeChangedCallback);
//......................................................

//This will unsubscribe from the event, so the callback won't be invoked anymore
sambaFrame.off('layoutModeChanged', modeChangedCallback);
```


# on()

on(event: string, callback: function)

Subscribes to an [event](/reference/sdk/events) using a callback function.

#### Event payload signature

```
{
  "type": "eventNameHere",
  "data": {
    .....................
  }
}
```

#### Sample subscription code

<pre class="language-javascript"><code class="lang-javascript"><strong>sambaFrame.on('userJoined', (event) => {
</strong>  const data = event.data;
  if (data.type === 'local') {
     console.log('You have joined the room');
  } else {
     console.log(data.user.name, 'has joined the room');
  }
});
</code></pre>

{% hint style="info" %}
It is possible to subscribe multiple times to the same event with different callbacks.
{% endhint %}

#### Sample subscription code with multiple callbacks

```javascript
sambaFrame.on('userJoined', (event) => {
  console.log('First callback called');
});

//....................................

sambaFrame.on('userJoined', (event) => {
  console.log('Second callback called');  
});
```


# once()

once(event: string, callback: function)

Subscribes to an [event](/reference/sdk/events) using a **one-time** callback function. The crucial difference to [on()](/reference/sdk/methods/on) is that once the callback is invoked , then it won't be invoked anymore.

#### Sample subscription code

<pre class="language-javascript"><code class="lang-javascript"><strong>sambaFrame.once('audioEnabled', (event) => {
</strong>  console.log('This will be printed only once even if user enables audio 5 times');
});
</code></pre>


# openLibraryFile()

openLibraryFile(id: string)

Opens a concrete file from the content library. If the file is already opened, then nothing will happen.

```javascript
sambaFrame.openLibraryFile('c0771004-c9fc-4308-be4f-6264d8e486af');
```

**Sample use case**: \
You may have buttons in your integration to control file opening and closing.

Often used in conjunction with [closeLibraryFile()](/reference/sdk/methods/closelibraryfile).


# openWhiteboard()

openWhiteboard(id?: string)

Opens a concrete whiteboard.&#x20;

If no id is specified, then a new one is created, opened and added to the room library.

```javascript
sambaFrame.openWhiteboard('c0771004-c9fc-4308-be4f-6264d8e486af');
```

**Sample use case**: \
You may have a button in your application to control the whiteboard visibility.

Often used in conjunction with [closeWhiteboard()](/reference/sdk/methods/closewhiteboard).


# pinUser()

pinUser(userId: string, tile = 'media' | 'screenshare')

Pins the tile of a concrete user. You can specify if you want to pin the **media** tile (video/audio) or **screenshare** tile of the user. If tile param is not specified, the default value is **media**.

<pre class="language-javascript"><code class="lang-javascript">//Pins the media tile of the user
<strong>sambaFrame.pinUser('9efc7798-a1a4-44bd-9d8d-532fe0feea9d');
</strong>
//Pins the screenshare tile of the user
sambaFrame.pinUser('9efc7798-a1a4-44bd-9d8d-532fe0feea9d', 'screenshare');
</code></pre>

**Sample use cases**:&#x20;

* Wanting to pin tile or screenshare of a concrete user

{% hint style="info" %}
**pinUser** is often used in conjunction with the [unpinUser](/reference/sdk/methods/unpinuser) method.
{% endhint %}


# raiseHand()

Raises the hand of the local user. Other users in the room will be notified about the raised hand.

```javascript
sambaFrame.raiseHand();
```

Corresponding [handRaised](/reference/sdk/events/handraised) event will be emitted.

**Sample use cases**:&#x20;

Have a custom toolbar in your integration and make user to be able to raise or lower hand from it.

{% hint style="info" %}
**raiseHand** is often used in conjunction with the [lowerHand](/reference/sdk/methods/lowerhand) method.
{% endhint %}


# removeFrameEventListener()

removeFrameEventListener(eventName, target, listener)

Removes a previously attached frame event listener (with [addFrameEventListener](/reference/sdk/methods/addframeeventlistener)).

```javascript
const keyUpEventListener = (payload) => {
   console.log('keyup', payload)
};
sambaFrame.addFrameEventListener('keyup', 'window', keyUpEventListener);

//At some point later when you no longer need the listener
sambaFrame.removeFrameEventListener('keyup', 'window', keyUpEventListener);
```

**Sample use case**: \
You may want to remove the listener after you no longer need it.

{% hint style="info" %}
**removeFrameEventListener** is used in conjunction with the [addFrameEventListener](/reference/sdk/methods/addframeeventlistener)
{% endhint %}


# removeTileAction()

removeTileAction(name: string)

Removes a previously registered custom tile action from the 3-dots menu of the tiles.&#x20;

In the below example a custom tile action called **sendEmail** is registered and later removed.

<pre class="language-javascript"><code class="lang-javascript"><strong>const actionName = 'sendEmail';
</strong><strong>
</strong><strong>const customCallback = () => {
</strong><strong>   console.log('Custom logic called');
</strong><strong>};
</strong><strong>
</strong><strong>sambaFrame.addTileAction(
</strong><strong>   actionName, 
</strong><strong>   {"label": 'Send Email', scope: ''}, 
</strong><strong>   customCallback
</strong><strong>);
</strong><strong>
</strong><strong>//At some point later
</strong>sambaFrame.removeTileAction(actionName);
</code></pre>


# removeUICallback()

removeUICallback(event: string, callback: function)

Removes an already registered UI callback function.

In the below example the leave session callback is removed at some point later:

<pre class="language-javascript"><code class="lang-javascript"><strong>const leaveSessionCallback = () => {
</strong><strong>   console.log('Custom leave session logic called');
</strong><strong>   if (confirm('Are you sure you want to leave the session?')) {
</strong>      sambaFrame.leaveSession();
   }
<strong>};
</strong><strong>
</strong><strong>sambaFrame.addUICallback('leaveSession', leaveSessionCallback);
</strong><strong>
</strong><strong>//At some point later:
</strong>sambaFrame.removeUICallback('leaveSession', leaveSessionCallback);
</code></pre>

{% hint style="info" %}
This method is often used in conjunction with the [addUICallback ](/reference/sdk/methods/adduicallback)method.
{% endhint %}


# removeUser()

removeUser(userId: string)

Removes (kicks) a user from the room. The target user's id is provided as a parameter.

```javascript
sambaFrame.removeUser('9efc7798-a1a4-44bd-9d8d-532fe0feea9d');
```

**Sample use case**: \
Have a custom participants panel in your integration and want moderators to be able to remove (kick) a misbehaving remote user by clicking a button.


# requestMute()

requestMute(userId: string)

Requests muting a remote user's microphone. The target user's id is provided as a parameter.\
A confirmation popup will be shown inside the session to avoid an accidental mute.

```javascript
sambaFrame.requestMute('9efc7798-a1a4-44bd-9d8d-532fe0feea9d');
```

**Sample use case**: \
Have a custom participants panel in your integration and want moderators to be able to mute a noisy remote user by clicking a button.

{% hint style="info" %}
A related method is [requestUnmute](/reference/sdk/methods/requestunmute), if you want to request a user to unmute microphone.
{% endhint %}


# requestToggleAudio()

(userId: string, shouldMute?: boolean)

Requests toggle of a remote user's microphone. The target user's id is provided as a parameter.\
As an optional second parameter you can specify a concrete wanted state for the remote user's microphone. In case it is not specified, then the microphone will be toggled - if it is enabled, then it will become muted and vice-versa - if muted, then the remote user will be asked to enable it.

{% hint style="warning" %}
You cannot forcefully unmute a remote user, because that can easily become a privacy concern. You can only request a remote user to unmute and then the remote user will accept or deny the request.
{% endhint %}

```javascript
//Toggles the state of the remote user microphone - id as param
sambaFrame.requestToggleAudio('9efc7798-a1a4-44bd-9d8d-532fe0feea9d');

//Mutes the remote user's microphone - id as first param, true means mute
sambaFrame.requestToggleAudio('9efc7798-a1a4-44bd-9d8d-532fe0feea9d', true);

//Ask the remote user to unmute microphone - id as first param, false means unmute
sambaFrame.requestToggleAudio('9efc7798-a1a4-44bd-9d8d-532fe0feea9d', false);
```

**Sample use case**: \
Have a custom participants panel in your integration and want moderators to be able to toggle or set the remote user's microphone state.

{% hint style="info" %}
This method is a combination of [requestMute](/reference/sdk/methods/requestmute) and [requestUnmute](/reference/sdk/methods/requestunmute) functionality.
{% endhint %}


# requestUnmute()

requestUnmute(userId: string)

Requests unmuting a remote user's microphone. The target user's id is provided as a parameter.\
A confirmation popup will be shown to the remote user, who can accept or deny the request.

{% hint style="warning" %}
You cannot forcefully unmute a remote user, because that can easily become a privacy concern. You can only request a remote user to unmute and then the remote user will accept or deny the request.
{% endhint %}

```javascript
sambaFrame.requestUnmute('9efc7798-a1a4-44bd-9d8d-532fe0feea9d');
```

**Sample use case**: \
Have a custom participants panel in your integration and want moderators to be able to request another user to speak - e.g the user may have forgotten that the microphone is muted.

{% hint style="info" %}
A related method is [requestMute](/reference/sdk/methods/requestmute), if you want to mute a remote user's microphone.
{% endhint %}


# sendMessageToCustomTile()

sendMessageToCustomTile({name: string, event?: string, origin?: string, data?: any})

Posts a message to the iframe of the custom tile which was previously created with [addCustomTile()](/reference/sdk/methods/addcustomtile).

It is mainly used if you have listeners in your custom tile and want to inform your iframe.

{% hint style="warning" %}
The method must be called after you have add the custom tile. It won't do anything if there isn't an existing tile with a matching name.
{% endhint %}

{% hint style="info" %}
This method is often used in conjunction with the [addCustomTile()](/reference/sdk/methods/addcustomtile) and [removeCustomTile()](/reference/sdk/methods/removecustomtile) methods.
{% endhint %}

In the below example a custom AI tile is added to the stage and then a message send to it.

```javascript
sambaFrame.on('userJoined', (event) => {
   const data = event.data;
   if (data.type === 'local') {
     sambaFrame.addCustomTile({
        "name": "AI", 
        "html": '<iframe src="url to your customm site with a listener inside"></iframe>',
        "position": "last"
     });
     
     .....................
     
     //At some point later
     sambaFrame.sendMessageToCustomTile({
     
        //Identifier and title of your custom tile. Must match the name in addCustomTile
        "name": "AI",
        
        //A custom event name which your tile knows about
        "event": "muteInternally",
         
        /*
          The target origin for postMessage
          https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
        */
        "origin": "*" ,
        
        //Some custom payload data if you need        
        "data": {
          "everything": true/false
        }
     });
   }
});
```

```javascript
//Somewhere in your embedded iframe custom site
<script>
  window.addEventListener("message", (event) => {
    console.log(event.data);
    alert(JSON.stringify(event.data));
  }, false);
</script>
```


# showCaptions()

Shows the captions (automatic subtitles) panel at the bottom of the screen.

```javascript
sambaFrame.showCaptions();
```

{% hint style="warning" %}
Note that captions functionality must be enabled in the settings of your room, otherwise this method won't be able to do anything meaningful. To enable captions through REST API use the **captions\_enabled** boolean field when [creating](/reference/rest-api/rooms/create) or [editing](/reference/rest-api/rooms/edit) your room.
{% endhint %}

**Sample use case**: \
Have a completely custom toolbar in your integration and you want user to be able to show/hide captions panel from a custom button in your toolbar.

{% hint style="info" %}
**showCaptions** is often used in conjuction with [hideCaptions](/reference/sdk/methods/hidecaptions) method.
{% endhint %}


# showToolbar()

Shows the application toolbar.

```javascript
sambaFrame.showToolbar();
```

**Sample use cases**:&#x20;

* You may want to hide the toolbar when user's cursor is outside the iframe and show the toolbar again when user's cursor is hovering over the iframe.
* If you have a picture-in-picture mode in your application, then you may want to hide the toolbar when you go into picture-in-picture and show the toolbar after you exit the picture-in-picture.

{% hint style="info" %}
**showToolbar** is often used in conjunction with the [hideToolbar](/reference/sdk/methods/hidetoolbar) method.
{% endhint %}


# showTopbar()

Shows the application topbar.

```javascript
sambaFrame.showTopbar();
```

**Sample use cases**:&#x20;

* You may want to show/hide the topbar conditionally based on your integration logic

{% hint style="info" %}
**showTopbar** is often used in conjunction with the [hideTopbar](/reference/sdk/methods/hidetopbar) method.
{% endhint %}


# startRecording()

Starts a cloud recording of the meeting. The result **mp4** file will be available in your team dashboard after recording is stopped and processed.

```javascript
sambaFrame.startRecording();
```

The related event is [recordingStarted](/reference/sdk/events/recordingstarted), if you want to be informed when a recording is started.

{% hint style="info" %}
The method call will be ignored if recordings are not enabled for the room or if a room recording is already in progress.
{% endhint %}

**Sample use cases**:&#x20;

* You may want to record the meeting, so participants can review it after. Especially useful in educational scenarios.

{% hint style="info" %}
**startRecording** is often used in conjunction with [stopRecording](/reference/sdk/methods/stoprecording) method.
{% endhint %}


# startRestreaming()

The user who invoked the method will see a popup to enter the details of the target platform to restream to and start it.

```javascript
sambaFrame.startRestreaming();
```

{% hint style="info" %}
The method call will be ignored if restreaming is not enabled for the room or if a room restreaming is already in progress.
{% endhint %}

**Sample use cases**:&#x20;

* You may want to restream the meeting to a larger audience on Youtube, Cloudflare, etc...

{% hint style="info" %}
**startRestreaming** is often used in conjunction with [stopRecording](/reference/sdk/methods/stoprecording) method.
{% endhint %}


# startScreenshare()

Makes the browser show the screenshare modal, so user can choose to share the entire screen or only a concrete specific window/tab.

```javascript
sambaFrame.startScreenshare();
```

**Sample use case**: \
Have a custom toolbar in your integration and want user to control screenshare from it.

{% hint style="info" %}
The related event is [screenshareStarted](/reference/sdk/methods/startscreenshare), if you want to be informed when a user starts a screenshare.
{% endhint %}


# stopRecording()

Stops the recording of the meeting. The result **mp4** file will be available in your team dashboard soon after it is processed.

```javascript
sambaFrame.stopRecording();
```

The related event is [recordingStopped](/reference/sdk/events/recordingstopped), if you want to be informed when a recording is stopped.

{% hint style="info" %}
The method call will be ignored if recordings are not enabled for the room or if a room recording is not in progress.
{% endhint %}

**Sample use cases**:&#x20;

* You may want to control recording of the meeting, so participants can review it after. Especially useful in educational scenarios.

{% hint style="info" %}
**stopRecording** is often used in conjunction with [startRecording](/reference/sdk/methods/startrecording) method.
{% endhint %}


# stopRestreaming()

Stops the restreaming of the meeting.

```javascript
sambaFrame.stopRestreaming();
```

{% hint style="info" %}
The method call will be ignored if restreaming is not enabled for the room or if a room restreaming is not in progress.
{% endhint %}

**Sample use cases**:&#x20;

* You may want to control restreaming of the meeting to a larger audience on Youtube, Cloudflare, etc...

{% hint style="info" %}
**stopRestreaming** is often used in conjunction with [startRecording](/reference/sdk/methods/startrecording) method.
{% endhint %}


# stopScreenshare()

Stops user's screenshare. The browser will stop publishing user's screen.

```javascript
sambaFrame.stopScreenshare();
```

**Sample use case**: \
Have a custom toolbar in your integration and want user to control screensharing from it.

{% hint style="info" %}
The related event is [screenshareStopped](/reference/sdk/events/screensharestopped), if you want to be informed when a user stops screensharing.
{% endhint %}


# toggleAudio()

toggleAudio(newState?: boolean)

Toggles user's microphone state.

If the microphone is currently enabled, then it will be disabled. And vice-versa -> if the microphone is currently disabled, then it will be enabled. There is also an optional param to set a concrete target microphone state, but you may use [disableAudio()](/reference/sdk/methods/disableaudio) and [enableAudio()](/reference/sdk/methods/enableaudio) to achieve similar functionality.

```javascript
//This will toggle the microphone state
sambaFrame.toggleAudio();

//This will enable the microphone, equivalent to sambaFrame.enableAudio();
sambaFrame.toggleAudio(true); 

//This will disable the microphone, equivalent to sambaFrame.disableAudio();
sambaFrame.toggleAudio(false);
```

**Sample use case**: \
Have a custom toolbar in your integration and want user to control microphone from it.


# toggleCaptions()

toggleCaptions(newState?: boolean)

Toggles the captions panel visibility state.&#x20;

If the captions panel is currently shown, then it will be hidden. And vice-versa -> if the captions panel is currently hidden, then it will be shown. There is also an optional param to set a concrete target visibility state, but you may use [hideCaptions()](/reference/sdk/methods/hidecaptions) and [showCaptions()](/reference/sdk/methods/showcaptions) to achieve similar functionality.

```javascript
//This will toggle the captions panel visibility state
sambaFrame.toggleCaptions();

//This will show the captions panel, equivalent to sambaFrame.showCaptions();
sambaFrame.toggleCaptions(true); 

//This will hide the captions panel, equivalent to sambaFrame.hideCaptions();
sambaFrame.toggleCaptions(false);
```

**Sample use case**: \
You may have a custom button in your application to control the captions panel visibility.


# toggleMuteFrame()

toggleMuteFrame(newState?: boolean)

Toggles the mute state of the video conference frame. If frame is not muted it will become muted and vice-versa. Note that this doesn't affect other (remote) users. The method behaves like muting or unmuting your browser tab - affects only local user.

```javascript
//This will toggle the frame mute state
sambaFrame.toggleMuteFrame();

//This will mute the frame, equivalent to sambaFrame.muteFrame();
sambaFrame.toggleMuteFrame(true); 

//This will unmute the frame, equivalent to sambaFrame.unmuteFrame();
sambaFrame.toggleMuteFrame(false);
```

**Sample use cases**:&#x20;

* Having the conference loaded in the background and muted from user until a certain event happens. At some point you will want to unmute it, so user can participate.


# toggleToolbar()

toggleToolbar(newState?: boolean)

Toggles the application toolbar visibility state.&#x20;

If the toolbar is currently shown, then it will be hidden. And vice-versa -> if the toolbar is currently hidden, then it will be shown. There is also an optional param to set a concrete target visibility state, but you may use [hideToolbar()](/reference/sdk/methods/hidetoolbar) and [showToolbar()](/reference/sdk/methods/showtoolbar) to achieve similar functionality.

```javascript
//This will toggle the toolbar visibility state
sambaFrame.toggleToolbar();

//This will show the toolbar, equivalent to sambaFrame.showToolbar();
sambaFrame.toggleToolbar(true); 

//This will hide the toolbar, equivalent to sambaFrame.hideToolbar();
sambaFrame.toggleToolbar(false);
```

**Sample use case**: \
You may have a button in your application to control the toolbar visibility.


# toggleTopbar()

toggleTopbar(newState?: boolean)

Toggles the application topbar visibility state (which includes the logo and tile mode switcher).&#x20;

If the topbar is currently shown, then it will be hidden. And vice-versa -> if the topbar is currently hidden, then it will be shown. There is also an optional param to set a concrete target visibility state, but you may use [hideTopbar()](/reference/sdk/methods/hidetopbar) and [showTopbar() ](/reference/sdk/methods/showtopbar)to achieve similar functionality.

```javascript
//This will toggle the topbar visibility state
sambaFrame.toggleTopbar();

//This will show the topbar, equivalent to sambaFrame.showTopbar();
sambaFrame.toggleTopbar(true); 

//This will hide the topbar, equivalent to sambaFrame.hideTopbar();
sambaFrame.toggleTopbar(false);
```

**Sample use case**: \
You may have a button in your application to control the topbar visibility.


# toggleVideo()

toggleVideo(newState?: boolean)

Toggles user's camera state.

If the camera is currently enabled, then it will be disabled. And vice-versa -> if the camera is currently disabled, then it will be enabled. There is also an optional param to set a concrete target camera state, but you may use [disableVideo()](/reference/sdk/methods/disablevideo) and [enableVideo()](/reference/sdk/methods/enablevideo) to achieve similar functionality.

```javascript
//This will toggle the camera state
sambaFrame.toggleVideo();

//This will enable the camera, equivalent to sambaFrame.enableVideo();
sambaFrame.toggleVideo(true); 

//This will disable the camera, equivalent to sambaFrame.disableVideo();
sambaFrame.toggleVideo(false);
```

**Sample use case**: \
Have a custom toolbar in your integration and want user to control camera from it.


# toggleWhiteboard()

toggleWhiteboard(show: boolean, id: string)

Sets a concrete whiteboard visibility state.

```javascript
//This will open the whiteboard, equivalent to sambaFrame.openWhiteboard(...);
sambaFrame.toggleWhiteboard(true, 'c0771004-c9fc-4308-be4f-6264d8e486af'); 

//This will close the whiteboard, equivalent to sambaFrame.closeWhiteboard(...);
sambaFrame.toggleWhiteboard(false, 'c0771004-c9fc-4308-be4f-6264d8e486af');
```

**Sample use case**: \
You may have a button in your application to control the whiteboard visibility.


# toggleLibraryFile()

toggleLibraryFile(id?: string, show?: boolean)

Toggles a concrete file's open/close state.

If the file is currently opened, then it will be closed. And vice versa -> if the file is currently closed, then it will be opened. There is also an optional param to set a concrete target state, but you may use [closeLibraryFile()](/reference/sdk/methods/closelibraryfile) and [openLibraryFile()](/reference/sdk/methods/openlibraryfile) to achieve similar functionality.

```javascript
//This will toggle the file's open/close state
sambaFrame.toggleLibraryFile('c0771004-c9fc-4308-be4f-6264d8e486af');

//This will open the file, equivalent to sambaFrame.openLibraryFile();
sambaFrame.toggleLibraryFile('c0771004-c9fc-4308-be4f-6264d8e486af', true); 

//This will close the file, equivalent to sambaFrame.closeLibraryFile();
sambaFrame.toggleLibraryFile('c0771004-c9fc-4308-be4f-6264d8e486af', false);
```

**Sample use case**: \
You may have buttons in your integration to control file opening and closing.


# unmuteFrame()

Unmutes a previously muted frame. Note that this doesn't affect other (remote) users. The method behaves like unmuting your browser tab - affects only local user.

```javascript
sambaFrame.unmuteFrame();
```

**Sample use cases**:&#x20;

* Having the conference loaded in the background and muted from user until a certain event happens and you want to unmute it, so user can finally participate in the conference.

{% hint style="info" %}
**unmuteFrame** is often used in conjunction with the [muteFrame](/reference/sdk/methods/muteframe) method.
{% endhint %}


# unpinUser()

Unpins the currently pinned content.

<pre class="language-javascript"><code class="lang-javascript"><strong>sambaFrame.unpinUser();
</strong></code></pre>

**Sample use cases**:&#x20;

* Wanting to unpin the currently pinned content.

{% hint style="info" %}
**unpinUser** is often used in conjunction with the [pinUser](/reference/sdk/methods/pinuser) method.
{% endhint %}


# Events

With events you can subscribe to various things which are happening inside the room.

For example you may want to hide the iframe when user leaves the meeting -> then you will subscribe to the [userLeft](/reference/sdk/events/userleft) event. For the full list of events please have a look at the navigation bar on the left.

You will subscribe to an event with the [on()](/reference/sdk/methods/on) method and unsubscribe with the [off()](/reference/sdk/methods/off) method.\
There is also the [once()](/reference/sdk/methods/once) method for subscription, but it's only a one-time subscription and is used rarely in general. The events architecture is built upon the commonly used [EventEmitter](https://nodejs.org/api/events.html#class-eventemitter) interface.

#### Templates for subscription/unsubscription:

```javascript
sambaFrame.on('eventNameHere', (event) => {
   //Execute your own custom logic here
});

sambaFrame.once('eventNameHere', (event) => {
   //This will execute ONLY ONCE, even if the event happens a hundred times
});

const myCallback = (event) => {
   //Execute your own custom logic here
});
sambaFrame.on('eventNameHere', myCallback);
//........................................

//Unsubscribe if you want at some point later
sambaFrame.off('eventNameHere', myCallback);
```

{% hint style="info" %}
There is a special event named '**\***', which can be useful for debugging purposes to see all incoming events and their data.\
\
`sambaFrame.on('*', (event) => {`&#x20;

&#x20;  `console.log(event);`

`});`
{% endhint %}


# activeSpeakerChanged

Emitted when a different user starts speaking inside the room. This can be useful if you want to display information in your app which user is currently speaking inside the room.&#x20;

#### Sample payload

```json
{
  "type": "activeSpeakerChanged",
  "data": {
    "type": "local",
    "user": {
      "id": "2775f882-845e-4416-82c9-04cc25669c0b",
      "name": "John Smith",
      ........................
    }
  }
}
```

#### Sample subscription code

```javascript
sambaFrame.on('activeSpeakerChanged', (event) => {
  const data = event.data;
  if (data.type === 'local') {
     console.log('You are now speaking...');
  } else {
     console.log(data.user.name, 'is now speaking...');
  }
});
```


# appError

Emitted when something unexpected or not allowed happens in the room.

#### Here is a list of the possible error names:

* `permissions-rejected` -> emitted when user tries to screen share, but browser doesn't have enough permissions for it
* `not-allowed` -> emitted when a not allowed action was requested by the user. For example if a user tries to start a recording and recording is not supported in the room, you will receive a `not-allowed` type.
* `forbidden-action` -> emitted when a forbidden action was requested by the user. For example if a user tries to end a session and doesn't have a permission to do so, then the `forbidden-action` type.
* `authorization-failed` -> emitted when a user's authorization into the room is rejected — for example a display name that fails room validation.
* `command-failed` -> emitted when an SDK method call fails to be processed on the room side. The `data.command` field tells you which method failed. **If `data.command` is `"connect"`, treat this as fatal**: the room did not finish loading and will not recover on its own — reload the iframe or show your own error state rather than treating it as a single failed call.
* `virtual-bg` -> emitted for virtual background problems. Historically this covered invalid `configureVirtualBackground()` options only; it now also reports that a requested virtual background **was not applied**. See [Virtual background not applied](#virtual-background-not-applied) below.

#### Sample payload

```json
{
  "type": "appError",
  "data": {
      "name": "not-allowed",
      "message": "Recording disabled. You’ll need to edit this room’s properties to record sessions in this room",
      "data": {
         "type": "recording"
      }
  }
}
```

Starting from `v0.0.58` of `@digitalsamba/embedded-sdk`, `not-allowed` can also occur when you call a session-only command (recording, screenshare, whiteboard actions, remote-user actions, hand raise/lower, and similar) before you've joined the session, or after you've left or the session has ended. In that case `data.type` is `"not-joined"` and `data` also includes the command name:

```json
{
  "type": "appError",
  "data": {
    "name": "not-allowed",
    "message": "Command \"removeUser\" requires an active session",
    "data": {
      "type": "not-joined",
      "command": "removeUser"
    }
  }
}
```

If your integration inspects `data` on `not-allowed` errors, make sure it tolerates `data.type` values it doesn't recognize yet and the additional `data.command` field — don't assume `data` only ever has a `type` key.

```json
{
  "type": "appError",
  "data": {
      "name": "forbidden-action",
      "message": "Forbidden action. This participant is not allowed to end session",
      "data": {
         "type": "end-session"
      }
  }
}
```

```json
{
  "type": "appError",
  "data": {
    "name": "authorization-failed",
    "message": "User authorization failed",
    "data": {
      "message": "<underlying error message>"
    }
  }
}
```

```json
{
  "type": "appError",
  "data": {
    "name": "command-failed",
    "message": "Failed to process SDK command \"startRecording\"",
    "data": {
      "command": "startRecording"
    }
  }
}
```

`message` on `command-failed` always follows the template `Failed to process SDK command "<command>"`, where `<command>` is the exact method/command name you called.

## Virtual background not applied

A virtual background you requested can end up not being applied — either because the participant's device cannot run virtual backgrounds at all, or because applying it failed. Previously this was silent: the participant simply kept their raw camera and your application was never told. It is now reported as an `appError` with `name: "virtual-bg"` and a `data.reason` field.

This matters most when you pass `enforce: true` to [configureVirtualBackground()](/reference/sdk/methods/configurevirtualbackground), because the virtual background panel is hidden from the participant, so nobody in the session notices either.

#### Sample payload

```json
{
  "type": "appError",
  "data": {
    "name": "virtual-bg",
    "message": "Virtual background was not applied: this device cannot run virtual backgrounds",
    "data": {
      "reason": "unsupported",
      "virtualBackgroundConfig": {
        "enabled": true,
        "type": "blur",
        "name": "blur-balanced",
        "enforced": true,
        "value": {
          "src": "balanced",
          "thumb": "<thumbnail url>",
          "alt": "<label>"
        }
      }
    }
  }
}
```

`data.virtualBackgroundConfig` describes **the background you requested**, in exactly the same shape as the [virtualBackgroundChanged](/reference/sdk/events/virtualbackgroundchanged) event — not the background that is now active. It is the requested configuration precisely because that configuration was *not* applied.

#### `data.reason`

| Value         | Meaning                                                                                                            |
| ------------- | ------------------------------------------------------------------------------------------------------------------ |
| `unsupported` | This device cannot run virtual backgrounds. The request is refused; the participant continues on their raw camera. |
| `failed`      | The device can run virtual backgrounds, but applying this one failed.                                              |

{% hint style="info" %}
**Telling the new events apart from the legacy ones.** `name: "virtual-bg"` is also used for invalid `configureVirtualBackground()` options (an unknown image name, a missing `thumbnailUrl`, and similar). Those carry no `data.reason`. Branch on the presence of `data.reason`, not on the name alone.
{% endhint %}

#### Sample subscription code

```javascript
sambaFrame.on('appError', (event) => {
  const error = event.data; // { name, message, data }

  if (error.name !== 'virtual-bg' || !error.data?.reason) {
    return; // not a "not applied" report — a legacy option-validation error
  }

  if (error.data.reason === 'unsupported') {
    console.warn('This participant cannot run virtual backgrounds — they are on a raw camera.');
  } else {
    console.warn('Applying the virtual background failed.');
  }

  console.log('Requested background was:', error.data.virtualBackgroundConfig);
});
```

#### Timing and how often it fires

{% hint style="warning" %}
Two behaviours worth designing around before you treat this event as a one-shot signal:

* **`unsupported` can arrive up to \~30 seconds after your `configureVirtualBackground()` call, and before the participant has joined.** The room re-probes the device's graphics capability for about 30 seconds before accepting a refusal, because a device that reports no capability at page load frequently recovers within that window. You get one `unsupported` event per `configureVirtualBackground()` command, so a page reload or a second call means another event.
* **`failed` can be reported more than once in a session for the same request.** A configured background is re-attempted when the participant joins, joins a breakout room, and when broadcasting restarts. Each attempt that fails reports its own event. Every one of them is individually true — an activation was attempted and it failed — so treat them as repeated attempts rather than distinct problems, and de-duplicate on your side if you only want to warn the presenter once.
  {% endhint %}

If the background is applied successfully on a later attempt, you receive a normal [virtualBackgroundChanged](/reference/sdk/events/virtualbackgroundchanged) event. A `virtual-bg` `appError` is never retracted, so the last VB event you received is always the current truth.


# appLanguageChanged

Emitted when the user selects a different UI language.

#### Sample payload

```json
{
    "type": "appLanguageChanged",
    "data": {
        "language": "de"
    }
}
```

#### Sample subscription code

```javascript
sambaFrame.on('appLanguageChanged', (event) => {
  const data = event.data;
  console.log('New language is:', data.language);
});
```


# audioDisabled

Emitted when a user disables his microphone. You can discriminate between the **local** user and **remote** users by the `type` field inside the event `data`.

#### Sample payload

```json
{
  "type": "audioDisabled",
  "data": {
    "type": "local",
    "user": {
      "id": "2775f882-845e-4416-82c9-04cc25669c0b",
      "name": "John Smith",
      ........................
    }
  }
}
```

#### Sample subscription code

```javascript
sambaFrame.on('audioDisabled', (event) => {
  const data = event.data;
  if (data.type === 'local') {
     console.log('You have disabled your microphone');
  } else {
     console.log(data.user.name, 'has disabled microphone');
  }
});
```


# audioEnabled

Emitted when a user enables his microphone. You can discriminate between the **local** user and **remote** users by the `type` field inside the event `data`.

#### Sample payload

```json
{
  "type": "audioEnabled",
  "data": {
    "type": "local",
    "user": {
      "id": "2775f882-845e-4416-82c9-04cc25669c0b",
      "name": "John Smith",
      ........................
    }
  }
}
```

#### Sample subscription code

```javascript
sambaFrame.on('audioEnabled', (event) => {
  const data = event.data;
  if (data.type === 'local') {
     console.log('You have enabled your microphone');
  } else {
     console.log(data.user.name, 'has enabled microphone');
  }
});
```


# captionsDisabled

Emitted when the local user closes the captions panel.

#### Sample payload

```json
{
  "type": "captionsDisabled"
}
```

#### Sample subscription code

```javascript
sambaFrame.on('captionsDisabled', (event) => {
  console.log('Local user disabled captions');
});
```


# captionsEnabled

Emitted when the local user opens the captions panel.

#### Sample payload

```json
{
  "type": "captionsEnabled"
}
```

#### Sample subscription code

```javascript
sambaFrame.on('captionsEnabled', (event) => {
  console.log('Local user enabled captions');
});
```


# captionsFontSizeChanged

When the user changes the captions font size from the settings inside the room, then the **captionsFontSizeChanged** event will be emitted.

{% hint style="info" %}
You can also change the captions font size programmatically through the SDK. Use the [configureCaptions](/reference/sdk/methods/configurecaptions) method to achieve that.
{% endhint %}

#### Sample payload

```json
{
  "type": "captionsFontSizeChanged",
  "data": {
    "fontSize": "large"
  }
}
```

#### Sample subscription code

```javascript
sambaFrame.on('captionsFontSizeChanged', (event) => {
  const data = event.data;
  //Possible values for "fontSize" field are "small", "medium" and "large"
  console.log('Captions font size has been changed to', data.fontSize);
});
```


# captionsSpokenLanguageChanged

When the user changes his captions spoken language from the settings inside the room, then the **captionsSpokenLanguageChanged** event will be emitted.

{% hint style="info" %}
You can also change the captions spoken language programmatically through the SDK. Use the [configureCaptions](/reference/sdk/methods/configurecaptions) method to achieve that.
{% endhint %}

#### Sample payload

```json
{
  "type": "captionsSpokenLanguageChanged",
  "data": {
    "language": "de"
  }
}
```

#### Sample subscription code

```javascript
sambaFrame.on('captionsSpokenLanguageChanged', (event) => {
  const data = event.data;
  //Possible values for "language" field are language codes described in the docs of configureCaptions event
  console.log('Captions spoken language has been changed to', data.language);
});
```


# chatMessageReceived

Emitted when a new chat message has been received.

You can use that event to play a chime sound on receiving a message or to display chat messages in a custom way in your integration. Note the **local** boolean flag in the message - it tells if this message was sent by the local user (yourself). For example if you are going to play a chime sound on receiving a message, then you would not want to do it when **local** flag is **true**.

#### Sample payload

```json
{
    "type": "chatMessageReceived",
    "data": {
        "message": {
            "id": "ceb29418-3aa7-4354-9fe6-9875b9b260cf",
            "message": "How are you?",
            "date": "2024-06-11T08:23:16Z",
            //If it was sent by the local user (yourself)
            "local": true,
            "privateGroup": true/false,
            "user": {
               "name": "John Smith",
               "avatarColor": "#4ecdc4",
               "role": "moderator",
               "id": "862f90f8-5a66-4b24-befb-7343a9fd34aa"
            }
        }
        //Contains detailed information if chat panel is opened and which section
        "chatState": {
           "panelOpen": true,
           "activeTab": "public", //public or private
           "privateChatActiveView": {
              //"list" or "personal" depending on if private list is opened or a concrete personal private chat
              "name": "list",
              "data": {
                 //uuid of the user who you are having private chat with
                 "id": "..uuid...",
                 //If the opened chat is the group chat
                 "group": true/undefined
              }
           }
        }    
    }
}
```

#### Sample subscription code

```javascript
sambaFrame.on('chatMessageReceived', (event) => {
  const data = event.data;
  console.log('New chat message is:', data.message);
});
```


# connectionFailure

Emitted when the application cannot connect to the backend - it's a fatal error.\
The error could be caused by a bad internet connection or a firewall blocking the traffic.

#### Sample payload

```json
{
  "type": "connectionFailure"
}
```

#### Sample subscription code

```javascript
sambaFrame.on('connectionFailure', (data) => {
   //Do something custom and inform user
});
```


# featureSetUpdated

Emitted when the features set changes. The updated features are included in the payload.

Read about the features specification in the [features](/reference/sdk/properties/features) property.

{% hint style="info" %}
You can access the latest features set directly through the [features](/reference/sdk/properties/features) property.
{% endhint %}

#### Sample payload

```json
{
  "type": "featureSetUpdated",
  "data": {
    "state": {
        //Look at the features property for full payload description
    }
  }
}
```

#### Sample subscription code

```javascript
sambaFrame.on('featureSetUpdated', (event) => {
  const features = event.data.state;
  //Read some properties from the updated feature state
  console.log('Chat state is:', features['chat']);
});
```


# frameLoaded

Emitted when the iframe has finished loading -> corresponds to the iframe onload event.

{% hint style="danger" %}
Do **NOT** manually subscribe to the **sambaFrame.frame.onload** event, because it will override the internal handler of our SDK and app won't function. Subscribe to the **frameLoaded** instead as shown if you want to listen to the **onload** event of the iframe.
{% endhint %}

#### Sample subscription code

```javascript
sambaFrame.on('frameLoaded', () => {
  console.log('The iframe has been loaded');
});
```


# handRaised

Emitted when a user raises a hand. You can discriminate between the **local** user and **remote** users by the `type` field inside the event `data`.

#### Sample payload

```json
{
  "type": "handRaised",
  "data": {
    "type": "local",
    "user": {
      "id": "2775f882-845e-4416-82c9-04cc25669c0b",
      "name": "John Smith",
      ........................
    }
  }
}
```

#### Sample subscription code

```javascript
sambaFrame.on('handRaised', (event) => {
  const data = event.data;
  if (data.type === 'local') {
     console.log('You have raised a hand');
  } else {
     console.log(data.user.name, 'has raised a hand');
  }
});
```


# handLowered

Emitted when a user lowers a hand. You can discriminate between the **local** user and **remote** users by the `type` field inside the event `data`.

#### Sample payload

```json
{
  "type": "handLowered",
  "data": {
    "type": "local",
    "user": {
      "id": "2775f882-845e-4416-82c9-04cc25669c0b",
      "name": "John Smith",
      ........................
    }
  }
}
```

#### Sample subscription code

```javascript
sambaFrame.on('handLowered', (event) => {
  const data = event.data;
  if (data.type === 'local') {
     console.log('You have lowered hand');
  } else {
     console.log(data.user.name, 'has lowered hand');
  }
});
```


# layoutModeChanged

There are two layout modes provided inside the room - `Tiled Mode (`**`tiled`**`)` and `Automatic Mode (`**`auto`**`)`.

In `Automatic Mode` the current active speaker is being displayed in a larger tile and also fine-grain controls like pinning and fullscreen are hidden from the layout.

When the user changes the layout mode by clicking on the mode switcher, the **layoutModeChanged** event will be emitted.

{% hint style="info" %}
You can also change the layout mode programmatically through the SDK. Use the [changeLayoutMode](/reference/sdk/methods/changelayoutmode) method to achieve that.
{% endhint %}

#### Sample payload

```json
{
  "type": "layoutModeChanged",
  "data": {
    "mode": "tiled"
  }
}
```

#### Sample subscription code

```javascript
sambaFrame.on('layoutModeChanged', (event) => {
  const data = event.data;
  //Possible values for "mode" field are "tiled" and "auto"
  console.log('Layout mode has been changed to', data.mode);
});
```


# mediaConnectionFailed

Emitted when the media plane (audio/video) cannot be established or sustained, even though the signaling connection (WebSocket) remains functional. This event lets integrators branch fallback UX — such as HLS playback, dial-in, or a custom retry flow — based on which direction failed and whether a fresh rejoin is likely to help.

The event fires once per failed peer connection for the remainder of that connection's lifetime. Rejoining the room or re-establishing a new peer connection starts a fresh evaluation.

### Sample payload

```json
{
  "type": "mediaConnectionFailed",
  "data": {
    "direction": "subscribing",
    "cause": "network_blocked"
  }
}
```

### Parameters

<table><thead><tr><th width="116.1015625">Parameter</th><th width="264.71875">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>direction</code></td><td><code>'publishing' | 'subscribing'</code></td><td>Which media flow failed. <code>subscribing</code> — the participant cannot receive remote audio/video (silent room). <code>publishing</code> — the participant cannot deliver their own audio/video (others see/hear nothing from them). Both directions can fail independently and each triggers its own event.</td></tr><tr><td><code>cause</code></td><td><code>'network_blocked' | 'connection_failed'</code></td><td>Why the failure is terminal. <code>network_blocked</code> — the network prevented ICE from gathering any candidates (typically corporate DPI, strict firewall, or port restrictions blocking STUN/TURN). Rejoining the same room on the same network will fail identically. <code>connection_failed</code> — ICE gathered candidates but could not establish or maintain a working path, even after an automatic restart attempt. A fresh peer connection via rejoin may succeed if the underlying issue was transient.</td></tr></tbody></table>

### Usage example

```javascript
sambaFrame.on('mediaConnectionFailed', ({ direction, cause }) => {
  if (cause === 'network_blocked') {
    // Rejoining on the same network will not help.
    // Suggest switching networks, or swap to a fallback transport (e.g. HLS, dial-in).
    showNetworkBlockedFallback({ direction });
  } else {
    // cause === 'connection_failed' — the issue may be transient.
    // Offer a retry, or let the user dismiss and try rejoining.
    showConnectionFailedRetry({ direction });
  }
});
```

### Remarks

{% hint style="info" %}
The event pairs with the built-in "Media connection failed" modal, which shows direction- and cause-aware copy. Integrators implementing their own fallback UX can dismiss or hide the built-in modal.
{% endhint %}

* `cause: 'network_blocked'` corresponds to zero ICE candidates gathered after ICE negotiation. This is a strong signal of network-layer blocking.
* `cause: 'connection_failed'` fires when an ICE restart attempt fails to re-establish connectivity on a previously-negotiated peer connection.
* Fires independently for publishing and subscribing directions. A single session can emit both if both directions fail.
* Distinct from `connectionFailure`, which fires for signaling-layer (WebSocket) connection failures, not media-layer failures.


# mediaDeviceChanged

Emitted when the user selects a different camera, microphone or speakers device.

The **kind** property can be:

* videoinput - for camera
* audioinput - for microphone
* audiooutput - for speakers

#### Sample payloads

```json
{
    "type": "mediaDeviceChanged",
    "data": {
      "kind": "videoinput OR audioinput OR audiooutput",
      "label": "HD Pro Webcam C920 (046d:082d)",
      "previousDeviceLabel": "Logi Capture",
      "availableDevices": [
        An array of all available devices of all types, following these specs:
        https://developer.mozilla.org/en-US/docs/Web/API/MediaDeviceInfo
      ]
    }
}
```

#### Sample subscription code

```javascript
sambaFrame.on('mediaDeviceChanged', (event) => {
  const data = event.data;
  console.log('New device id:', data.deviceId);
});
```


# permissionsChanged

When a user gives/revokes your broadcast or screenshare permissions, then the **permissionsChanged** event will be emitted. Such users are typically moderators who are capable of managing other users' permissions.

{% hint style="info" %}
Typical use-case for listening to this event is to show camera and microphone icons in your custom toolbar when the user receives permissions to broadcast.
{% endhint %}

#### Sample payload

```json
{
    "type": "permissionsChanged",
    "data": {
       "broadcast": true,           // Legacy field, true if either audio or video is allowed
       "broadcastAudio": true,      // New field, true if audio broadcasting is allowed
       "broadcastVideo": true,      // New field, true if video broadcasting is allowed
       "screenshare": true
    }
}
```

#### Sample subscription code

```javascript
sambaFrame.on('permissionsChanged', (event) => {
  const data = event.data;
  
  if (data.broadcast !== undefined) {
    if (data.broadcast) {
      console.log('You were granted broadcast permission')
    } else {
      console.log('Your permission to broadcast was revoked')
    }
  }
  
  // New way - using granular broadcast permissions
  if (data.broadcastAudio !== undefined) {
    if (data.broadcastAudio) {
      console.log('You were granted audio broadcast permission')
    } else {
      console.log('Your audio broadcast permission was revoked')
    }
  }

  if (data.broadcastVideo !== undefined) {
    if (data.broadcastVideo) {
      console.log('You were granted video broadcast permission')
    } else {
      console.log('Your video broadcast permission was revoked')
    }
  }

  if (data.screenshare !== undefined) {
    if (data.screenshare) {
      console.log('You were granted screenshare permission')
    } else {
      console.log('Your permission to screenshare was revoked')
    }
  }
});
```


# recordingFailed

Emitted when a recording has failed due to an unexpected error.&#x20;

#### Sample payload

```json
{
  "type": "recordingFailed"
}
```

#### Sample subscription code

```javascript
sambaFrame.on('recordingFailed', (event) => {
  console.log('Recording has failed');
});
```




---

[Next Page](https://docs.digitalsamba.com/reference/llms-full.txt/1)

