Advanced Usage - Agentic Avatars SDK
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:
// 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:
const session = new KalturaAvatarSession({
apiKey: 'your-api-key',
baseUrl: '...',
logLevel: 'debug', // 'debug' | 'info' | 'warn' | 'error'
});
Log levels:
debug- All logs including verbose debug infoinfo- Normal operation logs (default)warn- Warnings onlyerror- Errors only
Say Text with Streaming Support
Use sayText with turnId and isFinal parameters for LLM streaming:
// 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:
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:
// 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:
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:
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 - Complete working examples
- Production Deployment - Best practices
- Troubleshooting - Common issues and solutions