Skip to main content

Core Components

EstuaryManager

MonoBehaviour -- Singleton that owns the network connection and coordinates all Estuary components.

Namespace: Estuary

Accessing the Singleton

EstuaryManager.Instance

If no instance exists in the scene, accessing Instance creates a new GameObject named EstuaryManager automatically. The instance persists across scene loads (DontDestroyOnLoad).

EstuaryManager.HasInstance returns true only if an instance already exists (does not create one).

Inspector Fields

FieldTypeDefaultDescription
ConfigEstuaryConfigReference to your configuration asset
DebugLoggingboolfalseEnable verbose logging on the manager and underlying client
note

AutoConnect lives on EstuaryCharacter, not EstuaryManager. Each character decides whether to connect when it starts.

Properties

PropertyTypeAccessDescription
InstanceEstuaryManagerstatic getSingleton accessor (creates one if needed)
HasInstanceboolstatic gettrue if an instance exists
ConfigEstuaryConfigget/setConfiguration asset
IsConnectedboolgettrue when Socket.IO is connected
ConnectionStateConnectionStategetCurrent connection state
DebugLoggingboolget/setEnable verbose logs (also applied to underlying client and LiveKit manager)
LiveKitStateLiveKitConnectionStategetCurrent LiveKit connection state
IsLiveKitReadyboolgettrue when LiveKit is available and the room is ready
IsLiveKitEnabledboolgettrue when LiveKit mode is configured and the LiveKit assembly is present
IsVoiceModeActiveboolgettrue when backend STT is active (after StartVoiceModeAsync)
LiveKitManagerILiveKitVoiceManagergetThe LiveKit voice manager (or null if the LiveKit SDK is not installed)
ActiveCharacterEstuaryCharactergetCurrently active character

Methods

MethodReturnsDescription
Connect()voidFire-and-forget wrapper for ConnectAsync()
ConnectAsync()TaskConnect using Config and the active character
Disconnect()voidFire-and-forget wrapper for DisconnectAsync()
DisconnectAsync()TaskDisconnect from LiveKit (if connected) and Socket.IO
RegisterCharacter(EstuaryCharacter character)voidRegister a character (called automatically by EstuaryCharacter.Start)
UnregisterCharacter(EstuaryCharacter character)voidUnregister a character
SetActiveCharacter(EstuaryCharacter character)voidSwitch the active character (reconnects if already connected)
SendTextAsync(string text)TaskSend a text message via the active character
SendTextAsync(string text, bool textOnly)TaskSend a text message; textOnly=true suppresses TTS
SayLineAsync(string text, bool textOnly = false)TaskScript the active character to say a specific prewritten line via TTS
StreamAudioAsync(string audioBase64)TaskStream base64-encoded PCM audio for STT (WebSocket voice mode)
NotifyAudioPlaybackCompleteAsync()TaskNotify the server that local TTS playback has finished
NotifyInterruptAsync(string messageId = null)TaskTell the server to stop streaming TTS for the given (or current) message
StartVoiceModeAsync()TaskEnable backend STT
StopVoiceModeAsync()TaskDisable backend STT
RequestLiveKitTokenAsync()TaskRequest a LiveKit token from the server
ConnectLiveKitAsync()TaskConnect to LiveKit using the most recently received token
ConnectLiveKitWithTokenAsync(LiveKitTokenResponse token)TaskConnect to LiveKit using a specific token response
DisconnectLiveKitAsync()TaskLeave the LiveKit room and notify the server
StartLiveKitPublishingAsync()TaskStart publishing the microphone over LiveKit
StopLiveKitPublishingAsync()TaskStop publishing the microphone over LiveKit

Events

EventSignatureDescription
OnConnectionStateChangedEstuaryEvents.ConnectionStateHandler (Action<ConnectionState>)Fired when Socket.IO connection state changes
OnErrorEstuaryEvents.ErrorHandler (Action<string>)Fired on global errors
OnLiveKitStateChangedAction<LiveKitConnectionState>Fired when LiveKit connection state changes
OnLiveKitReadyAction<string>Fired when the LiveKit room is ready (room name)
OnActiveCharacterChangedAction<EstuaryCharacter, EstuaryCharacter>Fired when the active character changes (previous, current)
OnBotAudioSourceCreatedAction<AudioSource>Fired when LiveKit creates the bot's AudioSource (for lip sync)

EstuaryClient

Low-level Socket.IO v4 client used internally by EstuaryManager. You normally do not need to touch this class directly; use EstuaryManager for all application code.

Namespace: Estuary

EstuaryClient implements the Socket.IO v4 protocol over a raw ClientWebSocket. It handles packet framing, namespace connection (with auth payload), JSON event payloads, ping/pong heartbeats, and automatic reconnection (up to 5 attempts with linear backoff).

info

Inside EstuaryManager the EstuaryClient instance is private. The signatures below describe the underlying class for advanced/debug scenarios; reach for EstuaryManager's methods first.

Properties

