Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.spatius.ai/llms.txt

Use this file to discover all available pages before exploring further.

State & Events is how your application knows whether the connection is online, what the Avatar is doing, and which part should recover when something fails. AvatarKit exposes client-side state through AvatarController. In Custom Mode and LiveKit Plugin integrations, part of the state also lives in your backend, plugin, or RTC room. Wire three signals first:
SignalCallbackUse it to
Connection healthonConnectionStateShow connecting / failed UI and decide when to reconnect.
Avatar activityonConversationStateShow idle, speaking, or paused UI and coordinate barge-in.
FailuresonErrorLog stable error codes, refresh tokens, or surface unrecoverable issues.
Do not infer one signal from another. A connection can be connected while the Avatar is idle; a conversation can fail because playback data is bad even if the room or WebSocket is still online.

Connection Ownership

Connection means the active path that carries avatar speech audio to Motion Server and brings audio and motion data back to AvatarKit. The owner depends on the integration mode.
ModeWhere the Motion Server connection livesWhat the client observes
Basic ModeAvatarKit connects to Motion Server from the client.ConnectionState, onError, and onConnectionState on AvatarController.
Custom ModeYour backend connects to Motion Server through the Spatius Server SDK.AvatarKit observes the downstream transport and playback state; your backend must also observe its server-side connection.
LiveKit PluginYour agent worker starts the plugin; Motion Server publishes audio and motion data into the LiveKit room.AvatarKit observes the LiveKit room / RTC path and playback state.

ConnectionState

ConnectionState answers one question: can this client path currently receive audio and motion data?
disconnected → connecting → connected

                             failed
ConnectionStateMeaning
disconnectedNo active connection.
connectingHandshake in progress.
connectedActive and ready for avatar speech audio.
failedConnection failed. On iOS and Android the variant carries code and message.
Subscribe to onConnectionState on AvatarController to observe these transitions. → Reference: Web ConnectionState · iOS ConnectionState · Android ConnectionState

Errors

Client-side errors arrive through onError as AvatarError — a { code: ErrorCode, message: string } shape. Switch on code; treat message as log-only.
CategoryRepresentative codesWhen you see them
AuthenticationsessionTokenInvalid, sessionTokenExpired, appIDUnrecognized, insufficientBalance, concurrentLimitExceededToken problems, billing limits, duplicate concurrent sessions.
Resource loadingavatarIDUnrecognized, failedToFetchAvatarMetadata, failedToDownloadAvatarAssetsBad Avatar ID or download failure.
ConnectionwebsocketError, websocketClosedAbnormally, sessionTimeout, connectionInProgressWebSocket-level failures.
ServerserverErrorMotion Server reported an unexpected error.
For the full enumeration with WebSocket close codes, see Resources → Error Codes.

Token expiry

This is the most common Basic Mode production failure path. AvatarKit does not auto-recover. When the token expires, Motion Server closes the WebSocket with close code 4010, onError reports sessionTokenExpired or sessionTokenInvalid, and onConnectionState transitions to failed. Your code fetches a fresh token, calls AvatarSDK.setSessionToken(newToken), and starts the Basic Mode connection again.
Do not restart the same connection with the same expired token — you will loop on the same failure. Refresh the token first.
The same recovery shape applies to insufficientBalance, concurrentLimitExceeded, and sessionTimeout.

Recovery Ownership

Start from where the failed connection lives:
ModeRecovery ownerRecovery shape
Basic ModeClient appInspect AvatarError, refresh tokens for auth failures, back off for transient failures, then restart the client connection.
Custom ModeYour backend plus client transportRecover the Spatius Server SDK connection on your backend, then restore the downstream transport to AvatarKit.
LiveKit PluginLiveKit room / agent workerLet the room reconnect, and restart the plugin or agent worker only if the server-side session failed.
The Avatar and AvatarView instances stay valid across reconnects. You usually do not need to reload the Avatar just because the connection dropped.

ConversationState

ConversationState answers a different question: what is the Avatar doing with the audio and motion data it has received? It is driven by avatar speech audio, playback control, and motion data. See Audio and Motion Data for the data path.
idle → playing → idle

      paused
ConversationStateMeaning
idleNo active response — breathing animation only.
playingActively rendering audio + motion data.
pausedPlayback paused, state and buffers preserved.
Android also defines an Active state between idle and playing, representing the period after avatar speech audio is received but before playable motion data is available.
Subscribe to onConversationState on AvatarController to observe transitions. → Reference: Web ConversationState · iOS ConversationState · Android ConversationState

State change reasons

onConversationState fires with an optional StateChangeReason:
ReasonMeaning
userActionYour code called pause(), resume(), or interrupt().
playbackEndAudio + motion data ran out naturally.
networkErrorNetwork failure caused the transition.
serverErrorMotion Server reported an error.
fallbackModeAvatarKit entered fallback mode due to abnormal motion data.

Rendering events

CallbackPayloadFires when
onFirstRenderingThe first frame is rendered (iOS only).
onFrameRateInfoFrameRateInfoPeriodic FPS report (iOS and Android).
→ Reference: Web AvatarController · iOS AvatarController · Android AvatarController

Tips for production

  • Always listen to onError. Silent failures in audio and motion pipelines are expensive to debug after the fact.
  • Log the code, not the message. Codes are stable; messages are human-readable and may change.
  • Treat failed as a state, not an event. Keep it visible until retry logic moves the connection forward.
  • Bound your retries. Auth failures and quota failures do not become healthy through tight reconnect loops.

Go next

  • Sessions & Lifecycle if you need to understand where each connection lives.
  • Audio and Motion Data if playback state looks wrong because audio timing or end-of-stream handling is wrong.
  • Avatars if errors point to Avatar ID or asset loading failures.