For the complete documentation index, see llms.txt. This page is also available as Markdown.

Event Reference

Subscribe with `client.on(event, callback)`. The return value is an unsubscribe function.

const unsub = client.on('botReady', () => {
  console.log('Bot is ready');
});

// Later
unsub();
// or
client.off('botReady', handler);

Connection events

connect

Fires when the WebRTC/WebSocket transport connects. The bot may not be ready yet — wait for botReady before sending messages.

client.on('connect', () => {
  console.log('Transport connected');
});

botReady

Fires when the character has confirmed it is ready to receive messages. This is the correct signal to start interacting.

client.on('botReady', () => {
  client.sendUserTextMessage('Hello!');
});

disconnect

Fires when the session ends. Receives a DisconnectReason code.

stateChange

Fires whenever any part of ConvaiClientState changes. Use this for UI updates.

error

Fires on connection errors or bot-ready timeout.


Conversation events

conversationStart

Fires when a new conversation turn begins — either when the user sends a text message or starts speaking.

turnEnd

Fires when the bot finishes speaking for a turn.

message

Fires for each new ChatMessage added to the conversation. The full history is also available in client.chatMessages.

messagesChange

Fires whenever the message array changes (includes message updates mid-stream).

userTranscriptionChange

Fires repeatedly as the user speaks, providing live speech-to-text.


Speaking events

speakingChange

Fires when the bot starts or stops speaking.

botOutput

Fires for each aggregated output chunk from the bot. Includes both spoken and unspoken text.

botTtsStarted

Fires when the TTS engine starts producing audio.

botTtsStopped

Fires when the TTS engine finishes.

botTtsText

Fires word-by-word as the bot speaks, synchronized with TTS audio.


Microphone events

userMuteStarted

Fires when the server-side mutes the user's microphone (e.g., when the bot starts speaking to prevent echo).

userMuteStopped

Fires when the server un-mutes the user's microphone.


Blendshape / lipsync events

These require enableLipsync: true in config.

blendshapes

Fires for each incoming blendshape chunk (10 frames by default). Use client.blendshapeQueue instead of handling raw chunks directly.

blendshapeStatsReceived

Fires when the server sends end-of-turn blendshape statistics. Signals that no more frames are coming for this turn.


Action events

Requires actionConfig in config.

actionResponse

Fires after each bot turn with the actions the bot decided to perform.

See Actions for the complete guide.


Server response events

serverResponse

Fires as an acknowledgment for every message you send to the server.

interactionCreated

Fires early in the session lifecycle — before botReady — when the server assigns a unique interaction ID. This is the first message that carries both interactionId and characterSessionId, making it the right place to capture identifiers for analytics, logging, or session resumption.

Field
Type
Description

interactionId

string

Unique identifier for this interaction. Use for analytics or log correlation.

characterSessionId

string

Character session identifier. Same value as client.characterSessionId after connect.

interactionCreated fires once per connect() call. If you reconnect, a new interactionId is issued.


Session events

idleWarning

Fires before the server disconnects an idle session.

llmNoResponse

Fires when the LLM deliberately chose not to respond (e.g., because the input didn't warrant a reply).


metrics

Fires with performance data after each turn.


Audio track (WebSocket transport)

botAudioTrack

Fires when a new audio track is available from the bot (WebSocket transport only). Attach to an <audio> element to play.


Event quick-reference

Event
Payload
When

connect

Transport connected

botReady

Bot confirmed ready

disconnect

DisconnectReason

Session ended

stateChange

ConvaiClientState

Any state change

error

Error

Connection or timeout error

conversationStart

{ sessionId, userMessage, timestamp }

New turn begins

turnEnd

{ sessionId, duration, timestamp }

Bot finishes speaking

message

ChatMessage

New message

messagesChange

ChatMessage[]

History updated

userTranscriptionChange

string

Live STT update

speakingChange

boolean

Bot speaking state

botOutput

{ text, spoken, aggregatedBy }

Aggregated bot chunk

botTtsStarted

TTS begins

botTtsStopped

TTS ends

botTtsText

{ text }

Word-by-word TTS

userMuteStarted

Server muted user mic

userMuteStopped

Server un-muted user mic

blendshapes

raw data

Blendshape chunk

blendshapeStatsReceived

stats

Turn end stats

actionResponse

{ actions }

Bot action decisions

serverResponse

ServerResponse

Server acknowledgment

interactionCreated

{ interactionId, characterSessionId }

Session ID assigned

idleWarning

{ remainingSeconds }

Idle timeout warning

llmNoResponse

LLM chose not to respond

metrics

data

Turn performance data

botAudioTrack

MediaStreamTrack

New audio track (WS transport)

Last updated

Was this helpful?