> ## 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.

# Agora Convo AI Client

> Join the Agora channel and render the Avatar with a packaged AgoraProvider.

## Before you start

Start the Convo AI agent or TEN graph on your backend, then return this runtime configuration to the app:

| Value | Source |
| - | - |
| Spatius App ID and Avatar ID | The values used by the agent setup |
| Agora App ID and channel | Your Agora project and agent session |
| Client UID and RTC token | Generated by your backend for this participant |

Use a different Agora UID for the client, conversational agent, and avatar publisher. Never send the Spatius API Key or Agora App Certificate to the app. This path does not use a Spatius Session Token.

## Connect the client

<Tabs>
  <Tab title="Web">
    Install AvatarKit, the Web RTC Adapter, and Agora's Web SDK:

    ```bash theme={null}
    pnpm add @spatius/avatarkit @spatius/avatarkit-rtc agora-rtc-sdk-ng
    ```

    Configure the AvatarKit WebAssembly assets for [Vite or Next.js](/sdk-reference/web-sdk/toolchain), then connect:

    ```typescript theme={null}
    import { AvatarManager, AvatarSDK, AvatarView, DrivingServiceMode } from '@spatius/avatarkit'
    import { AgoraProvider, AvatarPlayer } from '@spatius/avatarkit-rtc'

    await AvatarSDK.initialize(spatiusAppId, {
      drivingServiceMode: DrivingServiceMode.rtc,
    })

    const avatar = await AvatarManager.shared.load(avatarId)
    const avatarView = new AvatarView(
      avatar,
      document.getElementById('avatar-container')!,
    )
    const player = new AvatarPlayer(new AgoraProvider(), avatarView, {
      logLevel: 'info',
    })

    await player.connect({
      appId: agoraAppId,
      channel,
      token: clientToken,
      uid: clientUid,
    })

    await player.startPublishing()

    async function disconnectAvatar() {
      await player.stopPublishing()
      await player.disconnect()
      avatarView.dispose()
    }
    ```

    Call the connect flow from a user action so the browser can request microphone permission.

    [Web RTC Adapter Reference](/sdk-reference/web-sdk/rtc-adapter)
  </Tab>

  <Tab title="iOS">
    Install `AvatarKitRTC` with Swift Package Manager or CocoaPods:

    In Xcode, open **File > Add Package Dependencies**, enter `https://github.com/spatius-ai/avatarkit-ios-rtc.git`, and select the latest stable release.

    ```ruby theme={null}
    pod 'AvatarKitRTC'
    ```

    Initialize AvatarKit in RTC mode, load the Avatar, and connect:

    ```swift theme={null}
    import AvatarKit
    import AvatarKitRTC

    AvatarSDK.initialize(
        appID: spatiusAppID,
        configuration: Configuration(drivingServiceMode: .rtc)
    )

    let avatar = try await AvatarManager.shared.load(id: avatarID)
    let avatarView = AvatarView(avatar: avatar)
    let player = AvatarPlayer(
        provider: AgoraProvider(),
        avatarView: avatarView,
        options: AvatarPlayerOptions(logLevel: .info)
    )

    try await player.connect(AgoraConnectionConfig(
        appId: agoraAppID,
        channel: channel,
        token: clientToken,
        uid: clientUID
    ))

    try await player.publishAudio()

    func disconnectAvatar() async {
        await player.unpublishAudio()
        await player.disconnect()
    }
    ```

    Add `NSMicrophoneUsageDescription` to the app and request microphone permission before calling `publishAudio()`.

    <Note>
      The default `connect(_:)` path lets `AgoraProvider` own the engine. If your iOS app already owns an `AgoraRtcEngineKit`, call `attach(to:)` before joining the channel instead. The two paths are mutually exclusive; do not create a second engine only for avatar playback.
    </Note>
  </Tab>

  <Tab title="Android">
    Add the Android RTC package:

    ```kotlin theme={null}
    implementation("ai.spatius:avatarkit-rtc:<latest-version>")
    ```

    Use the latest stable release from [Maven Central](https://central.sonatype.com/artifact/ai.spatius/avatarkit-rtc).

    Initialize AvatarKit in RTC mode, load the Avatar, then connect the player:

    ```kotlin theme={null}
    import ai.spatius.avatarkit.AvatarSDK
    import ai.spatius.avatarkit.AvatarView
    import ai.spatius.avatarkit.Configuration
    import ai.spatius.avatarkit.DrivingServiceMode
    import ai.spatius.avatarkit.assets.AvatarManager
    import ai.spatius.avatarkit.rtc.AgoraConnectionConfig
    import ai.spatius.avatarkit.rtc.AvatarPlayer
    import ai.spatius.avatarkit.rtc.AvatarPlayerOptions
    import ai.spatius.avatarkit.rtc.RTCLogLevel
    import ai.spatius.avatarkit.rtc.providers.AgoraProvider

    AvatarSDK.initialize(
        context = context,
        appId = spatiusAppId,
        configuration = Configuration(
            drivingServiceMode = DrivingServiceMode.RTC,
        ),
    )

    AvatarManager.initialize(context)
    val avatar = AvatarManager.load(avatarId) ?: error("Avatar load failed")
    val avatarView = AvatarView(context)
    avatarView.init(avatar, lifecycleScope)

    val player = AvatarPlayer(
        provider = AgoraProvider(context),
        avatarView = avatarView,
        options = AvatarPlayerOptions(logLevel = RTCLogLevel.INFO),
    )

    player.connect(
        AgoraConnectionConfig(
            appId = agoraAppId,
            channel = channel,
            token = clientToken,
            uid = clientUid,
        )
    )

    player.publishAudio()

    suspend fun disconnectAvatar() {
        player.unpublishAudio()
        player.disconnect()
    }
    ```

    Declare `android.permission.RECORD_AUDIO` and request the runtime permission before calling `publishAudio()`.
  </Tab>
</Tabs>

The packaged `AgoraProvider` coordinates audio and motion data. On the default `connect` path, it also owns the RTC lifecycle. Do not also call Backend Mode feed methods.

## Next steps

<CardGroup cols={3}>
  <Card title="Scenario demo" icon="github" href="https://github.com/spatius-ai/spatius-scenario-demo" />

  <Card title="Integration demo" icon="github" href="https://github.com/spatius-ai/spatius-integration-demo/tree/main/rtc-mode" />

  <Card title="Client lifecycle" icon="arrows-rotate" href="/concepts/lifecycle" />
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.