Deploying Your AgentConnections

WebRTC

Connect to an agent in the browser using the Web SDK

The Web SDK lets you embed a real-time audio and video connection to your agent directly in your web application. It provides a ready-made UI component — including the avatar widget, controls, and tooltips — that you can drop into any page.

The SDK is framework-agnostic and works with React, Vue, Angular, or vanilla JavaScript. It ships with full TypeScript support, tree-shakeable exports, and zero external dependencies in standalone mode.

For the full SDK documentation, including configuration options, event handling, and advanced usage, see the Web SDK package on npm.

Supported environments

Browsers

Chrome, Firefox, Safari, Edge

React

16.x through 19.x

Vue

2.x and 3.x

Angular

12+

Vanilla JS

No build tools required

Connecting to an agent

Create a session

Call POST /public/connections to create a WebRTC session. Specify the companion, provider configuration, and any resources you want to attach:

curl -X POST https://companion-api.napster.com/public/connections \
  -H "X-Api-Key: $NAPSTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "companionId": "comp_abc123",
    "providerConfig": {
      "voiceId": "alloy",
      "settings": {}
    },
    "functions": ["fn_tool1", "fn_tool2"],
    "faqCollections": ["faqc_01"],
    "knowledgeBaseId": "col_8f2a3b"
  }'

The response returns a token and a connection object containing the session id. Pass the token to the Web SDK — you don't need to decode it. Store the connection id on your backend to retrieve session details later, such as transcripts or duration.

For the full list of request body fields — including language, tags, external client identification, and provider settings — see Configuration.

Install the Web SDK

Install the SDK and its peer dependency:

npm install @touchcastllc/napster-companion-api @reduxjs/toolkit

Import the SDK and its stylesheet in your application:

import { NapsterCompanionApiSdk } from "@touchcastllc/napster-companion-api";
import "@touchcastllc/napster-companion-api/styles";

The stylesheet can also be loaded via a <link> tag or CSS @import if you prefer not to import it in JavaScript:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@touchcastllc/napster-companion-api@latest/lib/index.css" />

Add a single script tag to your HTML. All dependencies are bundled — no build tools required.

<script src="https://cdn.jsdelivr.net/npm/@touchcastllc/napster-companion-api@latest/lib/index.standalone.js"></script>

Initialize the SDK

Pass the token from the connection response and a container element to mount the widget into:

const widget = await NapsterCompanionApiSdk.init(token, {
  mountContainer: "#avatar-container",
});
<div id="avatar-container"></div>

<script>
  window.napsterCompanionApiSDK.init(token, {
    mountContainer: "#avatar-container",
  });
</script>

Framework examples

import React, { useEffect, useRef } from "react";
import { NapsterCompanionApiSdk } from "@touchcastllc/napster-companion-api";
import type { NapsterCompanionApiInstance } from "@touchcastllc/napster-companion-api";
import "@touchcastllc/napster-companion-api/styles";

export function CompanionWidget({ token }: { token: string }) {
  const containerRef = useRef<HTMLDivElement>(null);
  const instanceRef = useRef<NapsterCompanionApiInstance | null>(null);

  useEffect(() => {
    const initSDK = async () => {
      if (!containerRef.current) return;

      const result = await NapsterCompanionApiSdk.init(token, {
        mountContainer: containerRef.current,
        position: "bottom-right",
      });
      instanceRef.current = result;
    };

    initSDK();

    return () => {
      instanceRef.current?.destroy();
    };
  }, []);

  return <div ref={containerRef} style={{ width: "100%", height: "100%" }} />;
}
<template>
  <div ref="containerRef"></div>
</template>

<script setup lang="ts">
import { onMounted, onUnmounted, ref } from "vue";
import { NapsterCompanionApiSdk } from "@touchcastllc/napster-companion-api";
import type { NapsterCompanionApiInstance } from "@touchcastllc/napster-companion-api";
import "@touchcastllc/napster-companion-api/styles";

const props = defineProps<{ token: string }>();
const containerRef = ref<HTMLElement>();
let instance: NapsterCompanionApiInstance | null = null;

onMounted(async () => {
  if (!containerRef.value) return;

  instance = await NapsterCompanionApiSdk.init(props.token, {
    mountContainer: containerRef.value,
    position: "bottom-right",
  });
});

onUnmounted(() => {
  instance?.destroy();
});
</script>
import {
  Component,
  OnInit,
  OnDestroy,
  ElementRef,
  ViewChild,
  Input,
} from "@angular/core";
import {
  NapsterCompanionApiSdk,
  NapsterCompanionApiInstance,
} from "@touchcastllc/napster-companion-api";

@Component({
  selector: "app-companion",
  template: "<div #containerRef></div>",
})
export class CompanionComponent implements OnInit, OnDestroy {
  @Input() token!: string;
  @ViewChild("containerRef") containerRef!: ElementRef<HTMLDivElement>;
  private instance: NapsterCompanionApiInstance | null = null;

  async ngOnInit() {
    this.instance = await NapsterCompanionApiSdk.init(this.token, {
      mountContainer: this.containerRef.nativeElement,
      position: "bottom-right",
    });
  }

  ngOnDestroy() {
    this.instance?.destroy();
  }
}
<div id="sdk-container"></div>
<script src="https://cdn.jsdelivr.net/npm/@touchcastllc/napster-companion-api@latest/lib/index.standalone.js"></script>
<script>
  // token comes from your server after calling POST /public/connections
  const sdk = window.napsterCompanionApiSDK;

  sdk
    .init(token, {
      mountContainer: "#sdk-container",
      position: "bottom-right",
    })
    .then(instance => {
      instance.showAvatar();
    });
</script>

On this page