Skip to main content

Quick Reference

ClassPurposeKey Methods
AvatarSDKSDK initializationinitialize(), setSessionToken()
AvatarManagerAvatar loadingload()
AvatarView3D renderingonFirstRendering, dispose()
AvatarControllerCommunicationstart(), 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.
export class AvatarSDK

AvatarSDK

Main entry point for SDK initialization and global configuration.
import { AvatarSDK, Environment } from '@spatialwalk/avatarkit'

Static Properties

PropertyTypeDescription
isInitializedbooleanWhether SDK is initialized
appIdstring | nullCurrent App ID
configurationConfigurationCurrent SDK configuration
sessionTokenstring | nullCurrent session token
userIdstring | nullCurrent user ID
versionstringSDK 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.
AvatarSDK.cleanup()

AvatarManager

Handles avatar loading and caching.
import { AvatarManager } from '@spatialwalk/avatarkit'

Static Properties

PropertyTypeDescription
sharedAvatarManagerSingleton 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:
ParameterTypeDescription
idstringAvatar ID
onProgress(progress: LoadProgressInfo) => voidProgress 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)
ParameterTypeDescription
avatarAvatarLoaded avatar object
containerHTMLElementContainer 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

PropertyTypeDescription
controllerAvatarControllerCommunication controller
onFirstRendering() => voidCallback when first frame renders
transform{ x, y, scale }Avatar position and scale

Instance Methods

dispose()

Clean up view resources. Call when view is no longer needed.
avatarView.dispose()

AvatarController

Handles real-time communication with the avatar service.
// Accessed via AvatarView
const controller = avatarView.controller

Instance Properties

PropertyTypeDescription
connectionStateConnectionStateCurrent connection state
conversationStateConversationStateCurrent 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: Error) => {
  console.error('Error:', error)
}

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.
await controller.start()

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)
ParameterTypeDescription
audioDataArrayBufferPCM16 mono audio data
endbooleanWhether this is the final chunk
Returns: string - Conversation ID

close()

Close service connection. SDK mode only.
controller.close()

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.
controller.pause()

resume()

Resume paused playback.
await controller.resume()

interrupt()

Interrupt current playback and clear data.
controller.interrupt()

clear()

Clear all data and resources.
controller.clear()

getCurrentConversationId()

Get the current active conversation ID.
const conversationId = controller.getCurrentConversationId()
// Returns: string | null

setVolume(volume) / getVolume()

Control playback volume (avatar audio only, not system volume).
controller.setVolume(0.5)  // 50% volume (0.0 to 1.0)
const currentVolume = controller.getVolume()

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
  pausing = 'pausing'   // Paused during playback
}

LoadProgressInfo

type LoadProgressInfo = {
  type: 'downloading' | 'completed' | 'failed'
  progress?: number  // 0-100
  error?: Error
}

AudioFormat

interface AudioFormat {
  channelCount: 1  // Fixed to mono
  sampleRate: number  // 8000 | 16000 | 22050 | 24000 | 32000 | 44100 | 48000
}

Error Codes

CodeNameDescriptionSolution
1001sdkNotVerifiedSDK not verifiedCheck SDK initialization
1002avatarIdWrongInvalid avatar IDVerify avatar ID
1003avatarAssetsMissingMissing avatar assetsCheck avatar resources
1004avatarCameraSettingsWrongInvalid camera settingsCheck camera config
1005serviceErrorServer errorCheck server status
1008sendDataWrongInvalid audio dataVerify PCM16 format
1009requestTimeoutRequest timeoutCheck network

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
  }
}