SDKsWeb SDK

Events

Lifecycle callbacks and the incoming data your client receives

Events are the SDK's observe surface: callbacks you register in config to follow the session as it happens. For the other direction — sending messages and commands to the agent — see Messaging.

Lifecycle callbacks

Register these in the config object. All are optional.

const instance = await NapsterCompanionApiSdk.init(token, {
  onReady: () => console.log("SDK ready"),
  onError: error => console.error("SDK error:", error),
  onAvatarReady: isReady => console.log("Avatar ready:", isReady),
  onInactivityStatusChange: isInactive => console.log("Inactive:", isInactive),
  onScreenShareStateChange: isSharing => console.log("Sharing:", isSharing),
  onDestroy: () => console.log("SDK destroyed"),
  onData: data => console.log("Data:", data),
});
CallbackSignatureFires when
onReady() => voidThe SDK has finished initialization and is ready to render.
onError(error: Error) => voidA runtime or network error occurs.
onAvatarReady(isReady?: boolean) => voidThe visual avatar is fully prepared and rendering. Fires exactly once.
onInactivityStatusChange(isInactive: boolean) => voidThe user's inactivity status changes. Pairs with the inactivity timeout feature.
onDestroy() => voidThe SDK is destroyed, via destroy() or the built-in end control.
onData(data: EventMessage) => voidA message arrives over the data channel. See incoming data.
onFeaturesUpdate(features: FeatureConfig) => voidFeature configuration changes at runtime.
onScreenShareStateChange(isSharing: boolean) => voidScreen sharing starts or stops.

Prefer onAvatarReady over reacting to the raw ready state when you need to know the avatar video is actually visible. Under deferred video the session goes live on audio first and the avatar renders a moment later — onAvatarReady fires once, when video is up.

Incoming data

onData receives each message the avatar sends over the data channel as an EventMessage:

interface EventMessage {
  event: string;
  data?: {
    state?: string;
    message?: { action?: string; content?: string; role?: string };
    [key: string]: unknown;
  };
}

The event field names the message type (for example avatar_state_changed or message_received) and data carries the payload. For the full protocol — the server events you receive and how transcripts and state changes are shaped — see Server events.

One event doesn't originate from the platform: ui_update carries arbitrary JSON that your own functions server pushed to the client — use it to drive your page's UI from your backend in sync with the conversation.

Next steps

On this page