Skip to main content

🎭 Avatar Service

An avatar pairs a face with a voice — think of it as casting your character.

An avatar is a reusable composition: it references one visual appearance and one voice from the Catalog, combines them into a named character, and can be assigned to one or more agents. Change an avatar's voice speed? Every agent using it gets the update automatically.

Base route: POST /service/avatar/action/{actionName}

How Avatars Relate to Catalog Items

📦 Visual catalog item ──(visual.id)──┐
├──► 🎭 Avatar ────(avatarIds)──► 🤖 Agent A
📦 Voice catalog item ──(voice.id)───┘ └──(avatarIds)──► 🤖 Agent B

An avatar's voice.id and visual.id reference catalog item IDs from the Catalog Service. Browse the catalog first to find the IDs you want, then create your avatar.

Data Model

FieldTypeDescription
idstring (MongoDB ObjectId)Unique avatar identifier
voiceobjectVoice configuration
voice.idstringID of the voice catalog item
voice.speednumberSpeech speed multiplier (0.5–2.0, default 1.0)
visualobjectVisual configuration
visual.idstringID of the visual catalog item
visual.motionControlobjectMotion animation settings (optional)
visual.motionControl.speakingnumberAnimation intensity while speaking
visual.motionControl.nonSpeakingnumberAnimation intensity while idle
openingPhrasestringWhat the avatar says when a session starts (max 1000 chars)
previewImageUrlstringPreview image URL (auto-generated)
loadingVideoUrlstringLoading animation URL (auto-generated)
partnerIdnumberYour Kaltura partner ID
createdAtDateCreation timestamp
updatedAtDateLast modification timestamp

Actions

get — Retrieve an Avatar

POST /service/avatar/action/get

Request body:

{
"id": "64f1a2b3c4d5e6f7a8b9c0d1"
}
FieldTypeRequiredDescription
idstring✅ YesMongoDB ObjectId of the avatar

Response:

{
"id": "64f1a2b3c4d5e6f7a8b9c0d1",
"voice": {
"id": "voice_catalog_item_id",
"speed": 1.0
},
"visual": {
"id": "visual_catalog_item_id",
"motionControl": {
"speaking": 1,
"nonSpeaking": 0.6
}
},
"openingPhrase": "Hi! How can I help you today?",
"previewImageUrl": "https://cdn.kaltura.com/avatars/preview-abc.jpg",
"loadingVideoUrl": "https://cdn.kaltura.com/avatars/loading-abc.mp4",
"partnerId": 12345,
"createdAt": "2024-01-10T09:00:00.000Z",
"updatedAt": "2024-01-12T11:30:00.000Z"
}

Examples:

cURL
curl -X POST "https://YOUR_API_HOST/service/avatar/action/get" \
-H "Authorization: KS YOUR_KS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "id": "64f1a2b3c4d5e6f7a8b9c0d1" }'
JavaScript
const avatar = await fetch('https://YOUR_API_HOST/service/avatar/action/get', {
method: 'POST',
headers: {
Authorization: `KS ${ksToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ id: '64f1a2b3c4d5e6f7a8b9c0d1' }),
}).then((res) => res.json());

list — List Avatars

POST /service/avatar/action/list

Request body:

{
"filter": {
"idsIn": ["64f1a2b3c4d5e6f7a8b9c0d1", "64f1a2b3c4d5e6f7a8b9c0d2"]
},
"pager": {
"offset": 0,
"limit": 30
}
}
FieldTypeRequiredDescription
filter.idsInstring[]NoFilter to specific avatar IDs
pager.offsetnumberNoPagination offset (default: 0)
pager.limitnumberNoMax results per page (default: 30)

Response:

{
"objects": [ ... ],
"totalCount": 8
}

Examples:

cURL — list all avatars
curl -X POST "https://YOUR_API_HOST/service/avatar/action/list" \
-H "Authorization: KS YOUR_KS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "pager": { "offset": 0, "limit": 30 } }'
JavaScript
const { objects, totalCount } = await fetch('https://YOUR_API_HOST/service/avatar/action/list', {
method: 'POST',
headers: {
Authorization: `KS ${ksToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
pager: { offset: 0, limit: 30 },
}),
}).then((res) => res.json());

console.log(`You have ${totalCount} avatars configured`);

create — Create an Avatar

POST /service/avatar/action/create

Request body:

{
"voice": {
"id": "voice_catalog_item_id",
"speed": 1.0
},
"visual": {
"id": "visual_catalog_item_id",
"motionControl": {
"speaking": 1,
"nonSpeaking": 0.6
}
},
"openingPhrase": "Hi there! How can I help you today?"
}
FieldTypeRequiredDescription
voiceobject✅ YesVoice configuration
voice.idstring✅ YesVoice catalog item ID
voice.speednumberNoSpeed multiplier 0.5–2.0 (default: 1.0)
visualobject✅ YesVisual configuration
visual.idstring✅ YesVisual catalog item ID
visual.motionControl.speakingnumberNoMotion intensity while speaking
visual.motionControl.nonSpeakingnumberNoMotion intensity while idle
openingPhrasestringNoGreeting said at session start (max 1000 chars)
Opening phrase tips

