WebRTC
Connect to an agent in the browser using the Web SDK
WebRTC is the browser channel: a real-time audio and video conversation with your agent, running in the user's browser and rendered by the Web SDK. This page covers the channel itself — creating a session, and the video behavior specific to WebRTC. Everything about the client library — installation, initialization, configuration, events, and methods — lives in the Web SDK section.
Connecting to an agent
Create a session and connect the Web SDK
Video policy
Start sessions audio-first with deferred video
Green screen background
Composite the avatar over your own backdrop
Connecting to an agent
Create a session
If you have an Omniagent, create a WebRTC session with a single call:
curl -X POST https://companion-api.napster.com/public/agents/agent_abc123/connections \
-H "X-Api-Key: $NAPSTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"channelType": "webrtc"
}'The agent's companion, voice, tools, knowledge, and provider settings are all inherited from the agent configuration. You can optionally pass externalClientId to enable cross-session memory.
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.
Connect with the Web SDK
Next, bring the agent into your frontend with the Web SDK — it takes the token from step 1, opens the WebRTC connection, and renders the avatar your users see, hear, and talk to:
Video policy
By default a WebRTC session becomes ready only when audio and video are both up — avatar_state_changed reports ready once, with the avatar fully rendered. If you'd rather let the conversation start as soon as audio is available, and let the video avatar appear a moment later, set videoPolicy to "deferred".
| Value | Behavior |
|---|---|
required (default) | The session waits for audio and video together. ready fires once, with the avatar fully up. |
deferred | The session becomes ready with audio first; the video avatar initializes in the background and comes up moments later. ready fires twice. |
Set it on the WebRTC channel config to apply to every session on the channel:
curl -X PUT https://companion-api.napster.com/public/agents/agent_abc123/channels/webrtc \
-H "X-Api-Key: $NAPSTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"videoPolicy": "deferred"
}'Per-session connections (POST /public/connections) accept videoPolicy directly in the request body. Sessions created from an agent (POST /public/agents/{agentId}/connections) inherit the value from the agent's WebRTC channel config.
videoPolicy applies to WebRTC only. WebSocket sessions carry no video, so the parameter has no effect there.
What deferred changes in the event stream
With "deferred", readiness arrives in two steps, and each ready carries a details object describing what became available:
avatar_state_changed { "state": "preparing" }
avatar_state_changed { "state": "ready", "details": { "mode": "audio_only" } }
avatar_state_changed { "state": "preparing", "details": { "stage": "initializing" } }
avatar_state_changed { "state": "ready", "details": { "mode": "audio_video", "video_type": "hd" } }The conversation is fully live from the first ready — the agent can hear, speak, and call tools before video exists. The second ready announces the video upgrade.
Write your handlers to tolerate both policies:
- Latch readiness. Treat
readyas a state you enter once, not a one-shot signal. Run session-start logic on the firstreadyand ignore repeats — anything triggered naively "on ready" (a greeting nudge, analytics, a UI transition) runs twice under"deferred". - Prefer
onAvatarReadyin the Web SDK. It fires exactly once, when the avatar video is actually rendering. Under"deferred"that is after the conversation went live, so don't gate audio-dependent logic on it. - Distinguish the steps with
details.mode—"audio_only"vs"audio_video"— when you need to react to the video upgrade specifically.
Green screen background
By default the agent's video stream comes with its own background. If you want to composite the avatar over your own UI — your brand colors, a custom backdrop, a product page — enable the green-screen mode.
This is a two-sided setting. Both halves must match, or the visuals break.
Step 1 — Enable on the channel config
Set useGreenVideo to true on the WebRTC channel config:
curl -X PUT https://companion-api.napster.com/public/agents/agent_abc123/channels/webrtc \
-H "X-Api-Key: $NAPSTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"useGreenVideo": true
}'This tells the server to send the avatar's video with a green-screen backdrop instead of the default scene.
Step 2 — Match it in the SDK init
In your client, set avatarStyle.view to "silhouette" when initializing the SDK:
await NapsterCompanionApiSdk.init(token, {
mountContainer: "#avatar-container",
avatarStyle: { view: "silhouette" },
});The SDK's silhouette view chroma-keys the green out, leaving the avatar floating over whatever you've placed behind the container.
Both settings must be set together. If useGreenVideo is on but the SDK view is "rectangle", you'll see a green background on the avatar. If the SDK view is "silhouette" but useGreenVideo is off, the chroma-key has nothing to remove and the avatar's normal background bleeds through.