AvatarKit follows a four-stage lifecycle: Initialize → Load → Connect → Cleanup. Each stage maps to a core component.
Overview
| Stage | Component | What happens |
|---|
| Initialize | AvatarSDK | Configures app ID, environment, audio format, and driving mode. Must be called once before any other API. |
| Load | AvatarManager | Downloads and caches avatar assets. Returns an Avatar instance. |
| Render | AvatarView | Creates the rendering surface and its associated AvatarController. |
| Connect | AvatarController | Opens a WebSocket to the driving service. The avatar begins responding to audio. |
Stage 1: Initialize
Call AvatarSDK.initialize() once at app startup. This sets global configuration that all subsequent operations depend on.
await AvatarSDK.initialize({
appId: 'YOUR_APP_ID',
audioFormat: { channelCount: 1, sampleRate: 16000 },
drivingServiceMode: 'sdk',
});
AvatarSDK.initialize(
appID: "YOUR_APP_ID",
configuration: Configuration(
environment: .intl,
audioFormat: AudioFormat(sampleRate: 16000),
drivingServiceMode: .sdk,
logLevel: .warning
)
)
AvatarSDK.initialize(
context = applicationContext,
appId = "YOUR_APP_ID",
configuration = Configuration(
environment = Environment.Intl,
audioFormat = AudioFormat(16000),
drivingServiceMode = DrivingServiceMode.SDK,
logLevel = LogLevel.INFO
)
)
Set AvatarSDK.sessionToken before connecting. The token authenticates your session with the driving service.
Stage 2: Load Avatar
Use AvatarManager to download and cache avatar assets. Loading is asynchronous and supports progress tracking.
const avatar = await AvatarManager.load('AVATAR_ID', (progress) => {
console.log('Loading:', progress);
});
let avatar = try await AvatarManager.shared.load(id: "AVATAR_ID") { progress in
print("Loading: \(progress)")
}
val avatar = AvatarManager.load("AVATAR_ID") { progress ->
Log.d("Avatar", "Loading: $progress")
}
Loaded assets are cached locally. Subsequent loads for the same avatar ID skip the download. Use AvatarManager.clear(id:) or clearAll() to manage cache.
Stage 3: Render
Create an AvatarView with the loaded avatar. The view automatically creates an AvatarController you can access to manage the connection and send audio.
const avatarView = new AvatarView(containerElement, avatar);
const controller = avatarView.avatarController;
let avatarView = AvatarView(avatar: avatar)
let controller = avatarView.controller
val avatarView = AvatarView(context)
avatarView.init(avatar, lifecycleScope)
val controller = avatarView.avatarController
Stage 4: Connect and Interact
Call controller.start() to open the WebSocket connection. Once connected, send audio with controller.send() (SDK Mode) or controller.yield() (Host Mode).
Call controller.interrupt() to stop the current playback immediately. Call controller.close() when done.
Cleanup
Always clean up resources when the avatar is no longer needed to avoid memory leaks.
controller.close();
avatarView.destroy();
// AvatarView handles cleanup when removed from the view hierarchy.
// To explicitly close the connection:
controller.close()
controller?.close()
avatarView.cleanup()
On Android, always call avatarView.cleanup() when the view is removed (e.g., in onDestroy). Failing to do so can leak GPU resources.