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

# AvatarKit Flutter SDK Reference

> AvatarKit Flutter SDK reference for Direct Mode, Backend Mode client feed, state callbacks, and demos.

## Installation

Add the Flutter package from [pub.dev](https://pub.dev/packages/spatius_avatarkit):

```bash theme={null}
flutter pub add spatius_avatarkit
```

The package supports iOS and Android Flutter apps.

## Import

```dart theme={null}
import 'package:spatius_avatarkit/spatius_avatarkit.dart';
```

## Initialize

Initialize AvatarKit once before loading avatars or creating an avatar view.

```dart theme={null}
await AvatarSDK.initialize(
  appID: appId,
  configuration: Configuration(
    drivingServiceMode: DrivingServiceMode.direct,
    logLevel: LogLevel.all,
  ),
);

await AvatarSDK.setSessionToken(sessionToken);
```

Use `DrivingServiceMode.direct` for [Direct Mode](/direct-mode/client). Use `DrivingServiceMode.backend` when your Flutter app receives response audio and motion data from [Backend Mode Client](/backend-mode/client-sdk).

`initialize` fails fast when `appID` is missing, rather than returning silently. Get an App ID from [app.spatius.ai](https://app.spatius.ai/).

### Configuration

| Field | What it does |
| - | - |
| `region` | Defaults to `'auto'`: the SDK selects the closest serving region at initialization and reuses the cached choice on later launches. Pass `'us-west'`, `'ap-northeast'`, or `'cn-beijing'` to force that region. If automatic selection cannot be reached, the SDK falls back to a default region and continues initializing. |
| `drivingServiceMode` | `direct` or `backend`, as described above. |
| `logLevel` | SDK log verbosity. |
| `renderQuality` | Rendering quality tier. Defaults to `RenderQuality.ultra`. |

The audio format is not part of `Configuration`. Set it per view with `AvatarWidget(audioFormat:)`; see [AudioFormat](#audioformat).

### RenderQuality

`RenderQuality.ultra` is the default and highest-quality tier. Use `high` or `standard` only when you intentionally trade visual quality for lower rendering cost.

```dart theme={null}
enum RenderQuality { standard, high, ultra }

await AvatarSDK.setRenderQuality(RenderQuality.ultra);
```

### AudioFormat

Each avatar view has its own audio format, so two views in one app can run different sample rates. Pass it to `AvatarWidget(audioFormat:)` when you create the view; it defaults to 16 kHz PCM. The value is used when the native view is created, so changing the widget property afterwards has no effect. Use `AvatarController.setAudioFormat` to change it at runtime.

```dart theme={null}
const AudioFormat({
  int sampleRate = 16000,
  AudioCodec inputAudioFormat = AudioCodec.pcm,
  bool opusUplinkEnabled = true,
  int opusBitrate = 48000,
})
```

| Field | What it does |
| - | - |
| `sampleRate` | Sample rate in Hz. Supported: 8000, 16000, 22050, 24000, 32000, 44100, 48000. Not used when `inputAudioFormat` is `AudioCodec.opus`: Opus always decodes at 48 kHz, so the session runs at 48000. |
| `inputAudioFormat` | The codec of the audio you feed into the SDK via `send` / `yieldAudioData`. `AudioCodec.pcm` (default) for raw PCM16, `AudioCodec.opus` for Opus. Change it on a live view with `setAudioFormat`. |
| `opusUplinkEnabled` | Whether the SDK compresses the Direct Mode uplink to Opus. On by default, which reduces the upload to roughly an eighth at the cost of encoding on the client. Set `false` to keep a raw PCM uplink. Not used in Backend Mode, which has no uplink, or with Opus input, which is already compressed. With PCM input, `sampleRate` must be 8000, 16000, 24000, or 48000; on any other rate the SDK logs a warning and sends raw PCM instead of failing. |
| `opusBitrate` | Target bitrate in bits/sec for the uplink the SDK encodes. Defaults to 48000. Higher means better quality and a larger upload. |

Audio that does not match the declared `inputAudioFormat` is reported through `AvatarController.onError` as `AvatarError.invalidAudioInput`.

`AudioFormat` has value equality and converts with `toJson()` / `AudioFormat.fromJson()`.

### Change the audio format at runtime

Read the format in effect for a view with `controller.audioFormat()`. It returns the format after the SDK's normalization, for example 48000 Hz for Opus input.

```dart theme={null}
final format = await controller.audioFormat();

await controller.setAudioFormat(sampleRate: 24000);
await controller.start(); // Direct Mode: reconnect, then send audio in the new format.
```

`setAudioFormat({sampleRate, inputAudioFormat, opusBitrate, opusUplinkEnabled})` changes the format of a live view without tearing the SDK down. Every parameter is optional; `null` keeps the current value.

* Any change interrupts whatever is playing and, in Direct Mode, disconnects. Call `start()` again and feed audio in the new format.
* Switching `inputAudioFormat` to `AudioCodec.opus` pins the sample rate at 48000. Switching back to `AudioCodec.pcm` keeps the current rate unless you pass `sampleRate` in the same call.
* Accepted sample rates are 8000, 16000, 22050, 24000, 32000, 44100, and 48000. An unsupported rate, or a `sampleRate` paired with Opus input, is logged by the SDK and leaves the format unchanged.

## Load an avatar

```dart theme={null}
final avatar = await AvatarManager.shared.load(
  id: avatarId,
  onProgress: (progress) {
    // Update loading UI.
  },
);
```

## Render and control playback

The Flutter view creates an `AvatarController` when the platform view is ready. Keep that controller and use it for lifecycle, state, and audio operations.

```dart theme={null}
void onAvatarViewCreated(AvatarController controller) {
  controller.onConnectionState = (state, errorMessage) {
    // Observe Direct Mode connection state.
  };

  controller.onConversationState = (state) {
    // Observe avatar playback state.
  };

  controller.onError = (error) {
    // Log or surface AvatarError.
  };
}
```

### Render over an Avatar Background

Download the optional 16:9 background from Spatius Studio, add it to your Flutter assets, and declare it in `pubspec.yaml`.

```yaml theme={null}
flutter:
  assets:
    - assets/avatar-background.webp
```

Place the background and `AvatarWidget` in the same `Stack`, with the image first.

```dart theme={null}
AspectRatio(
  aspectRatio: 16 / 9,
  child: ClipRect(
    child: Stack(
      fit: StackFit.expand,
      children: [
        Image.asset(
          'assets/avatar-background.webp',
          fit: BoxFit.cover,
        ),
        AvatarWidget(
          avatar: avatar,
          audioFormat: const AudioFormat(sampleRate: 16000),
          onPlatformViewCreated: onAvatarViewCreated,
        ),
      ],
    ),
  ),
)
```

For square or portrait display windows, center this 16:9 stage inside a clipped outer widget. See [Avatar Background](/concepts/avatar-background) for the shared cropping rules.

For Direct Mode audio input, start the connection and send PCM chunks:

```dart theme={null}
await controller.start();
controller.send(audioBytes, end: isLastChunk);
```

For audio source and timing guidance, see [Audio](/concepts/audio).

For Backend Mode input, feed the response audio and motion data received from your backend:

```dart theme={null}
final conversationId = await controller.yieldAudioData(audioBytes, end: isLastChunk);
controller.yieldAnimations(framesData, conversationID: conversationId);
```

<Note>
  The per-call `audioFormat` parameter of `yieldAudioData` is deprecated and ignored. The format comes from the view: `AvatarWidget.audioFormat`, or whatever `setAudioFormat` last applied. Drop the argument if you still pass it; it will be removed in a future release. The iOS and Android SDKs have already removed theirs.
</Note>

## Demos

<CardGroup cols={2}>
  <Card title="Flutter Direct Mode demo" icon="github" href="https://github.com/spatius-ai/spatius-integration-demo/tree/main/direct-mode/clients/flutter" />

  <Card title="Flutter Backend Mode demo" icon="github" href="https://github.com/spatius-ai/spatius-integration-demo/tree/main/backend-mode/clients/flutter" />
</CardGroup>


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