Skip to main content

๐Ÿ› ๏ธ Workflows

Let's build something! These end-to-end walkthroughs show you how the three management services work together in real scenarios.

Before You Startโ€‹

Make sure you have:

  • โœ… A valid KS token (see Authentication)
  • โœ… Your API host URL
  • โœ… At least one catalog item available (or use the presets โ€” list them with catalog-item/action/list)

๐ŸŽฌ Scenario 1: From Zero to Talking Avatarโ€‹

The complete journey โ€” from browsing the catalog to a fully configured conversational agent ready for real-time sessions.

๐Ÿ“ฆ Browse catalog  โ”€โ”€โ–บ  ๐ŸŽญ Create avatar  โ”€โ”€โ–บ  ๐Ÿค– Create agent  โ”€โ”€โ–บ  ๐Ÿš€ Get embed script  โ”€โ”€โ–บ  ๐Ÿ‘ค Live!
(Step 1) (Step 2) (Step 3) (Step 4)

Step 1 โ€” Find your visual and voice ๐Ÿ“ฆโ€‹

Start by listing the catalog to find what's available. Filter by type to get visuals and voices separately:

Step 1: Browse the catalog
const API_HOST = 'https://YOUR_API_HOST';
const ksToken = 'YOUR_KS_TOKEN';

