Quick Reference
| Class | Purpose | Key Methods |
|---|
AvatarSDK | SDK initialization | initialize(), setSessionToken() |
AvatarManager | Avatar loading | load() |
AvatarView | 3D rendering | onFirstRendering, dispose() |
AvatarController | Communication | start(), send(), pause(), interrupt() |
Important: App ID and Session Token are paired and must be used together. Each App ID corresponds to a specific list of avatars that can be driven. You must obtain both App ID and Session Token from the SpatialReal Studio.
AvatarSDK
Main entry point for SDK initialization and global configuration.
import { AvatarSDK, Environment } from '@spatialwalk/avatarkit'
Static Properties
| Property | Type | Description |
|---|
isInitialized | boolean | Whether SDK is initialized |
appId | string | null | Current App ID |
configuration | Configuration | Current SDK configuration |
sessionToken | string | null | Current session token |
userId | string | null | Current user ID |
version | string | SDK version |
Static Methods
initialize(appId, configuration)
Initialize the SDK. Must be called before any other operations.
await AvatarSDK.initialize('your-app-id', {
environment: Environment.cn, // or Environment.intl
drivingServiceMode: DrivingServiceMode.sdk, // Optional, default: sdk
logLevel: LogLevel.warning, // Optional, default: off
audioFormat: { // Optional
channelCount: 1,
sampleRate: 16000,
},
})
setSessionToken(token)
Set session token for authentication. Only required for SDK Mode (server-driven animation).
AvatarSDK.setSessionToken('your-session-token')
Important:
- Only needed for SDK Mode - not required for Host Mode or RTC Mode
- Token must be obtained from your backend server
- Token has max 24 hours validity
- Token must be paired with App ID
setUserId(userId)
Set user ID for logging and analytics.
AvatarSDK.setUserId('user-123')
cleanup()
Release all SDK resources. Call when SDK is no longer needed.
AvatarManager
Handles avatar loading and caching.
import { AvatarManager } from '@spatialwalk/avatarkit'
Static Properties
| Property | Type | Description |
|---|
shared | AvatarManager | Singleton instance |
Instance Methods
load(id, onProgress?)
Load an avatar by ID.
const avatar = await AvatarManager.shared.load('avatar-id', (progress) => {
switch (progress.type) {
case 'downloading':
console.log(`Loading: ${progress.progress}%`)
break
case 'completed':
console.log('Load complete')
break
case 'failed':
console.error('Load failed:', progress.error)
break
}
})
Parameters:
| Parameter | Type | Description |
|---|
id | string | Avatar ID |
onProgress | (progress: LoadProgressInfo) => void | Progress callback |
Returns: Promise<Avatar | null>
clearAll()
Clear all cached avatar resources.
AvatarManager.shared.clearAll()
AvatarView
3D rendering view that displays the avatar.
import { AvatarView } from '@spatialwalk/avatarkit'
Constructor
const avatarView = new AvatarView(avatar, container)
| Parameter | Type | Description |
|---|
avatar | Avatar | Loaded avatar object |
container | HTMLElement | Container element (canvas auto-fills container) |
⚠️ Important: The container element MUST have non-zero width and height. The canvas will automatically fill the container size.
Instance Properties
| Property | Type | Description |
|---|
controller | AvatarController | Communication controller |
onFirstRendering | () => void | Callback when first frame renders |
avatarTransform | { x, y, scale } | Avatar position and scale |
Instance Methods
dispose()
Clean up view resources. Call when view is no longer needed.
AvatarController
Handles real-time communication with the avatar service.
// Accessed via AvatarView
const controller = avatarView.controller
Instance Properties
| Property | Type | Description |
|---|
connectionState | ConnectionState | Current connection state |
conversationState | ConversationState | Current conversation state |
Event Callbacks
// Connection state changes
controller.onConnectionState = (state: ConnectionState) => {
// 'disconnected' | 'connecting' | 'connected' | 'failed'
}
// Conversation state changes
controller.onConversationState = (state: ConversationState) => {
// 'idle' | 'playing' | 'pausing'
}
// Error handling
controller.onError = (error: AvatarError) => {
console.error('Error:', error.code, error.message)
}
Instance Methods
initializeAudioContext()
Initialize audio context. MUST be called in user gesture context.
button.addEventListener('click', async () => {
await controller.initializeAudioContext()
})
start()
Connect to the avatar service. SDK mode only.
send(audioData, end)
Send audio data to server. SDK mode only.
// Send audio data (continue)
controller.send(audioData, false)
// Send final audio data (end conversation)
controller.send(audioData, true)
| Parameter | Type | Description |
|---|
audioData | ArrayBuffer | PCM16 (S16LE) mono audio data. Byte length must be even (2 bytes per sample). |
end | boolean | Whether this is the final chunk |
Audio data byte length must be even (2 bytes per sample). Odd-length data will cause a server-side validation error and WebSocket disconnect.
Returns: string - Conversation ID
close()
Close service connection. SDK mode only.
Host Mode Methods
For Host Mode (DrivingServiceMode.host) only:
yieldAudioData(audioData, end)
Provide audio data in Host Mode.
const conversationId = controller.yieldAudioData(audioData, false)
yieldFramesData(frames, conversationId)
Provide animation frames in Host Mode.
controller.yieldFramesData(animationDataArray, conversationId)
Common Methods (Both Modes)
pause()
Pause current playback.
resume()
Resume paused playback.
await controller.resume()
interrupt()
Interrupt current playback and clear data.
clear()
Clear all data and resources.
getCurrentConversationId()
Get the current active conversation ID.
const conversationId = controller.getCurrentConversationId()
// Returns: string | null
volume
Playback volume property (avatar audio only, not system volume). Range: 0.0 to 1.0.
controller.volume = 0.5 // Set to 50%
const currentVolume = controller.volume // Get current volume
Types and Enums
Configuration
interface Configuration {
environment: Environment
drivingServiceMode?: DrivingServiceMode // Default: 'sdk'
logLevel?: LogLevel // Default: 'off'
audioFormat?: AudioFormat // Default: { channelCount: 1, sampleRate: 16000 }
}
Environment
enum Environment {
cn = 'cn', // China region
intl = 'intl' // International region
}
DrivingServiceMode
enum DrivingServiceMode {
sdk = 'sdk', // SDK handles WebSocket communication
host = 'host' // Host provides audio and animation data
}
LogLevel
enum LogLevel {
off = 'off',
error = 'error',
warning = 'warning',
all = 'all'
}
ConnectionState
enum ConnectionState {
disconnected = 'disconnected',
connecting = 'connecting',
connected = 'connected',
failed = 'failed'
}
ConversationState
enum ConversationState {
idle = 'idle', // Breathing animation
playing = 'playing', // Active conversation
paused = 'paused' // Paused during playback
}
LoadProgressInfo
type LoadProgressInfo = {
type: 'downloading' | 'completed' | 'failed'
progress?: number // 0-100
error?: Error
}
interface AudioFormat {
channelCount: 1 // Fixed to mono
sampleRate: number // 8000 | 16000 | 22050 | 24000 | 32000 | 44100 | 48000
}
Error Codes
| Code | Description | Recovery |
|---|
appIDUnrecognized | App ID not recognized. | Verify your app ID in the dashboard. |
sessionTokenInvalid | Session token is invalid or appId mismatch. | Verify token generation on your server. |
sessionTokenExpired | Session token has expired. | Request a new token from your server. |
insufficientBalance | Account balance is insufficient. | Top up your account in the dashboard. |
sessionTimeout | Session timed out. | Reconnect by calling start() again. |
concurrentLimitExceeded | Concurrent connection limit exceeded. | Close other active sessions. |
avatarIDUnrecognized | Avatar ID not found. | Check the avatar ID exists and is published. |
failedToFetchAvatarMetadata | Failed to fetch avatar metadata. | Check network connectivity and retry. |
failedToDownloadAvatarAssets | Failed to download avatar assets. | Check network connectivity and retry. |
websocketError | WebSocket connection error. | Check network and retry. |
websocketClosedAbnormally | WebSocket closed abnormally. | Retry connection. |
serverError | Server-side error. | Check the error message for details. |
audioContextNotInitialized | Audio context not initialized. | Call initializeAudioContext() in a user gesture handler first. |
Complete Usage Example
import {
AvatarSDK,
AvatarManager,
AvatarView,
Environment,
ConnectionState,
ConversationState,
} from '@spatialwalk/avatarkit'
class AvatarApp {
private avatarView: AvatarView | null = null
async init(appId: string, sessionToken: string, avatarId: string, container: HTMLElement) {
// Initialize SDK
await AvatarSDK.initialize(appId, { environment: Environment.cn })
AvatarSDK.setSessionToken(sessionToken)
// Load avatar
const avatar = await AvatarManager.shared.load(avatarId)
if (!avatar) throw new Error('Failed to load avatar')
// Create view
this.avatarView = new AvatarView(avatar, container)
this.avatarView.onFirstRendering = () => {
console.log('First frame rendered')
}
// Set up handlers
this.avatarView.controller.onConnectionState = (state) => {
console.log('Connection:', state)
}
this.avatarView.controller.onConversationState = (state) => {
console.log('Conversation:', state)
}
this.avatarView.controller.onError = (error) => {
console.error('Error:', error)
}
}
// Must be called in user gesture context
async start() {
await this.avatarView?.controller.initializeAudioContext()
await this.avatarView?.controller.start()
}
send(audioData: ArrayBuffer, isEnd: boolean) {
this.avatarView?.controller.send(audioData, isEnd)
}
interrupt() {
this.avatarView?.controller.interrupt()
}
dispose() {
this.avatarView?.controller.close()
this.avatarView?.dispose()
this.avatarView = null
}
}