The openingPhrase is what the avatar says the moment a user starts a session — make it friendly and contextual!

  • ✅ "Hi! I'm Maya, your customer support assistant. What can I help you with today?"
  • ✅ "Welcome back! I'm here and ready to help."
  • ❌ Don't make it too long — users want to get to their question quickly.

Response: Returns the created Avatar object with the generated id.

Examples:

cURL
curl -X POST "https://YOUR_API_HOST/service/avatar/action/create" \
-H "Authorization: KS YOUR_KS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"voice": { "id": "voice_catalog_item_id", "speed": 1.0 },
"visual": { "id": "visual_catalog_item_id" },
"openingPhrase": "Hi! How can I help you today?"
}'
JavaScript
const newAvatar = await fetch('https://YOUR_API_HOST/service/avatar/action/create', {
method: 'POST',
headers: {
Authorization: `KS ${ksToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
voice: { id: 'voice_catalog_item_id', speed: 1.0 },
visual: { id: 'visual_catalog_item_id' },
openingPhrase: 'Hi! How can I help you today?',
}),
}).then((res) => res.json());

console.log(`Created avatar: ${newAvatar.id}`);

update — Update an Avatar

POST /service/avatar/action/update

Update voice, visual, or other settings. Only include fields you want to change.

Request body:

{
"id": "64f1a2b3c4d5e6f7a8b9c0d1",
"voice": {
"id": "voice_catalog_item_id",
"speed": 1.2
},
"openingPhrase": "Hello! What can I do for you?"
}
FieldTypeRequiredDescription
idstring✅ YesThe avatar to update
voiceobjectNoNew voice configuration (replaces existing)
visualobjectNoNew visual configuration (replaces existing)
openingPhrasestringNoNew opening phrase (max 1000 chars)

Response: Returns the updated Avatar object.

Examples:

cURL — speed up the voice
curl -X POST "https://YOUR_API_HOST/service/avatar/action/update" \
-H "Authorization: KS YOUR_KS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "64f1a2b3c4d5e6f7a8b9c0d1",
"voice": { "id": "voice_catalog_item_id", "speed": 1.2 }
}'
JavaScript
const updatedAvatar = await fetch('https://YOUR_API_HOST/service/avatar/action/update', {
method: 'POST',
headers: {
Authorization: `KS ${ksToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
id: '64f1a2b3c4d5e6f7a8b9c0d1',
voice: { id: 'voice_catalog_item_id', speed: 1.2 },
}),
}).then((res) => res.json());

delete — Delete an Avatar

POST /service/avatar/action/delete

Permanently deletes an avatar. This cannot be undone.

Request body:

{
"id": "64f1a2b3c4d5e6f7a8b9c0d1"
}
FieldTypeRequiredDescription
idstring✅ YesThe avatar to delete

Response:

{
"id": "64f1a2b3c4d5e6f7a8b9c0d1"
}
Check agents before deleting

If you delete an avatar that's referenced by one or more agents (via avatarIds), those agents will still reference the deleted avatar ID. The agent won't automatically update — remove the ID from avatarIds on any affected agents first.

Examples:

cURL
curl -X POST "https://YOUR_API_HOST/service/avatar/action/delete" \
-H "Authorization: KS YOUR_KS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "id": "64f1a2b3c4d5e6f7a8b9c0d1" }'
JavaScript
await fetch('https://YOUR_API_HOST/service/avatar/action/delete', {
method: 'POST',
headers: {
Authorization: `KS ${ksToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ id: '64f1a2b3c4d5e6f7a8b9c0d1' }),
});

Usage Notes

Voice Speed

The voice.speed multiplier controls how fast the avatar speaks:

ValueEffect
0.7Slow - good for accessibility or complex explanations
1.0Normal speed (default)
1.2Slightly faster maximum speed — often feels more natural and engaging

Motion Control

Motion control tuning affects how "lively" the avatar looks:

The motionControl object has two numeric parameters, both ranging from 0.1 (Subtle) to 1.0 (Expressive). The default value is 1.0.

  • speaking — animation intensity while the avatar is speaking (mouth and body movement)
  • nonSpeaking — animation intensity while idle (subtle breathing-like motion)
ValueEffect
0.1Subtle — minimal movement, calm and professional
0.5Moderate — balanced, natural feel
1.0Expressive — pronounced movement (default)

Override only if you have specific requirements (e.g., a very calm avatar for professional contexts, or a more expressive one for entertainment).

Next Steps

  • 📦 Catalog Service — Browse and upload the voices and visuals referenced by voice.id and visual.id
  • 🤖 Agent Service — Assign this avatar to an agent via avatarIds
  • 🛠️ Workflows — See the complete end-to-end setup