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),
});| Callback | Signature | Fires when |
|---|---|---|
onReady | () => void | The SDK has finished initialization and is ready to render. |
onError | (error: Error) => void | A runtime or network error occurs. |
onAvatarReady | (isReady?: boolean) => void | The visual avatar is fully prepared and rendering. Fires exactly once. |
onInactivityStatusChange | (isInactive: boolean) => void | The user's inactivity status changes. Pairs with the inactivity timeout feature. |
onDestroy | () => void | The SDK is destroyed, via destroy() or the built-in end control. |
onData | (data: EventMessage) => void | A message arrives over the data channel. See incoming data. |
onFeaturesUpdate | (features: FeatureConfig) => void | Feature configuration changes at runtime. |
onScreenShareStateChange | (isSharing: boolean) => void | Screen 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.