---
title: Advanced Usage
url: https://docs.kaltura.com/docs/conversational-agents/agentic-avatars-sdk/client-sdk-advanced
---

## Advanced Usage

Advanced topics and customization options for the Kaltura Avatar Client SDK.

### Understanding the apiKey Parameter

The `KalturaAvatarSession` constructor accepts an optional `apiKey` in the configuration object:

```typescript
// FE-only control - SDK creates the session
const session = new KalturaAvatarSession({
  apiKey: 'your-kaltura-session',
  ...config
});
await session.createSession({ visualId: 'visual-123' });

// BE/FE split - Backend creates session, SDK displays only
const session = new KalturaAvatarSession(config); // No apiKey needed!
const { sessionId, token } = await myBackend.createSession();
await session.initSession({ sessionId, token });
```

**When to include apiKey in config:**

- Only when you want the SDK to create sessions (demos, quick testing)
- Not recommended for production

**When to omit apiKey:**

- When backend creates sessions (recommended)
- In `initSession()` flow - token comes from backend

> **New Signature**
>
> The apiKey is now part of the config object for a cleaner API. The legacy signature `new KalturaAvatarSession(apiKey, config)` still works but shows a deprecation warning.

### Custom Logging

Configure logging levels for debugging:

```typescript
const session = new KalturaAvatarSession({
  apiKey: 'your-api-key',
  baseUrl: '...',
  logLevel: 'debug', // 'debug' | 'info' | 'warn' | 'error'
});
```

**Log levels:**

- `debug` - All logs including verbose debug info
- `info` - Normal operation logs (default)
- `warn` - Warnings only
- `error` - Errors only

### Say Text with Streaming Support

Use `sayText` with `turnId` and `isFinal` parameters for LLM streaming:

```typescript
// Generate unique turn ID for this conversation turn
const turnId = `turn-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;

// Streaming chunks from LLM
const chunks = ['Hello, ', 'this is ', 'a ', 'streaming ', 'response.'];

for (let i = 0; i < chunks.length; i++) {
  const isFinal = i === chunks.length - 1; // Last chunk?
  await session.sayText(chunks[i], turnId, isFinal);
}
```

### Multiple Sessions

Run multiple avatar sessions simultaneously:

```typescript
const session1 = new KalturaAvatarSession({
  apiKey: 'your-api-key',
  ...config
});

const session2 = new KalturaAvatarSession({
  apiKey: 'your-api-key',
  ...config
});

await Promise.all([
  session1.createSession({
    visualId: 'visual-1',
    videoContainerId: 'container-1',
  }),
  session2.createSession({
    visualId: 'visual-2',
    videoContainerId: 'container-2',
  }),
]);

// Control them independently
await session1.sayText('Hello from avatar 1');
await session2.sayText('Hello from avatar 2');
```

### Custom Video Element Handling

If you need full control over the video element:

```typescript
// Create session without auto-attach
await session.createSession({
  visualId: 'visual-123',
});

// Get the media stream manually
const stream = session.getMediaStream(); // Advanced: not in basic API

// Create your own video element
const video = document.createElement('video');
video.srcObject = stream;
video.autoplay = true;
video.playsinline = true;
video.style.width = '100%';

// Custom container setup
const container = document.getElementById('my-custom-container');
container.appendChild(video);
```

#### Connection Quality

Monitor connection quality:

```typescript
session.on('connectionChange', (state) => {
  if (state === 'CONNECTED') {
    console.log('Streaming started');
  } else if (state === 'FAILED') {
    console.log('Poor network quality');
  }
});
```

### TypeScript Tips

Full TypeScript support with no additional packages needed:

```typescript
import type {
  AvatarConfig,
  CreateSessionOptions,
  SessionState,
  ConnectionState,
  AvatarError,
  AvatarErrorCode,
  TTSLanguage,
  CatalogServiceConfig,
  CatalogItem,
} from '@unisphere/models-sdk-js';

import { TTSLanguages, CatalogService } from '@unisphere/models-sdk-js';

const config: AvatarConfig = {
  baseUrl: 'https://api.avatar.us.kaltura.ai/',
  logLevel: 'info',
};

const options: CreateSessionOptions = {
  visualId: 'visual-123',
  voiceId: 'voice-456',
  language: TTSLanguages.ENGLISH,
  videoContainerId: 'avatar-container',
};
```

### Next Steps

- **[Examples](./examples-simple-client-side)** - Complete working examples
- **Production Deployment** - Best practices
- **Troubleshooting** - Common issues and solutions