// Helper function for all management API calls
async function kalturaAction(service, action, body = {}) {
const response = await fetch(`${API_HOST}/service/${service}/action/${action}`, {
method: 'POST',
headers: {
Authorization: `KS ${ksToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
if (!response.ok) {
throw new Error(`API error: ${response.status} ${response.statusText}`);
}
return response.json();
}

// List visual catalog items
const visuals = await kalturaAction('catalog-item', 'list', {
filter: { typeEqual: 'Visual' },
pager: { offset: 0, limit: 30 },
});
console.log('Available visuals:');
visuals.objects.forEach((v) => console.log(` ${v.itemId}: ${v.attributes.visual?.name}`));

// List English voice catalog items
const voices = await kalturaAction('catalog-item', 'list', {
filter: { typeEqual: 'Voice', languageEqual: 'en-US' },
pager: { offset: 0, limit: 30 },
});
console.log('\nAvailable voices:');
voices.objects.forEach((v) => console.log(` ${v.itemId}: ${v.attributes.voice?.name}`));

// ๐Ÿ“Œ Pick the IDs you want for the next step
const selectedVisualId = visuals.objects[0].itemId;
const selectedVoiceId = voices.objects[0].itemId;

Step 2 โ€” Create your avatar ๐ŸŽญโ€‹

Combine the visual and voice into a reusable avatar character:

Step 2: Create the avatar
const avatar = await kalturaAction('avatar', 'create', {
visual: {
id: selectedVisualId,
// Optional: tune motion intensity (default values work great)
motionControl: { speaking: 5, nonSpeaking: 2 },
},
voice: {
id: selectedVoiceId,
speed: 1.0, // Normal speed โ€” try 1.1 for a slightly more energetic feel
},
openingPhrase: "Hi there! I'm your virtual assistant. How can I help you today?",
});

console.log(`โœ… Avatar created: ${avatar.id}`);
// Save this ID โ€” you'll need it in Step 3
const avatarId = avatar.id;

Step 3 โ€” Create your agent ๐Ÿค–โ€‹

Attach the avatar to an intelligence engine and tune the conversation behavior:

Step 3: Create the agent
const agent = await kalturaAction('agent', 'create', {
displayName: 'Customer Support Assistant',
intellect: {
intellectType: 'genie', // Use Kaltura's Genie AI engine
genieId: 'YOUR_GENIE_ID', // Genie instance ID
configId: YOUR_CONFIG_ID, // Intellect partner config ID (number)
},
avatarIds: [avatarId], // The avatar we just created
maxConversationLength: 600, // 10 minutes max per session
adminTags: ['production'],
widgetConfig: {
initialPage: { title: 'How can I help?' },
layouts: { avatar: true, chat: true },
},
});

console.log(`๐ŸŽ‰ Agent created: ${agent.agentId}`);
console.log('Your agent is ready for real-time sessions!');
Customize the AI personality

The configId references an intellect configuration that controls your assistant's name, goals, restricted topics, glossary, and capabilities. Use the ๐Ÿง  Intellect Service to retrieve and tune it โ€” for example, give it a name, restrict off-topic conversations, or add domain-specific vocabulary.

Step 4 โ€” Embed your agent ๐Ÿš€โ€‹

Your agent is configured! Get the embed script and drop it into any webpage:

Step 4: Get the embed script
const { html } = await kalturaAction('agent', 'getEmbedScript', {
agentId: agent.agentId,
});

// Paste `html` into your webpage โ€” it contains everything needed to launch the agent
console.log('Embed script ready:', html);

๐Ÿ”„ Scenario 2: Give Your Avatar a Makeoverโ€‹

Your current avatar needs a fresh look โ€” or you want to try a different voice. Here's how to update an existing avatar without rebuilding from scratch.

Option A: Update the avatar's voice in-place
// Just update the voice โ€” all agents using this avatar get the new voice automatically
const updatedAvatar = await kalturaAction('avatar', 'update', {
id: 'YOUR_AVATAR_ID',
voice: {
id: 'NEW_VOICE_CATALOG_ID',
speed: 1.1,
},
});

console.log(`โœ… Avatar updated with new voice`);
// No need to touch the agent โ€” it references the same avatar ID
Option B: Swap the visual, keep everything else
// Upload a new visual to the catalog first
const formData = new FormData();
formData.append('file', newImageFile);
formData.append(
'attributes',
JSON.stringify({
visual: { name: 'Updated Look', background: 'Image', genderPresentation: 'Feminine' },
}),
);

const newVisualItem = await fetch(`${API_HOST}/service/catalog-item/action/create`, {
method: 'POST',
headers: { Authorization: `KS ${ksToken}` },
body: formData,
}).then((res) => res.json());

// Update the avatar to use the new visual
await kalturaAction('avatar', 'update', {
id: 'YOUR_AVATAR_ID',
visual: { id: newVisualItem.itemId },
});

console.log(`โœ… Avatar now uses the new visual: ${newVisualItem.itemId}`);

๐Ÿงช Scenario 3: Clone & Experimentโ€‹

Want to A/B test two variations of an avatar โ€” different voice speed, different opening phrase โ€” without disrupting production? Clone it.

Clone, customize, and test
// 1. Clone the production avatar
const experimentAvatar = await kalturaAction('avatar', 'clone', {
id: 'PRODUCTION_AVATAR_ID',
});

console.log(`Cloned avatar: ${experimentAvatar.id}`);

// 2. Customize the clone โ€” try a faster voice
await kalturaAction('avatar', 'update', {
id: experimentAvatar.id,
voice: {
id: 'VOICE_CATALOG_ID',
speed: 1.2, // 20% faster than production
},
openingPhrase: 'Hey! Great to see you. What can I do for you?', // More casual
});

// 3. Add the experiment avatar to the agent alongside the original
const currentAgent = await kalturaAction('agent', 'get', {
agentId: 'YOUR_AGENT_ID',
});

await kalturaAction('agent', 'update', {
agentId: 'YOUR_AGENT_ID',
avatarIds: [
...currentAgent.avatarIds, // Keep existing avatars
experimentAvatar.id, // Add the experiment
],
});

console.log(`โœ… Agent now has ${currentAgent.avatarIds.length + 1} avatars`);
console.log('Your system can now route some sessions to the experiment avatar!');
Cleaning up experiments

When you're done experimenting, remove the experiment avatar from the agent's avatarIds and delete the cloned avatar:

// Remove from agent
await kalturaAction('agent', 'update', {
agentId: 'YOUR_AGENT_ID',
avatarIds: currentAgent.avatarIds.filter((id) => id !== experimentAvatar.id),
});

// Delete the clone
await kalturaAction('avatar', 'delete', { id: experimentAvatar.id });

What's Next?โ€‹

Your conversational agent is built and configured. Here's where to go from here:

  • ๐Ÿค– Agent Service โ€” Full getEmbedScript reference and other agent actions
  • ๐ŸŽญ Avatar Service โ€” Fine-tune voice speed, motion, and opening phrases
  • ๐Ÿง  Intellect Service โ€” Customize prompts, glossary, and capabilities
  • ๐Ÿ“ฆ Catalog Service โ€” Upload your own custom visuals and voices
  • ๐Ÿ” Authentication โ€” Refresh your understanding of the KS token lifecycle