PropertyTypeDescription
StateConnectionStateCurrent connection state
IsConnectedbooltrue when the namespace is connected
CurrentSessionSessionInfoSession info after the server emits session_info (null otherwise)
DebugLoggingboolToggle verbose logs
IsVoiceModeActivebooltrue after StartVoiceModeAsync succeeds

Methods

MethodReturnsDescription
ConnectAsync(string serverUrl, string apiKey, string characterId, string playerId, int audioSampleRate = 48000, string token = null)TaskOpen the WebSocket and perform the Socket.IO handshake. Either apiKey or token must be supplied.
DisconnectAsync()TaskClose the connection gracefully
SendTextAsync(string text)TaskEmit a text event
SendTextAsync(string text, bool textOnly)TaskEmit a text event with text_only override
SayLineAsync(string text, bool textOnly = false)TaskEmit a say_line event for scripted lines
StreamAudioAsync(string audioBase64)TaskEmit a stream_audio event with base64-encoded PCM (WebSocket voice mode)
NotifyAudioPlaybackCompleteAsync()TaskEmit audio_playback_complete
NotifyInterruptAsync(string messageId = null)TaskEmit client_interrupt
StartVoiceModeAsync()TaskEmit start_voice
StopVoiceModeAsync()TaskEmit stop_voice
RequestLiveKitTokenAsync()TaskEmit livekit_token
NotifyLiveKitJoinedAsync()TaskEmit livekit_join
NotifyLiveKitLeftAsync()TaskEmit livekit_leave
NotifyLiveKitMuteAsync(bool muted)TaskEmit livekit_mute for mute-state UI sync
EmitAsync(string eventName, object data)TaskEmit a custom Socket.IO event

Events (Delegates)

EventSignatureDescription
OnSessionConnectedEstuaryEvents.SessionConnectedHandler (Action<SessionInfo>)session_info received
OnDisconnectedEstuaryEvents.DisconnectedHandler (Action<string>)Connection lost (reason)
OnBotResponseEstuaryEvents.BotResponseHandler (Action<BotResponse>)bot_response chunk received
OnBotVoiceEstuaryEvents.BotVoiceHandler (Action<BotVoice>)bot_voice audio chunk received
OnSttResponseEstuaryEvents.SttResponseHandler (Action<SttResponse>)stt_response transcription received
OnInterruptEstuaryEvents.InterruptHandler (Action<InterruptData>)interrupt confirmation received
OnErrorEstuaryEvents.ErrorHandler (Action<string>)error or auth error received
OnConnectionStateChangedEstuaryEvents.ConnectionStateHandler (Action<ConnectionState>)Connection state changed
OnLiveKitTokenReceivedAction<LiveKitTokenResponse>livekit_token payload received
OnLiveKitReadyAction<string>livekit_ready received (room name)
OnLiveKitErrorAction<string>livekit_error received
OnVoiceStartedActionvoice_started received
OnVoiceStoppedActionvoice_stopped received
OnVoiceErrorAction<string>voice_error received
OnQuotaExceededAction<QuotaExceededData>quota_exceeded received

EstuaryConfig

ScriptableObject -- Stores global SDK configuration. Character-specific settings (CharacterId, PlayerId) live on EstuaryCharacter.

Namespace: Estuary

Creating a Config Asset

In the Editor: Right-click in the Project window > Create > Estuary > Config.

In Code:

// API key first, then optional server URL
var config = EstuaryConfig.CreateForDevelopment("est_yourkey");
// Or with a custom server URL
var config = EstuaryConfig.CreateForDevelopment("est_yourkey", "http://localhost:4001");

Fields

FieldTypeDefaultDescription
ServerUrlstringhttps://api.estuary-ai.comEstuary server URL
ApiKeystring""API key for authentication (est_...). Optional when TokenProvider is set.
VoiceModeVoiceModeLiveKitVoice transport: WebSocket or LiveKit
DebugLoggingboolfalseEnable verbose logging

Properties

PropertyTypeAccessDescription
IsLiveKitEnabledboolgetConvenience: VoiceMode == VoiceMode.LiveKit
TokenProviderFunc<Task<string>>get/setAsync token provider (e.g., Firebase). When set, the SDK uses the returned Bearer token for auth instead of the API key. Not serialized.

Methods

MethodReturnsDescription
SetApiKeyRuntime(string key)voidSet the API key at runtime (does not persist to disk)
SetServerUrlRuntime(string url)voidSet the server URL at runtime
IsValid()booltrue if both server URL and (API key or token provider) are set
GetValidationError()stringHuman-readable validation error, or null when valid
CreateDefault()EstuaryConfigStatic: create a default in-memory config
CreateForDevelopment(string apiKey, string serverUrl = "http://localhost:4001")EstuaryConfigStatic: create a development config with debug logging enabled

:::info Audio sample rate Sample rates are not configured on EstuaryConfig. The SDK uses Unity's AudioSettings.outputSampleRate for TTS playback and forwards it during the Socket.IO handshake so the backend can match. Recording for WebSocket STT is fixed at 16 kHz. :::