---
title: State Management
url: https://docs.kaltura.com/docs/conversational-agents/agentic-avatars-sdk/client-sdk-state-management
---

## State Management

Learn how to track and respond to avatar session states and connection states.

### Session States

The avatar session progresses through several states:

```
IDLE -> CREATING -> READY -> ENDED
                     |
                   ERROR
```

#### State Definitions

| State | Description |
|-------|-------------|
| `IDLE` | Initial state, no session created yet |
| `CREATING` | Session is being created (API calls in progress) |
| `READY` | Session is ready, avatar can be controlled |
| `ENDED` | Session has been ended |
| `ERROR` | An error occurred during session creation or use |

#### Checking Current State

```javascript
const state = session.getSessionState();
console.log('Current state:', state);

if (state === 'READY') {
  // Safe to call sayText, interrupt, etc.
}
```

#### Listening to State Changes

```javascript
session.on('stateChange', (state) => {
  console.log('State changed to:', state);

  switch (state) {
    case 'IDLE':
      console.log('Session not started');
      break;
    case 'CREATING':
      console.log('Creating session...');
      break;
    case 'READY':
      console.log('Avatar ready!');
      break;
    case 'ENDED':
      console.log('Session ended');
      break;
    case 'ERROR':
      console.log('Error occurred');
      break;
  }
});
```

### Connection States

WebRTC connection states track the streaming connection:

```
DISCONNECTED -> CONNECTING -> CONNECTED
                    |             |
                  FAILED        CLOSED
```

#### State Definitions

| State | Description |
|-------|-------------|
| `DISCONNECTED` | No WebRTC connection |
| `CONNECTING` | WebRTC connection in progress |
| `CONNECTED` | WebRTC streaming active |
| `FAILED` | WebRTC connection failed |
| `CLOSED` | WebRTC connection closed |

#### Checking Connection State

```javascript
const connState = session.getConnectionState();
console.log('Connection state:', connState);

if (connState === 'CONNECTED') {
  // Video is streaming
}
```

#### Listening to Connection Changes

```javascript
session.on('connectionChange', (state) => {
  console.log('Connection state:', state);

  switch (state) {
    case 'DISCONNECTED':
      console.log('Not connected');
      break;
    case 'CONNECTING':
      console.log('Connecting...');
      break;
    case 'CONNECTED':
      console.log('Streaming!');
      break;
    case 'FAILED':
      console.log('Connection failed');
      break;
    case 'CLOSED':
      console.log('Connection closed');
      break;
  }
});
```

### Complete State Management Example

```javascript
import { KalturaAvatarSession } from '@unisphere/models-sdk-js';

const session = new KalturaAvatarSession({
  apiKey: 'your-api-key',
  baseUrl: 'https://api.avatar.us.kaltura.ai/',
});

// UI elements
const statusEl = document.getElementById('status');
const videoContainer = document.getElementById('avatar-container');

// Session state management
session.on('stateChange', (state) => {
  statusEl.textContent = `Session: ${state}`;

  switch (state) {
    case 'CREATING':
      statusEl.className = 'status-creating';
      break;
    case 'READY':
      statusEl.className = 'status-ready';
      enableControls();
      break;
    case 'ENDED':
      statusEl.className = 'status-ended';
      disableControls();
      break;
    case 'ERROR':
      statusEl.className = 'status-error';
      disableControls();
      break;
  }
});

// Connection state management
session.on('connectionChange', (state) => {
  const connStatusEl = document.getElementById('conn-status');
  connStatusEl.textContent = `Connection: ${state}`;

  switch (state) {
    case 'CONNECTING':
      videoContainer.classList.add('loading');
      break;
    case 'CONNECTED':
      videoContainer.classList.remove('loading');
      videoContainer.classList.add('streaming');
      break;
    case 'FAILED':
      videoContainer.classList.add('error');
      alert('Connection failed. Please refresh.');
      break;
  }
});

// Error handling
session.on('error', (error) => {
  console.error('Error:', error.code, error.message);
  document.getElementById('error-msg').textContent = error.message;
});

function enableControls() {
  document.querySelectorAll('button').forEach((btn) => {
    btn.disabled = false;
  });
}

function disableControls() {
  document.querySelectorAll('button').forEach((btn) => {
    btn.disabled = true;
  });
}
```

### Best Practices

#### 1. Wait for READY State

Only call control methods when session is READY:

```javascript
async function safelySpeak(text) {
  if (session.getSessionState() !== 'READY') {
    console.warn('Session not ready');
    return;
  }
  await session.sayText(text);
}
```

#### 2. Handle State Transitions

Update UI based on state changes:

```javascript
session.on('stateChange', (state) => {
  // Update button states
  document.getElementById('start-btn').disabled = state !== 'IDLE';
  document.getElementById('speak-btn').disabled = state !== 'READY';
  document.getElementById('end-btn').disabled = state !== 'READY';
});
```

#### 3. Monitor Connection Quality

```javascript
session.on('connectionChange', (state) => {
  if (state === 'FAILED') {
    // Try to reconnect or show error
    showReconnectOption();
  }
});
```

### Next Steps

- **[Error Handling](./client-sdk-error-handling)** - Handle errors gracefully
- **[Advanced Usage](./client-sdk-advanced)** - Custom configurations
