Skip to main content
This page covers the client side of Agora Convo AI Integration for Web, iOS, and Android. The client joins the Agora channel and renders the avatar audio and motion data produced by the server-side Spatius integration and Motion Server.
PlatformPackageProvider
Web@spatius/avatarkit-rtc with agora-rtc-sdk-ngAgoraProvider
iOSAvatarKitRTC from spatius-ai/avatarkit-ios-rtcAgoraProvider
Androidai.spatius:avatarkit-rtcAgoraProvider
When using an AvatarKit RTC client, do not create and manage a separate Agora client for avatar playback. The platform RTC package owns the Agora client internally so it can wire audio, motion data, and lifecycle handling correctly.

Install and connect

Install the AvatarKit Web SDK, the Web RTC Adapter, and the Agora Web SDK peer dependency:
pnpm add @spatius/avatarkit-rtc @spatius/avatarkit agora-rtc-sdk-ng
Configure your build tool to load the AvatarKit WebAssembly assets. See Toolchain Setup.
import { AvatarPlayer, AgoraProvider } from '@spatius/avatarkit-rtc'
import { AvatarSDK, AvatarView, AvatarManager, DrivingServiceMode } from '@spatius/avatarkit'

async function init() {
  await AvatarSDK.initialize('your-spatius-app-id', {
    drivingServiceMode: DrivingServiceMode.host,
  })

  const avatar = await AvatarManager.shared.load('your-spatius-avatar-id')
  const container = document.getElementById('avatar-container')!
  const avatarView = new AvatarView(avatar, container)

  const provider = new AgoraProvider()
  const player = new AvatarPlayer(provider, avatarView, {
    logLevel: 'info',
  })

  player.on('connected', () => console.log('Connected to Agora'))
  player.on('disconnected', () => console.log('Disconnected from Agora'))
  player.on('error', (err) => console.error('Avatar RTC error:', err))
  player.on('stalled', async () => {
    console.log('Avatar stream stalled, reconnecting...')
    await player.reconnect()
  })

  await player.connect({
    appId: 'your-agora-app-id',
    channel: 'your-agora-channel',
    token: 'agora-rtc-token-for-uid-1001',
    uid: 1001,
  })

  await player.startPublishing()
}
Microphone control:
await player.startPublishing()
await player.stopPublishing()
Custom audio publishing for non-microphone sources:
await player.publishAudio(track)
await player.unpublishAudio()
Audio sourceHow to obtain track
<audio> elementaudioElement.captureStream().getAudioTracks()[0]
Screen share audiogetDisplayMedia({ audio: true })
Web Audio APIaudioContext.createMediaStreamDestination().stream.getAudioTracks()[0]
unpublishAudio() does not stop the track. You are responsible for calling track.stop() to release the resource.
Access the underlying Agora client only for advanced features:
import type { AgoraClient } from '@spatius/avatarkit-rtc'

const client = provider.getNativeClient()  // AgoraClient | null
const sameClient = player.getNativeClient() as AgoraClient | null

console.log('Agora connection state:', client?.connectionState)

Connection config

FieldDescription
appIdAgora App ID.
channelAgora channel name. Must match params.agora_channel in the TEN extension.
tokenAgora RTC token for this client participant. Optional only for testing setups that allow tokenless joins. The client SDKs do not fetch tokens.
uidAgora UID for this client participant. Use a unique UID that does not collide with the avatar publisher UID.

Channel notes

  • The user’s microphone audio is published into the Agora channel. Convo AI handles the voice agent pipeline, while the Spatius avatar provider or TEN extension handles avatar output on the server side.
  • The TEN extension uses params.agora_uid as the avatar publisher UID. Do not reuse that UID for Web, iOS, or Android clients.
  • Generate Agora RTC tokens on your backend and pass them to clients. Do not ship an Agora App Certificate in client code.
  • No Spatius Session Token is needed on this RTC path. The client renders with externally supplied audio and motion data.

Events

The AvatarPlayer event surface is shared across platforms.
EventDescription
connected / ConnectedConnected to RTC server.
disconnected / DisconnectedDisconnected from RTC server.
error / ErrorAn error occurred.
connectionStateChanged / ConnectionStateChangedConnection state changed.
stalled / StalledData stream stalled with no frames.
When a stalled event fires, the avatar automatically transitions to idle animation. Consider calling reconnect() to recover.

Next steps

Convo AI Agent

Configure Spatius in the managed Convo AI start-agent request.

TEN Extension

Configure spatius_avatar_python in a direct TEN Framework graph.

RTC Adapter reference

Review the Web AvatarPlayer provider model.