Skip to main content

Avatars

Avatars enable agents to respond with AI-generated video, creating more engaging and human-like interactions. When enabled, agents can generate lip-synced video responses using customizable digital avatars.

What are Avatars?

Avatars are AI-generated digital personas that can:

  • Speak agent responses: Convert text to lip-synced video
  • Maintain consistent appearance: Same avatar across all interactions
  • Support multiple languages: Generate videos in different languages
  • Customize backgrounds: Use branded or contextual backgrounds

How Avatars Work

Agent Response ──▶ Avatar Service ──▶ Video Generation ──▶ Video URL
│ │ │
▼ ▼ ▼
"Hello, I'm Select avatar AI lip-sync +
here to help" + voice settings voice synthesis
  1. Agent generates a text response
  2. Response is sent to the Avatar service
  3. Avatar service generates lip-synced video
  4. Video URL is returned to the client

Assigning Avatars to Agents

Via API

// Assign an avatar to an agent
await client.agents.assignAvatar('agent-123', {
avatarId: 'avatar-456'
});

// Get the current avatar for an agent
const avatar = await client.agents.getAvatar('agent-123');
console.log(avatar);
// {
// id: 'avatar-456',
// name: 'Professional Assistant',
// language: 'en-US',
// avatarType: 'video',
// status: 'ready'
// }

// Remove avatar from agent
await client.agents.removeAvatar('agent-123');

Via Dashboard

  1. Go to Agents -> Select agent -> Settings
  2. Scroll to Avatar section
  3. Click Assign Avatar
  4. Select from available avatars
  5. Save changes

Generating Video Responses

Basic Video Generation

// Generate a video response for an agent message
const result = await client.avatars.generateResponse({
agentId: 'agent-123',
text: 'Hello! I am here to help you with your questions.',
options: {
language: 'en-US',
waitForCompletion: false // Async generation
}
});

console.log(result);
// {
// jobId: 'job-789',
// status: 'processing'
// }

Wait for Completion

// Generate and wait for video to be ready
const result = await client.avatars.generateResponse({
agentId: 'agent-123',
text: 'Welcome to our platform!',
options: {
waitForCompletion: true // Block until video is ready
}
});

console.log(result);
// {
// jobId: 'job-789',
// status: 'completed',
// videoUrl: 'https://cdn.deeployd.com/videos/job-789.mp4'
// }

Check Video Status

// Poll for video status
const status = await client.avatars.getVideoStatus('job-789');

console.log(status);
// {
// jobId: 'job-789',
// status: 'completed',
// videoUrl: 'https://cdn.deeployd.com/videos/job-789.mp4',
// durationSeconds: 12.5
// }

Video Status Lifecycle

Videos go through these status states:

StatusDescription
pendingJob queued, waiting to start
processingVideo is being generated
completedVideo is ready
failedGeneration failed

Batch Video Generation

Generate multiple videos in parallel:

const results = await client.avatars.generateBatch([
{
agentId: 'agent-123',
text: 'Welcome message',
options: { language: 'en-US' }
},
{
agentId: 'agent-123',
text: 'Mensaje de bienvenida',
options: { language: 'es-ES' }
},
{
agentId: 'agent-123',
text: 'Message de bienvenue',
options: { language: 'fr-FR' }
}
]);

// Wait for all videos to complete
const completed = await client.avatars.waitForVideos(
results.map(r => r.jobId),
{ maxWaitMs: 300000 } // 5 minutes max
);

Avatar Types

Image-Based Avatars

Created from a single image. Best for:

  • Quick setup
  • Consistent branding
  • Lower cost per video
{
avatarType: 'image',
sourceImageUrl: 'https://example.com/avatar.jpg'
}

Video-Based Avatars

Created from video footage. Best for:

  • Most realistic results
  • Natural expressions
  • Premium experiences
{
avatarType: 'video',
sourceVideoUrl: 'https://example.com/training-video.mp4',
voiceSampleUrl: 'https://example.com/voice-sample.wav'
}

Avatar Properties

PropertyTypeDescription
idstringUnique avatar identifier
namestringDisplay name
languagestringDefault language (e.g., en-US)
descriptionstringOptional description
avatarTypeimage | videoType of avatar
statuspending | processing | ready | failedCurrent status
sourceImageUrlstringSource image URL (for image avatars)
sourceVideoUrlstringSource video URL (for video avatars)
voiceSampleUrlstringVoice sample URL (for video avatars)

API Endpoints

Agent Avatar Endpoints

GET    /api/agents/:id/avatar     # Get agent's avatar
PUT /api/agents/:id/avatar # Assign avatar to agent
DELETE /api/agents/:id/avatar # Remove avatar from agent

Video Generation Endpoints

POST   /api/avatars/generate      # Generate video response
GET /api/avatars/videos/:jobId # Get video status
POST /api/avatars/batch # Generate batch videos

Integration with Conversations

When an agent has an avatar assigned, you can request video responses:

// Send message with video response
const response = await client.conversations.sendMessage({
conversationId: 'conv-123',
content: 'Tell me about your services',
options: {
generateVideo: true // Request video response
}
});

console.log(response);
// {
// id: 'msg-456',
// content: 'We offer a variety of services...',
// videoUrl: 'https://cdn.deeployd.com/videos/response-456.mp4'
// }

Best Practices

1. Keep Messages Concise

Shorter messages generate faster and cost less:

// Good - concise
"Welcome! How can I help you today?"

// Avoid - too long
"Welcome to our platform! We're so excited to have you here.
Let me tell you about all the amazing features we offer..."

2. Use Appropriate Languages

Match the avatar's language to your audience:

// Set language per request
options: {
language: user.preferredLanguage || 'en-US'
}

3. Handle Async Generation

For real-time applications, use async generation with polling:

// Start generation
const { jobId } = await client.avatars.generateResponse({
agentId,
text: response,
options: { waitForCompletion: false }
});

// Show text immediately, then poll for video
displayText(response);

// Poll for video completion
const checkStatus = async () => {
const status = await client.avatars.getVideoStatus(jobId);
if (status.status === 'completed') {
displayVideo(status.videoUrl);
} else if (status.status === 'failed') {
// Fall back to text-only
} else {
setTimeout(checkStatus, 2000);
}
};
checkStatus();

4. Cache Common Responses

Pre-generate videos for common greetings:

// Pre-generate welcome videos in multiple languages
const welcomeMessages = [
{ text: 'Welcome!', language: 'en-US' },
{ text: 'Bienvenido!', language: 'es-ES' },
{ text: 'Bienvenue!', language: 'fr-FR' }
];

for (const msg of welcomeMessages) {
await client.avatars.generateResponse({
agentId,
text: msg.text,
options: {
language: msg.language,
waitForCompletion: true
}
});
}

Error Handling

try {
const result = await client.avatars.generateResponse({
agentId: 'agent-123',
text: 'Hello!'
});
} catch (error) {
if (error.code === 'AVATAR_NOT_ASSIGNED') {
// Agent doesn't have an avatar
} else if (error.code === 'AVATAR_NOT_READY') {
// Avatar is still processing
} else if (error.code === 'GENERATION_FAILED') {
// Video generation failed
}
}

Pricing

Avatar video generation is billed per second of generated video:

TierPrice per Second
Starter$0.02
Pro$0.015
Business$0.01
EnterpriseCustom

Next: Learn about MCP Integration for connecting external tools and services.