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
- Agent generates a text response
- Response is sent to the Avatar service
- Avatar service generates lip-synced video
- 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
- Go to Agents -> Select agent -> Settings
- Scroll to Avatar section
- Click Assign Avatar
- Select from available avatars
- 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:
| Status | Description |
|---|---|
pending | Job queued, waiting to start |
processing | Video is being generated |
completed | Video is ready |
failed | Generation 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
| Property | Type | Description |
|---|---|---|
id | string | Unique avatar identifier |
name | string | Display name |
language | string | Default language (e.g., en-US) |
description | string | Optional description |
avatarType | image | video | Type of avatar |
status | pending | processing | ready | failed | Current status |
sourceImageUrl | string | Source image URL (for image avatars) |
sourceVideoUrl | string | Source video URL (for video avatars) |
voiceSampleUrl | string | Voice 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:
| Tier | Price per Second |
|---|---|
| Starter | $0.02 |
| Pro | $0.015 |
| Business | $0.01 |
| Enterprise | Custom |
Next: Learn about MCP Integration for connecting external tools and services.