> ## Documentation Index
> Fetch the complete documentation index at: https://docs.corti.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Ambient Web Component

> Drop-in web component for real-time multi-speaker ambient streaming

The `@corti/ambient-web` package provides a set of custom elements that handle microphone management, audio streaming, transcript delivery, and facts on top of the Corti API. It works with any frontend framework or plain HTML.

<Info>
  **Package:** [@corti/ambient-web on npm](https://www.npmjs.com/package/@corti/ambient-web) | **Examples:** [corti-examples/ambient](https://github.com/corticph/corti-examples/tree/main/ambient)
</Info>

The library provides two usage modes:

1. **`<corti-ambient>`** -- opinionated, all-in-one component with built-in UI (recommended for most use cases)
2. **Modular components** -- individual building blocks (`<ambient-root>`, `<ambient-recording-button>`, etc.) for fully custom layouts

<Tip>Looking for single-speaker dictation with voice commands? See the [Dictation Web Component](/sdk/dictation/overview).</Tip>

<Note>
  OAuth 2.0 authentication is not handled by this library. The client must provide an authorization token or token refresh function while using the component. Each ambient session also requires an `interactionId`.
</Note>

## Installation

<CodeGroup>
  ```bash npm theme={null}
  npm install @corti/ambient-web
  ```

  ```bash yarn theme={null}
  yarn add @corti/ambient-web
  ```

  ```bash pnpm theme={null}
  pnpm add @corti/ambient-web
  ```

  ```html CDN theme={null}
  <script type="module" src="https://cdn.jsdelivr.net/npm/@corti/ambient-web/dist/bundle.js"></script>
  ```
</CodeGroup>

### Module import

```ts theme={null}
// Side-effect import -- registers all custom elements
import "@corti/ambient-web";

// Named imports -- access component classes directly
import { CortiAmbient } from "@corti/ambient-web";
```

## Quick start

```html theme={null}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Corti Ambient</title>
    <script type="module" src="https://cdn.jsdelivr.net/npm/@corti/ambient-web/dist/bundle.js"></script>
</head>
<body>
    <corti-ambient id="ambient" interactionId="<your-interaction-id>"></corti-ambient>

    <script>
        const ambient = document.getElementById("ambient");

        ambient.addEventListener("ready", () => {
            ambient.accessToken = "<your-access-token>";
            ambient.ambientConfig = {
                transcription: { primaryLanguage: "en" },
                mode: { type: "facts", outputLocale: "en" },
            };
        });

        ambient.addEventListener("transcript", (event) => {
            // Segments can arrive out of order across speakers — order by time.start
            [...event.detail.data]
                .sort((a, b) => a.time.start - b.time.start)
                .forEach((seg) => {
                    console.log(`[${seg.time.start}s → ${seg.time.end}s]: ${seg.transcript}`);
                });
        });

        ambient.addEventListener("facts", (event) => {
            event.detail.fact.forEach((fact) => {
                console.log(`Fact [${fact.group}]: ${fact.text}`);
            });
        });
    </script>
</body>
</html>
```

<Tip>The component handles microphone permissions, device selection, and audio streaming automatically. You only need to provide authentication, an interaction ID, and listen for events.</Tip>

***

## Configuration

Set `ambientConfig` as a JavaScript property to configure the stream. The type matches the [`StreamConfig`](/api-reference/streams) from the Streams WebSocket API.

When using `mode.type: "facts"`, you must also set `mode.outputLocale` (the language for extracted facts).

```js theme={null}
const ambient = document.querySelector("corti-ambient");

ambient.ambientConfig = {
    transcription: { primaryLanguage: "en" },
    mode: { type: "facts", outputLocale: "en" },
};
```

The `interactionId` property is **required** — it identifies the session for the Streams API.

See the [Streams API Reference](/api-reference/streams) for the full configuration schema.

***

## Modular components

For custom UI layouts, use individual components inside an `<ambient-root>` parent:

<Warning>All modular components **require** an `<ambient-root>` parent to provide context. They cannot be used standalone.</Warning>

```html theme={null}
<ambient-root id="root" interactionId="<your-interaction-id>" accessToken="<your-access-token>">
    <div class="custom-layout">
        <ambient-recording-button></ambient-recording-button>
        <ambient-settings-menu settingsEnabled="device,language,virtualMode"></ambient-settings-menu>
    </div>
</ambient-root>

<script>
    const root = document.getElementById("root");
    root.addEventListener("transcript", (e) => {
        e.detail.data.forEach((seg) => {
            console.log(seg.transcript);
        });
    });
</script>
```

| Component                         | Description                                                                                                                                                                                                                     |
| :-------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `<ambient-root>`                  | Context provider. Same properties as `<corti-ambient>` (auth, config, interactionId, virtualMode, devices, keybindings). Add `noWrapper` attribute to remove default styling.                                                   |
| `<ambient-recording-button>`      | Start/stop button with audio visualization. Supports `allowButtonFocus`. Has `startRecording()`, `stopRecording()`, `toggleRecording()`, `openConnection()`, `closeConnection()` methods. Requires `interactionId` on the root. |
| `<ambient-settings-menu>`         | Settings panel with device, language, and virtual mode selectors. Supports `settingsEnabled`.                                                                                                                                   |
| `<ambient-device-selector>`       | Standalone device dropdown. Supports `disabled`.                                                                                                                                                                                |
| `<ambient-language-selector>`     | Standalone language dropdown. Supports `disabled`.                                                                                                                                                                              |
| `<ambient-keybinding-selector>`   | Keybinding configuration. Supports `keybindingType` (`"push-to-talk"` or `"toggle-to-talk"`) and `disabled`.                                                                                                                    |
| `<ambient-virtual-mode-selector>` | Virtual mode toggle. Supports `disabled`.                                                                                                                                                                                       |

See the [API Reference](/sdk/ambient/reference) for full per-component property and method tables.

***

## Virtual mode

Virtual mode captures tab/window/app audio mixed with microphone input. Enable it via the `virtualMode` attribute or property, or let users toggle it from the settings menu when `settingsEnabled` includes `"virtualMode"` (included by default on `<corti-ambient>`).

***

## Keyboard shortcuts

The component supports two keybinding modes:

| Mode               | Behavior                            | Default key |
| :----------------- | :---------------------------------- | :---------- |
| **Push-to-talk**   | Hold key to record, release to stop | `Space`     |
| **Toggle-to-talk** | Press to start, press again to stop | `Enter`     |

Configure via attributes:

```html theme={null}
<corti-ambient
    interactionId="<your-interaction-id>"
    settingsEnabled="device,language,keybinding"
    pushToTalkKeybinding="Space"
    toggleToTalkKeybinding="Enter"
></corti-ambient>
```

Keys are specified as `event.key` names (e.g. `"Space"`, `"k"`, `"Meta"`) or `event.code` values (e.g. `"KeyK"`, `"Backquote"`). Modifier combinations are not supported.

<Info>When both keybindings are set to the same key, toggle-to-talk takes priority.</Info>

### Preventing keybinding activation

Use the `keybinding-activated` event to conditionally block keybindings:

```js theme={null}
const ambient = document.querySelector("corti-ambient");

ambient.addEventListener("keybinding-activated", (event) => {
    if (document.activeElement.tagName === "TEXTAREA") {
        event.preventDefault(); // Don't trigger recording while typing
    }
});
```

***

## Attribute formatting

| Type    | Format                           | Example                                         |
| :------ | :------------------------------- | :---------------------------------------------- |
| Boolean | Presence = true, absence = false | `<corti-ambient virtualMode>`                   |
| String  | Attribute value                  | `accessToken="token"`                           |
| Array   | Comma-separated                  | `settingsEnabled="device,language,virtualMode"` |
| Object  | JavaScript property only         | `ambient.ambientConfig = { ... }`               |

***

## Resources

* **[npm package](https://www.npmjs.com/package/@corti/ambient-web)** -- latest version and install info
* **[Examples](https://github.com/corticph/corti-examples/tree/main/ambient)** -- integration examples
* **[API Reference](/sdk/ambient/reference)** -- properties, methods, and events for every component
* **[Authentication Guide](/sdk/ambient/authentication)** -- access tokens and automatic refresh
* **[Proxy Guide](/sdk/ambient/proxy)** -- route WebSocket traffic through your own server
* **[Styling Guide](/sdk/ambient/styling)** -- CSS custom properties and theming
* **[Streams API Reference](/api-reference/streams/)** -- underlying WebSocket API specification

***

<Note>For support or questions, reach out through [help.corti.app](https://help.corti.app)</Note>
