Events and Types
Complete reference for all events emitted by EstuaryClient, plus enums and utility types.
EstuaryEventMap
The full typed event map. Each entry defines the event name and its callback signature.
| Event | Callback | Description |
|---|---|---|
connected | (session: SessionInfo) => void | Successfully connected and authenticated |
disconnected | (reason: string) => void | Connection closed |
reconnecting | (attempt: number) => void | Attempting to reconnect (attempt number) |
connectionStateChanged | (state: ConnectionState) => void | Connection state transition |
botResponse | (response: BotResponse) => void | Text response chunk from the character |
botVoice | (voice: BotVoice) => void | Voice audio chunk from the character |
sttResponse | (response: SttResponse) => void | Speech-to-text transcription result |
interrupt | (data: InterruptData) => void | Response was interrupted |
error | (error: Error) => void | An error occurred |
authError | (error: string) => void | Authentication failed |
quotaExceeded | (data: QuotaExceededData) => void | Usage quota exceeded |
cameraCaptureRequest | (request: CameraCaptureRequest) => void | Server requests a camera image |
voiceStarted | () => void | Voice session started |
voiceStopped | () => void | Voice session stopped |
livekitConnected | (room: string) => void | LiveKit room connected |
livekitDisconnected | () => void | LiveKit room disconnected |
audioPlaybackStarted | (messageId: string) => void | Audio playback started for a message |
audioPlaybackComplete | (messageId: string) => void | Audio playback finished for a message |
characterAction | (action: CharacterAction) => void | Parsed action from bot response (action tags are auto-stripped from botResponse.text) |
memoryUpdated | (event: MemoryUpdatedEvent) => void | Real-time memory extraction notification (requires realtimeMemory: true in config) |
Usage
client.on('connected', (session) => {
// session: SessionInfo
});
client.on('botResponse', (response) => {
// response: BotResponse
});
client.on('sttResponse', (response) => {
// response: SttResponse
});
client.on('interrupt', (data) => {
// data: InterruptData
});
client.on('error', (error) => {
// error: Error (may be EstuaryError)
});
client.on('quotaExceeded', (data) => {
// data: QuotaExceededData
});
client.on('cameraCaptureRequest', (request) => {
// request: CameraCaptureRequest
// Capture and send an image in response
client.sendCameraImage(imageBase64, 'image/jpeg', request.requestId);
});
client.on('voiceStarted', () => {
// No arguments
});
Session Rejection
Some server-side policy caps (currently the per-share-token concurrent-session cap) cause the server to emit a session_rejected payload and immediately disconnect.
The TypeScript SDK does not currently surface session_rejected as its own typed event. The disconnect is observable via the standard disconnected and error events. If you need to detect the cap specifically, watch for an immediate disconnect right after a successful connect() and surface a "session limit reached" message in your UI.
The wire payload is:
// Server -> Client (Socket.IO event 'session_rejected', not exposed as a typed SDK event)
interface SessionRejectedPayload {
reason: string; // e.g., "concurrent_limit"
cap: number; // The current limit (informational)
share_token_id: string; // The share token that was rejected
}
reason codes:
concurrent_limit-- too many active sessions are already open for this share token. Wait for another device to disconnect, or retry later.
ConnectionState
Enum representing the client's connection state.
import { ConnectionState } from '@estuary-ai/sdk';
| Value | Description |
|---|---|
ConnectionState.Disconnected | Not connected to the server |
ConnectionState.Connecting | Connection in progress |
ConnectionState.Connected | Connected and authenticated |
ConnectionState.Reconnecting | Lost connection, attempting to reconnect |
ConnectionState.Error | Connection failed (auth error, max retries, etc.) |
client.on('connectionStateChanged', (state) => {
if (state === ConnectionState.Connected) {
console.log('Ready');
}
});
VoiceTransport
Type alias for the voice transport option.
type VoiceTransport = 'websocket' | 'livekit' | 'auto';
| Value | Description |
|---|---|
'websocket' | Stream audio as base64 PCM over WebSocket |
'livekit' | Use LiveKit WebRTC (requires livekit-client) |
'auto' | Prefer LiveKit if available, fall back to WebSocket |
ErrorCode
Enum of all typed error codes used by EstuaryError.
import { ErrorCode } from '@estuary-ai/sdk';
| Value | Description |
|---|---|
CONNECTION_FAILED | WebSocket connection failed |
AUTH_FAILED | API key or credentials invalid |
CONNECTION_TIMEOUT | Connection attempt timed out |
QUOTA_EXCEEDED | Usage quota exceeded |
VOICE_NOT_SUPPORTED | No voice transport available |
VOICE_ALREADY_ACTIVE | startVoice() called while voice is already active |
VOICE_NOT_ACTIVE | Voice operation called without active voice session |
LIVEKIT_UNAVAILABLE | LiveKit requested but livekit-client not installed |
MICROPHONE_DENIED | User denied microphone permission |
NOT_CONNECTED | Operation requires a connection but client is disconnected |
REST_ERROR | REST API request failed |
UNKNOWN | Unclassified error |
EstuaryError
Error class extending Error with a typed code property.
import { EstuaryError, ErrorCode } from '@estuary-ai/sdk';
Properties
| Property | Type | Description |
|---|---|---|
code | ErrorCode | Typed error code |
message | string | Human-readable error message |
details | unknown (optional) | Additional error context |
name | string | Always 'EstuaryError' |
Usage
try {
await client.connect();
} catch (err) {
if (err instanceof EstuaryError) {
console.error(`[${err.code}] ${err.message}`);
if (err.details) {
console.error('Details:', err.details);
}
}
}