Skip to main content

EstuaryClient

The main entry point for the Estuary Python SDK. Inherits from AsyncEventEmitter.

from estuary_sdk import EstuaryClient, EstuaryConfig

config = EstuaryConfig(...)
client = EstuaryClient(config)

Context Manager

EstuaryClient supports async with for automatic cleanup:

async with EstuaryClient(config) as client:
await client.connect()
# ... use client ...
# disconnect() is called automatically on exit

Connection Methods

connect() -> SessionInfo

Connect to the Estuary server and authenticate. Returns a SessionInfo with session details.

session = await client.connect()
print(session.session_id, session.conversation_id)

Raises: EstuaryError with AUTH_FAILED, CONNECTION_FAILED, or CONNECTION_TIMEOUT.

disconnect() -> None

Disconnect from the server and clean up all resources (voice, REST client).

await client.disconnect()

Properties

PropertyTypeDescription
is_connectedboolWhether the client is currently connected
sessionSessionInfo | NoneCurrent session info, or None if not connected

Text Methods

send_text(text, text_only=False) -> None

Send a text message to the character.

ParameterTypeDefaultDescription
textstrrequiredThe message text
text_onlyboolFalseIf True, suppress voice response

Raises: EstuaryError with NOT_CONNECTED.

say_line(text, text_only=False) -> None

Script the character to say a specific prewritten line. Interrupts any in-progress response, skips the LLM entirely, and feeds the text directly to TTS (or text-only if text_only=True). The line is saved to chat history as a normal assistant turn.

ParameterTypeDefaultDescription
textstrrequiredThe exact line the character should speak. Blank/whitespace strings are silently ignored.
text_onlyboolFalseIf True, only bot_response is emitted (no TTS audio).

Raises: EstuaryError with NOT_CONNECTED (unless text is blank, which is a no-op).

send_text_and_wait(text, *, text_only=False, timeout=20.0) -> BotResponse

Send a text message and wait for the final bot response. Returns the complete BotResponse directly.

ParameterTypeDefaultDescription
textstrrequiredThe message text
text_onlyboolFalseIf True, suppress voice response
timeoutfloat20.0Max seconds to wait for a final response

Returns: BotResponse with is_final=True.

Raises: asyncio.TimeoutError if no final response within timeout. EstuaryError with NOT_CONNECTED.

interrupt(message_id=None) -> None

Interrupt the current bot response.

ParameterTypeDefaultDescription
message_idstr | NoneNoneSpecific message to interrupt, or None for current

Voice Methods

start_voice(mode=VoiceMode.CONTINUOUS) -> None

Start a voice session.

ParameterTypeDefaultDescription
modeVoiceModeCONTINUOUSCONTINUOUS for VAD, PUSH_TO_TALK for manual control

Raises: EstuaryError with VOICE_ALREADY_ACTIVE, VOICE_START_FAILED, or LIVEKIT_UNAVAILABLE.

stop_voice() -> None

Stop the voice session and clean up resources.

start_recording() -> None

Begin streaming audio (push-to-talk mode only).

Raises: EstuaryError with VOICE_NOT_ACTIVE.

stop_recording() -> None

Stop streaming audio and trigger end-of-turn (push-to-talk mode only).

Raises: EstuaryError with VOICE_NOT_ACTIVE.

send_audio(audio) -> None

Send raw PCM16 audio bytes to the server.

ParameterTypeDescription
audiobytesRaw PCM16 audio (16-bit signed integer, mono, at configured sample rate)

Raises: EstuaryError with VOICE_NOT_ACTIVE.

toggle_mute() -> None

Toggle voice mute state.

Voice Properties

PropertyTypeDescription
is_voice_activeboolWhether a voice session is currently active
is_mutedboolWhether voice is currently muted

Vision Methods

send_camera_image(image_base64, mime_type, request_id=None, text=None) -> None

Send a camera image for vision processing.

ParameterTypeDefaultDescription
image_base64strrequiredBase64-encoded image data
mime_typestrrequiredImage MIME type (e.g., "image/jpeg")
request_idstr | NoneNoneRequest ID from camera_capture_request event
textstr | NoneNoneOptional text to accompany the image

Preferences

update_preferences(enable_vision_acknowledgment=None) -> None

Update session preferences.

notify_audio_playback_complete(message_id=None) -> None

Notify the server that audio playback has finished.

REST Sub-Clients

These are accessed as properties on the client:

client.memory -> MemoryClient

Memory REST API. Available after connect().

MethodReturnsDescription
get_memories(...)MemoryListResponseList memories with filtering/pagination
get_timeline(...)MemoryTimelineMemories grouped by time period
get_stats()MemoryStatsAggregate memory statistics
get_core_facts()CoreFactsResponseHigh-confidence stable facts
get_graph(...)MemoryGraphFull knowledge graph
search(query, limit)MemorySearchResponseSemantic similarity search
delete_all(confirm)MemoryDeleteResponseDelete all memories

client.players -> PlayersClient

Players REST API. Available after connect().

MethodReturnsDescription
list(...)PlayerConversationListList player conversations
get(player_id)PlayerConversationGet a single player conversation
get_messages(player_id, ...)PlayerMessageListGet conversation messages
get_stats()PlayerStatsAggregate player statistics
delete(player_id)dictDelete a player and all data

client.characters -> CharactersClient

Characters REST API. Available immediately (no connect() required).

MethodReturnsDescription
create(name, ...)CharacterCreate a new character
list(limit, offset)CharacterListResponseList characters
get(character_id)CharacterGet a character by ID
update(character_id, ...)CharacterUpdate a character
delete(character_id)dictDelete a character

client.generate -> GenerateClient

Character generation REST API. Available immediately (no connect() required).

MethodReturnsDescription
image_to_character(image_base64, mime_type)GeneratedCharacterGenerate a character from an image
get_model_status(agent_id)ModelStatusPoll 3D model generation status
wait_for_model(agent_id, *, poll_interval, timeout, on_progress)ModelStatusPoll until model completes or fails

client.shares -> SharesClient

Share characters via long-lived anchors (NFC tags, QR codes, print) or short-lived tokens. Available immediately (no connect() required).

See Sharing Characters for a full guide.

MethodReturnsDescription
create_anchor(character_id, memory_sharing, max_interactions)dictCreate a long-lived anchor ({id, anchorUrl})
open_anchor(anchor_id)dictRedeem an anchor for a session token
exchange_share_token(token, recipient_id)dictExchange a short-lived share token for a session token
list_anchors(character_id)dict(Firebase auth) List owned anchors
revoke_anchor(anchor_id)dict(Firebase auth) Revoke a single anchor
bulk_revoke_anchors_by_api_key(api_key_id)dict(Firebase auth) Revoke all anchors minted by an API key
create_share_token(character_id, ttl, memory_sharing, max_exchanges)dict(Firebase auth) Create a short-lived share token
list_character_shares(character_id)dict(Firebase auth) List active share tokens for a character
revoke_share_token(share_token_id)dict(Firebase auth) Revoke a share token
Authentication

Methods marked (Firebase auth) require a Firebase ID token on the backend and will raise EstuaryError (HTTP 401) with API-key-only auth. Only create_anchor, open_anchor, and exchange_share_token are reachable with a standard est_ API key.