Skip to main content

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:

ParameterTypeRequiredDescription
apiKeystringOptionalYour Kaltura Session (KS). Required only if SDK will create the session. Omit for backend-created sessions.
configAvatarConfigNoOptional configuration object
apiKey is Optional
  • 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:

  1. Initializes the backend client
  2. Retrieves WHEP URL and TURN server configuration
  3. Establishes WebRTC connection
  4. Starts automatic keep-alive (every 10 seconds)
  5. Attaches video if videoContainerId is 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 sessionId and token
  • For production applications (keeps Kaltura Session secure on server)
  • When you need server-side control and validation

What it does:

  1. Injects the JWT token from backend
  2. Retrieves WHEP URL and TURN server configuration
  3. Establishes WebRTC connection
  4. Starts automatic keep-alive (every 10 seconds)
  5. Attaches video if videoContainerId is provided

Comparison with createSession():

AspectcreateSessioninitSession
Who creates sessionSDK (using apiKey)Backend server
apiKey needed✅ Yes❌ No
Use caseDemos, prototypesProduction 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:

ParameterTypeRequiredDescription
containerIdstringYesID 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:

  • autoplay and playsinline attributes
  • 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:

ParameterTypeRequiredDescription
textstringYesText for the avatar to speak
turnIdstringOptionalUnique identifier for this speech turn. Auto-generated if not provided.
isFinalbooleanOptionalWhether 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 same turnId for all chunks of a single turn.
  • isFinal: For simple use cases, always use true. For LLM streaming where text arrives in chunks, use false for intermediate chunks and true for the final one.

sayAudio(audioFile, turnId, duration)

Send an audio file for the avatar to speak.

Parameters:

ParameterTypeRequiredDescription
audioFileFile | BlobYesMP3 file at 44.1 kHz
turnIdstringYesUnique identifier for this speech turn
durationnumberYesDuration 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:

ParameterTypeRequiredDescription
eventSessionEventYesEvent name
callbackFunctionYesEvent 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);
}
}
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