ScenaroSession is the framework-agnostic core of the SDK. useScenaroSession is a thin React binding over it — if you’re not using React (vanilla JS, Vue, Svelte…), use this class directly.

Constructor

OptionTypeDefaultDescription
apiUrlstringAPI base URL (or pass client)
clientScenaroClientPre-built client instance
apiPathPrefixstring'/v1'Prepended to all endpoints
storagePrefixstring''Prefix for localStorage keys
storageStorageAdapter | nulllocalStorageCustom storage adapter
transportTransportLiveKitTransportInternal, non-public interface — injectable for tests
Throws if neither client nor apiUrl is provided.

State

All state is readable synchronously; changes are announced through events.
GetterType
status'idle' | 'connecting' | 'connected' | 'reconnecting' | 'ended'
agentState'idle' | 'listening' | 'thinking' | 'speaking'
messagesConversationMessage[]
configSessionConfig | null
rawConfigConfigPayload | null — wire format (restore_state, tool wiring)
conversationIdstring | null
roomunknownengine extension (LiveKit today), see Transport extensions

Methods

start

Identifies the visitor, starts a session, registers tools, and connects Transport. Throws ScenaroError with code IDENTIFY_FAILED or SESSION_START_FAILED.

StartSessionOptions

FieldTypeDefault
scenariostringrequired
languagestringscenario’s configured language
inputMode / outputMode'audio' | 'text''audio'
microphonebooleantrue
externalIdstring | nullauto-generated
resumeConversationIdstring
metadataRecord<string, unknown>
toolsRecord<string, ToolHandler>{}

end

Unregisters tools, disconnects Transport, and sets status to 'ended'. The session can be started again with start().

sendText / setMicrophoneEnabled

In-session actions never throw — failures are emitted on the error event instead, so fire-and-forget call sites don’t produce unhandled rejections.

destroy

Releases Transport listeners and timers. Call when the owning scope is torn down (ScenaroProvider does this automatically on unmount).

Events

Kebab-case event names, subscribed with on / off:
EventPayload
status-changeSessionStatus
agent-stateAgentState
messageConversationMessage
configSessionConfig
session-end{ reason: string }'shutdown', 'agent_disconnected', 'transport_disconnected'
errorScenaroError

Errors

start() throws; everything after connection emits on error instead.

SessionConfig

A curated view of the scenario config — backend plumbing (company_id, voice_stack, timestamps, tool wiring) is deliberately not exposed.