API Reference
Complete reference for all Kaltura Avatar Client SDK methods, properties, and events.
Constructor
new KalturaAvatarSession(apiKey?, config?)
Creates a new avatar session instance.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
apiKey | string | Optional | Your Kaltura Session (KS). Required only if SDK will create the session. Omit for backend-created sessions. |
config | AvatarConfig | No | Optional configuration object |
- Pass it: When the SDK should create sessions (FE-only flow)
- Omit it: When your backend creates sessions (recommended for production)
Config Options:
interface AvatarConfig {
baseUrl: string; // Backend API URL (required)
retryConfig?: RetryConfig; // Retry configuration
logLevel?: 'debug' | 'info' | 'warn' | 'error'; // Default: 'info'
}
interface RetryConfig {
maxAttempts: number; // Max retry attempts
initialDelayMs: number; // Initial delay in ms
maxDelayMs: number; // Max delay in ms
backoffMultiplier: number; // Exponential backoff multiplier
}
Examples:
// FE-Only: SDK creates the session (pass apiKey)
const session = new KalturaAvatarSession('your-kaltura-session', {
baseUrl: 'https://api.avatar.us.kaltura.ai/v1/avatar-session',
logLevel: 'info',
retryConfig: {
maxAttempts: 3,
initialDelayMs: 500,
maxDelayMs: 5000,
backoffMultiplier: 2,
},
});
// Backend-Created: Backend creates session, FE displays (no apiKey)
const session = new KalturaAvatarSession(undefined, {
baseUrl: 'https://api.avatar.us.kaltura.ai/v1/avatar-session',
logLevel: 'info',
});
// Then use initSession() with backend-provided credentials
Session Methods
createSession(options)
Create a new avatar session and establish WebRTC connection.
Parameters:
interface CreateSessionOptions {
avatarId: string; // Required - ID of the avatar
voiceId?: string; // Optional - ID of the voice for TTS
videoContainerId?: string; // Optional - ID of div to auto-attach video
}
Returns: Promise<void>
Example:
// With auto-attach
await session.createSession({
avatarId: 'avatar-123',
voiceId: 'voice-456',
videoContainerId: 'avatar-container',
});
// Without auto-attach
await session.createSession({
avatarId: 'avatar-123',
voiceId: 'voice-456',
});
What it does:
- Initializes the backend client
- Retrieves WHEP URL and TURN server configuration
- Establishes WebRTC connection
- Starts automatic keep-alive (every 10 seconds)
- Attaches video if
videoContainerIdis provided
initSession(session, options?)
Initialize a pre-created session from your backend. Use this when your backend creates the session (recommended for production).
Parameters:
interface InitSessionParams {
sessionId: string; // Required - from backend's create response
token: string; // Required - JWT token from backend
}
interface InitSessionOptions {
videoContainerId?: string; // Optional - ID of div to auto-attach video
}
Returns: Promise<void>
Example:
// Get session credentials from your backend
const { sessionId, token } = await fetch('/api/create-avatar-session').then(
(r) => r.json()
);
// Create SDK instance WITHOUT apiKey (backend already created session)
const session = new KalturaAvatarSession(undefined, {
baseUrl: 'https://api.avatar.us.kaltura.ai/v1/avatar-session',
});
// Initialize with backend-provided credentials
await session.initSession(
{ sessionId, token },
{ videoContainerId: 'avatar-container' }
);
// SDK is now ready to use
await session.sayText('Hello from backend-created session!');
When to use:
- Your backend creates the session and provides
sessionIdandtoken - For production applications (keeps Kaltura Session secure on server)
- When you need server-side control and validation
What it does:
- Injects the JWT token from backend
- Retrieves WHEP URL and TURN server configuration
- Establishes WebRTC connection
- Starts automatic keep-alive (every 10 seconds)
- Attaches video if
videoContainerIdis provided
Comparison with createSession():
| Aspect | createSession | initSession |
|---|---|---|
| Who creates session | SDK (using apiKey) | Backend server |
| apiKey needed | ✅ Yes | ❌ No |
| Use case | Demos, prototypes | Production apps |
| Security | ⚠️ KS in client | ✅ KS on server |
attachAvatar(containerId)
Attach avatar video to a container div by creating a video element inside it.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
containerId | string | Yes | ID of the div element |
Returns: void
Example:
session.attachAvatar('avatar-container');
HTML:
<div id="avatar-container" style="width: 512px; height: 512px;"></div>
Generated video element:
autoplayandplaysinlineattributes- Width and height set to 100%
- Appropriate styling for fullscreen display
sayText(text, turnId?, isFinal?)
Send text for the avatar to speak using text-to-speech.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
text | string | Yes | Text for the avatar to speak |
turnId | string | Optional | Unique identifier for this speech turn. Auto-generated if not provided. |
isFinal | boolean | Optional | Whether this is the final chunk (default: true). Use false for LLM streaming. |
Returns: Promise<void>
Examples:
// Simple usage (auto-generates turnId)
await session.sayText('Hello, how are you doing today?');
// With explicit turn tracking
const turnId = `turn-${Date.now()}`;
await session.sayText('Hello!', turnId, true);
// LLM streaming support (streaming chunks from LLM)
const streamTurnId = `turn-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
await session.sayText('Hello, ', streamTurnId, false); // More chunks coming
await session.sayText('how are you?', streamTurnId, true); // Final chunk
Parameters explained:
turnId: Unique identifier to track which speech turn this text belongs to. Useful for correlating avatar speech with your application state. Use the sameturnIdfor all chunks of a single turn.isFinal: For simple use cases, always usetrue. For LLM streaming where text arrives in chunks, usefalsefor intermediate chunks andtruefor the final one.
sayAudio(audioFile, turnId, duration)
Send an audio file for the avatar to speak.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
audioFile | File | Blob | Yes | MP3 file at 44.1 kHz |
turnId | string | Yes | Unique identifier for this speech turn |
duration | number | Yes | Duration of the audio in seconds |
Returns: Promise<void>
Example:
// Get duration via WebAudio API
async function getAudioDuration(file: File): Promise<number> {
const arrayBuffer = await file.arrayBuffer();
const audioCtx = new AudioContext();
const decoded = await audioCtx.decodeAudioData(arrayBuffer);
await audioCtx.close();
return decoded.duration;
}
const audioFile = new File([audioBlob], 'speech.mp3', { type: 'audio/mpeg' });
const duration = await getAudioDuration(audioFile);
const turnId = `turn-${Date.now()}`;
await session.sayAudio(audioFile, turnId, duration);
interrupt()
Interrupt the avatar's current speech.
Parameters: None
Returns: Promise<void>
Example:
await session.interrupt();
endSession()
End the session and cleanup resources.
Parameters: None
Returns: Promise<void>
Example:
await session.endSession();
What it does:
- Stops the automatic keep-alive interval
- Disconnects the WebRTC connection
- Ends the session on the backend
- Cleans up all resources
State Methods
getSessionId()
Get the current session ID.
Returns: string | null
Example:
const sessionId = session.getSessionId();
console.log('Session ID:', sessionId);
getSessionState()
Get current session state.
Returns: SessionState
Possible values:
'IDLE'- Not yet created'CREATING'- Session being created'READY'- Session ready for use'ENDED'- Session ended'ERROR'- Error occurred
Example:
const state = session.getSessionState();
console.log('Session state:', state);
getConnectionState()
Get current WebRTC connection state.
Returns: ConnectionState
Possible values:
'DISCONNECTED'- Not connected'CONNECTING'- Connection in progress'CONNECTED'- Connected and streaming'FAILED'- Connection failed'CLOSED'- Connection closed
Example:
const connState = session.getConnectionState();
console.log('Connection state:', connState);
Event Methods
on(event, callback)
Register event handlers.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
event | SessionEvent | Yes | Event name |
callback | Function | Yes | Event handler function |
Returns: void
Available Events:
'stateChange'- Session state changed'connectionChange'- WebRTC connection state changed'error'- Error occurred'speakingStart'- Avatar started speaking'speakingEnd'- Avatar stopped speaking
'stateChange'
Fired when session state changes.
session.on('stateChange', (state: SessionState) => {
console.log('Session state:', state);
});
'connectionChange'
Fired when WebRTC connection state changes.
session.on('connectionChange', (state: ConnectionState) => {
console.log('Connection state:', state);
});
'error'
Fired when an error occurs.
session.on('error', (error: AvatarError) => {
console.error('Error:', error.message, error.code);
});
'speakingStart'
Fired when the avatar starts speaking.
session.on('speakingStart', () => {
console.log('Avatar started speaking');
// Update UI to show speaking state
});
'speakingEnd'
Fired when the avatar stops speaking.
session.on('speakingEnd', () => {
console.log('Avatar stopped speaking');
// Update UI to show idle state
});
TypeScript Types
Enums
enum SessionState {
IDLE = 'IDLE',
CREATING = 'CREATING',
READY = 'READY',
ENDED = 'ENDED',
ERROR = 'ERROR',
}
enum ConnectionState {
DISCONNECTED = 'DISCONNECTED',
CONNECTING = 'CONNECTING',
CONNECTED = 'CONNECTED',
FAILED = 'FAILED',
CLOSED = 'CLOSED',
}
enum AvatarErrorCode {
INVALID_STATE = 'INVALID_STATE',
API_REQUEST_FAILED = 'API_REQUEST_FAILED',
RTC_CONNECTION_FAILED = 'RTC_CONNECTION_FAILED',
INVALID_CONFIGURATION = 'INVALID_CONFIGURATION',
SESSION_NOT_FOUND = 'SESSION_NOT_FOUND',
UNAUTHORIZED = 'UNAUTHORIZED',
}
Error Interface
class AvatarError extends Error {
code: AvatarErrorCode;
message: string;
details?: any;
}
Complete Examples
Pattern 1: FE-Only (SDK Creates Session)
import { KalturaAvatarSession, SessionState, ConnectionState, AvatarError, AvatarErrorCode } from '@unisphere/models-sdk-js';
async function runAvatarFEOnly() {
// Create instance with apiKey
const session = new KalturaAvatarSession('your-kaltura-session', {
baseUrl: 'https://api.avatar.us.kaltura.ai/v1/avatar-session',
logLevel: 'info',
});
// Event listeners
session.on('stateChange', (state: SessionState) => {
console.log('State:', state);
});
session.on('error', (error: AvatarError) => {
console.error('Error:', error.code, error.message);
});
try {
// Create session (SDK creates it using apiKey)
await session.createSession({
avatarId: 'avatar-123',
voiceId: 'voice-456',
videoContainerId: 'avatar-container',
});
console.log('Session ID:', session.getSessionId());
// Say text
await session.sayText('Hello from Kaltura Avatar!');
// Wait...
await new Promise((r) => setTimeout(r, 5000));
// End session
await session.endSession();
} catch (error) {
console.error('Failed:', error);
}
}
Pattern 2: Backend-Created (Recommended for Production)
import { KalturaAvatarSession, SessionState, AvatarError } from '@unisphere/models-sdk-js';
async function runAvatarBECreated() {
// Get session from your backend
const { sessionId, token } = await fetch('/api/create-avatar-session').then(
(r) => r.json()
);
// Create instance WITHOUT apiKey (no need, backend created session)
const session = new KalturaAvatarSession(undefined, {
baseUrl: 'https://api.avatar.us.kaltura.ai/v1/avatar-session',
logLevel: 'info',
});
// Event listeners
session.on('stateChange', (state: SessionState) => {
console.log('State:', state);
});
session.on('error', (error: AvatarError) => {
console.error('Error:', error.code, error.message);
});
try {
// Initialize with backend-provided credentials
await session.initSession(
{ sessionId, token },
{ videoContainerId: 'avatar-container' }
);
console.log('Session ID:', session.getSessionId());
// Say text
const turnId = `turn-${Date.now()}`;
await session.sayText('Hello from backend-created session!', turnId, true);
// Wait...
await new Promise((r) => setTimeout(r, 5000));
// End session
await session.endSession();
} catch (error) {
console.error('Failed:', error);
}
}
Next Steps
- State Management - Learn about states and events
- Error Handling - Handle errors gracefully
- Advanced Usage - Custom ICE servers and more