Avatars
Learn how to retrieve and use AI avatars for conversational verification experiences.
FaceSign uses AI-powered avatars to create natural, conversational verification experiences. These virtual assistants guide users through the verification process with human-like interactions, making the experience more engaging and less intimidating than traditional forms.
How avatars work
FaceSign avatars are AI-powered virtual assistants that:
- Guide users through each step of the verification process
- Adapt their conversation based on the flow nodes you've configured
- Speak multiple languages and adjust their communication style accordingly
- Provide real-time feedback and help users complete verification successfully
- Detect emotions and engagement to provide a more personalized experience
Avatar object
| Property | Type | Description |
|---|---|---|
id | string | Unique identifier for the avatar. |
name | string | Human-readable name of the avatar. |
gender | string | Avatar gender: male, female, or unknown. |
imageUrl | string | URL to the avatar's profile image for display in your interface. |
Get available avatars
GET /avatars
Returns a list of all available AI avatars that can be used in verification sessions. Choose an avatar that best fits your brand and target audience.
curl https://api.facesign.ai/avatars \
-H "Authorization: Bearer sk_test_..."import Client from '@facesignai/api'
import { FSNodeType } from '@facesignai/api'
const client = new Client({
auth: 'sk_test_...'
})
const { avatars } = await client.avatars.retrieve()
// Use in session creation
const { session, clientSecret } = await client.session.create({
clientReferenceId: 'user_123',
avatarId: avatars[0].id,
flow:[
{ id: 'start', type: FSNodeType.START, outcome: 'end' },
{ id: 'end', type: FSNodeType.END }
]
})import facesignai
client = facesignai.Client(
auth='sk_test_...'
)
response = client.avatars.retrieve()
avatars = response['avatars']
# Use in session creation
session_response = client.session.create(
client_reference_id='user_123',
avatar_id=avatars[0]['id'],
flow=[
{'id': 'start', 'type': 'start', 'outcome': 'end'},
{'id': 'end', 'type': 'end'}
]
)[
{
"id": "Ann_Therapist_public",
"name": "Ann Therapist",
"gender": "unknown",
"imageUrl": "https://files2.heygen.ai/avatar/v3/75e0a87b7fd94f0981ff398b593dd47f_45570/preview_talk_4.webp",
"createdAt": 1732855717000
},
{
"id": "Shawn_Therapist_public",
"name": "Shawn Therapist",
"gender": "unknown",
"imageUrl": "https://files2.heygen.ai/avatar/v3/db2fb7fd0d044b908395a011166ab22d_45680/preview_target.webp",
"createdAt": 1732855256000
},
{
"id": "Dexter_Lawyer_Sitting_public",
"name": "Dexter Lawyer",
"gender": "unknown",
"imageUrl": "https://files2.heygen.ai/avatar/v3/e20ac0c902184ff793e75ae4e139b7dc_45600/preview_target.webp",
"createdAt": 1732855201000
}
]Choosing the right avatar
Consider your audience
Different avatars work better for different use cases and audiences:
const AVATAR_RECOMMENDATIONS = {
financial_services: { avatarId: 'avatar_sarah_professional', description: 'Professional, trustworthy appearance for banking and financial apps' },
healthcare: { avatarId: 'avatar_james_caring', description: 'Warm, empathetic avatar for medical verification' },
gaming: { avatarId: 'avatar_alex_casual', description: 'Casual, friendly avatar for gaming platforms' },
enterprise: { avatarId: 'avatar_david_corporate', description: 'Business-appropriate avatar for B2B applications' },
international: { avatarId: 'avatar_maria_bilingual', description: 'Multicultural avatar for global applications' }
};
function selectAvatarForUseCase(useCase: string) {
return AVATAR_RECOMMENDATIONS[useCase] || AVATAR_RECOMMENDATIONS.enterprise;
}Dynamic avatar selection
You can dynamically select avatars based on user preferences or demographics:
async function selectPersonalizedAvatar(userId: string) {
const { avatars } = await client.avatars.list();
const user = await db.users.findUnique({ where: { id: userId } });
let preferredAvatars = avatars;
if (user.preferredAvatarGender) {
preferredAvatars = avatars.filter(avatar => avatar.gender === user.preferredAvatarGender || avatar.gender === 'unknown');
}
return preferredAvatars[0] || avatars[0];
}
async function createPersonalizedSession(userId: string) {
const selectedAvatar = await selectPersonalizedAvatar(userId)
const { session, clientSecret } = await client.session.create({
clientReferenceId: userId,
avatarId: selectedAvatar.id,
flow: [ { id: 'start', type: FSNodeType.START, outcome: 'end' }, { id: 'end', type: FSNodeType.END } ],
})
return { session, clientSecret }
}Avatar selection UI
Let users choose their avatar
Provide an avatar selection interface before starting verification:
import React, { useState, useEffect } from 'react';
interface Avatar {
id: string;
name: string;
gender: string;
imageUrl: string;
}
function AvatarSelector({ onAvatarSelect }: { onAvatarSelect: (avatar: Avatar) => void }) {
const [avatars, setAvatars] = useState<Avatar[]>([]);
const [selectedAvatar, setSelectedAvatar] = useState<Avatar | null>(null);
useEffect(() => {
// Fetch available avatars
fetch('/api/avatars')
.then(res => res.json())
.then(data => {
setAvatars(data.avatars);
setSelectedAvatar(data.avatars[0]); // Default to first avatar
});
}, []);
const handleAvatarSelect = (avatar: Avatar) => {
setSelectedAvatar(avatar);
onAvatarSelect(avatar);
};
return (
<div className="avatar-selector">
<h3>Choose your verification assistant:</h3>
<div className="avatar-grid">
{avatars.map(avatar => (
<div
key={avatar.id}
className={`avatar-card ${selectedAvatar?.id === avatar.id ? 'selected' : ''}`}
onClick={() => handleAvatarSelect(avatar)}
>
<img
src={avatar.imageUrl}
alt={avatar.name}
className="avatar-image"
/>
<div className="avatar-info">
<h4>{avatar.name}</h4>
<div className="avatar-description">
{getAvatarDescription(avatar)}
</div>
</div>
</div>
))}
</div>
</div>
);
}
function getAvatarDescription(avatar: Avatar): string {
const descriptions = {
'avatar_sarah_professional': 'Professional and trustworthy',
'avatar_james_friendly': 'Warm and approachable',
'avatar_maria_bilingual': 'Great for international users',
'avatar_alex_neutral': 'Friendly and inclusive'
};
return descriptions[avatar.id] || 'Helpful verification assistant';
}
function VerificationSetup() {
const [selectedAvatar, setSelectedAvatar] = useState<Avatar | null>(null);
const startVerification = async () => {
if (!selectedAvatar) return;
const response = await fetch('/api/create-session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
avatarId: selectedAvatar.id
})
});
const { clientSecret } = await response.json();
// Start verification with selected avatar
const facesign = new FaceSign({ clientSecret });
await facesign.mount('#verification-container');
};
return (
<div>
<AvatarSelector onAvatarSelect={setSelectedAvatar} />
<button
onClick={startVerification}
disabled={!selectedAvatar}
className="start-verification-btn"
>
Start Verification with {selectedAvatar?.name}
</button>
<div id="verification-container"></div>
</div>
);
}Preview avatar interactions
Show users what to expect from their chosen avatar:
function AvatarPreview({ avatar }: { avatar: Avatar }) {
return (
<div className="avatar-preview">
<div className="avatar-preview-header">
<img src={avatar.imageUrl} alt={avatar.name} />
<h4>Meet {avatar.name}</h4>
</div>
<div className="preview-conversation">
<div className="avatar-message">
<p>Hi! I'm {avatar.name}. I'll guide you through the verification process step by step.</p>
</div>
<div className="avatar-message">
<p>Don't worry - I'll make sure everything goes smoothly and answer any questions you have.</p>
</div>
<div className="user-message">
<p>Sounds good! Let's get started.</p>
</div>
<div className="avatar-message">
<p>Perfect! Let's begin with verifying your identity...</p>
</div>
</div>
<div className="preview-features">
<h5>What {avatar.name} can help with:</h5>
<ul>
<li>Guide you through document scanning</li>
<li>Help with facial recognition</li>
<li>Answer questions about the process</li>
<li>Provide encouragement and support</li>
</ul>
</div>
</div>
);
}Best practices
FaceSign provides an endpoint to fetch the list of currently supported avatars. It is recommended to retrieve this list from the API and store it locally -- for example, in your database or an in-memory cache. To keep your local list up to date, listen for the settings.avatars webhook event, which notifies your application of any changes to the supported avatars. When this event is received, fetch the updated avatars list from the API and update your local storage.
This approach ensures your application always has the most current set of available avatars, minimizing API calls and keeping your user experience consistent even as available avatars change.