Brand Logo

How to Create Videos from Photos with a Photo Avatar API: The Complete Guide

Aug 21, 2025

Photo Avatar API Tutorial

Learn how to create AI avatars from photos using Miraflow's Photo Avatar API. Master full-background and face-cropped generation modes, Python integration, and best practices for AI video generation from single photos.


Introducing Photo Avatars: AI Video Generation Revolution

We're excited to announce a major leap forward in AI video generation: Photo Avatars! This groundbreaking feature allows you to create incredibly realistic AI avatars using just a single photograph. No more complex video setups or expensive studio sessions – now you can transform any photo into a dynamic, speaking AI avatar.

Whether you're building personalized marketing campaigns, creating educational content, or developing interactive applications, Photo Avatars open up entirely new possibilities for scalable video generation. The technology behind this feature represents months of research and development in computer vision and generative AI, and we can't wait to see what you'll build with it.

💡 New to Miraflow API?

If you haven't used our API before, check out our comprehensive guide:How to Create AI Avatar Videos Using Miraflow API for setup instructions and basic usage examples.

🎨 Want to Create Your Own Photo Avatar?

While we don't provide an API for creating photo avatars, you can easily create them through our website at miraflow.ai/create-avatar

  • • Just upload a photo to create a realistic avatar
  • • Prompt-based or setting-based image generation
  • • Prompt-based editing of uploaded photos

Photo Avatars vs. Video Avatars: What's the Difference?

📸 Photo Avatars

  • Created from a single high-quality photo
  • Faster to set up - no video recording needed
  • Two generation modes: full-background or face-cropped
  • Perfect for personalized content at scale

🎥 Video Avatars

  • Created from video recordings
  • More natural movement and expressions
  • Single generation mode
  • Ideal for professional presentations

The key advantage of Photo Avatars is accessibility – you can create professional AI avatars from existing photos without any special equipment or recording setup. This makes them perfect for scenarios where you need to generate many different avatars quickly, such as personalized marketing campaigns or educational content.

API Changes: New Fields and Parameters

To support Photo Avatars, we've made two important updates to our API that maintain backward compatibility while adding powerful new functionality:

🔄 API Updates Overview

1

GET /api/avatars

New isPhoto field indicates avatar type

2

POST /api/video/create

New im2vid_full parameter controls generation mode for photo avatars

Discovering Avatar Types with the isPhoto Field

The GET /api/avatars endpoint now includes an isPhoto boolean field that tells you whether each avatar was created from a photo or video. This is crucial for determining how to use the im2vid_full parameter.

Example: Listing All Available Avatars

curl -X GET https://miraflow.ai/api/avatars \
  -H "x-api-key: YOUR_API_KEY"

Response:

{
  "avatars": [
    {
      "id": "cmdms9d3s001no401kqwbr0q5",
      "name": "Margot",
      "createdAt": "2025-07-28T07:25:02.489Z",
      "voiceId": "Nhs7eitvQWFTQBsf0yiT",
      "isPhoto": true
    },
    {
      "id": "cme8if4yk007ko9013856uc33",
      "name": "Miraflow Muse",
      "createdAt": "2025-08-12T12:20:31.580Z",
      "voiceId": "Nhs7eitvQWFTQBsf0yiT",
      "isPhoto": true
    },
    {
      "id": "cm2yaz9j10008l0qg9npyjgs3",
      "name": "Aerin",
      "createdAt": "2024-11-01T05:37:46.194Z",
      "voiceId": "wBPTRK6eIJgAFmDsfw29",
      "isPhoto": false
    }
  ]
}

Mastering the im2vid_full Parameter

The new im2vid_full parameter gives you control over how photo avatars are generated. This parameter is ignored for video avatars, making it safe to include in all your requests.

Generation Modes Explained

Full-Background Generation

  • • Complete video with background
  • • Takes ~5–10 minutes
  • • Higher quality output
  • • Best for professional content

Face-Cropped Generation

  • • Focused on avatar's face only
  • • Takes ~1–2 minutes
  • • Faster processing
  • • Perfect for quick previews

Example 1: Creating a Quick Preview Video

For rapid prototyping or when you need quick results, use face-cropped generation:

curl -X POST https://miraflow.ai/api/video/create \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "avatarId": "cmdms9d3s001no401kqwbr0q5",
    "name": "Quick Product Demo",
    "text": "Hi there! Welcome to our new product demonstration. Let me show you the amazing features we have built for you.",
    "im2vid_full": false
  }'

Response:

{
  "result": "success",
  "jobId": "cm42ab3ou0008aggajj0jy5e2"
}

Example 2: Creating a High-Quality Marketing Video

For production-ready content where quality is paramount, use full-background generation:

curl -X POST https://miraflow.ai/api/video/create \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "avatarId": "cmdms9d3s001no401kqwbr0q5",
    "name": "Executive Welcome Message",
    "text": "Hi there! Welcome to our company! I am excited to personally introduce you to our revolutionary platform that will transform how you work and collaborate.",
    "im2vid_full": true
  }'

Response:

{
  "result": "success",
  "jobId": "cm42ab3ou0008aggajj0jy5f3"
}

Complete Python Integration Example

Here's a production-ready Python example showing how to implement a smart avatar selection and video creation system using the requests library:

import requests
import time
import json
from typing import Dict, List, Optional, Any


class MiraflowPhotoAvatarAPI:
    """Production-ready Python client for Miraflow Photo Avatar API."""
    
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://miraflow.ai/api"
        self.session = requests.Session()
        self.session.headers.update({
            "x-api-key": self.api_key,
            "Content-Type": "application/json"
        })
    
    def get_avatars(self) -> Dict[str, Any]:
        """Retrieve all available avatars."""
        response = self.session.get(f"{self.base_url}/avatars")
        response.raise_for_status()
        return response.json()
    
    def create_video(
        self, 
        avatar_id: str, 
        name: str, 
        text: str, 
        is_photo: bool,
        use_full_background: bool = False
    ) -> Dict[str, Any]:
        """
        Create a video with the specified avatar.
        
        Args:
            avatar_id: The avatar ID to use
            name: Name for the video
            text: Script text for the avatar to speak
            is_photo: Whether this is a photo avatar
            use_full_background: If True, use full-background generation for photo avatars
                                If False, use face-cropped generation for photo avatars
        """
        payload = {
            "avatarId": avatar_id,
            "name": name,
            "text": text
        }
        
        # Only add im2vid_full parameter for photo avatars
        if is_photo:
            payload["im2vid_full"] = use_full_background
        
        response = self.session.post(f"{self.base_url}/video/create", json=payload)
        response.raise_for_status()
        return response.json()
    
    def check_job_status(self, job_id: str) -> Dict[str, Any]:
        """Check the status of a video creation job."""
        response = self.session.get(f"{self.base_url}/video/{job_id}/status")
        response.raise_for_status()
        return response.json()
    
    def wait_for_completion(
        self, 
        job_id: str, 
        polling_interval: int = 10,
        max_wait_time: int = 600
    ) -> Dict[str, Any]:
        """
        Wait for a video creation job to complete.
        
        Args:
            job_id: The job ID to monitor
            polling_interval: Seconds between status checks
            max_wait_time: Maximum time to wait in seconds
            
        Returns:
            Final job status
        """
        start_time = time.time()
        
        while time.time() - start_time < max_wait_time:
            status = self.check_job_status(job_id)
            
            print(f"Status: {status.get('status', 'unknown')}")
            
            if status.get("status") == "inference_complete":
                print("✅ Video creation completed successfully!")
                return status
            elif status.get("status") == "inference_failed":
                print("❌ Video creation failed!")
                return status
            
            time.sleep(polling_interval)
        
        raise TimeoutError(f"Job {job_id} did not complete within {max_wait_time} seconds")


def create_personalized_marketing_campaign():
    """Example: Create personalized videos for a marketing campaign."""
    
    # Initialize API client
    api = MiraflowPhotoAvatarAPI("YOUR_API_KEY")
    
    try:
        # Get all available avatars
        avatars_response = api.get_avatars()
        avatars = avatars_response.get("avatars", [])
        
        # Filter photo avatars
        photo_avatars = [avatar for avatar in avatars if avatar.get("isPhoto")]
        
        if not photo_avatars:
            print("No photo avatars available")
            return
        
        # Select the first photo avatar
        selected_avatar = photo_avatars[0]
        print(f"Using photo avatar: {selected_avatar['name']}")
        
        # Create a quick preview first (face-cropped generation)
        print("Creating quick preview...")
        preview_result = api.create_video(
            avatar_id=selected_avatar["id"],
            name="Marketing Preview - Face Cropped",
            text="Hi there! This is a quick preview of our new product features.",
            is_photo=True,
            use_full_background=False  # Fast face-cropped generation
        )
        
        if preview_result.get("result") == "success":
            preview_job_id = preview_result["jobId"]
            print(f"Preview job started: {preview_job_id}")
            
            # Wait for preview to complete
            api.wait_for_completion(preview_job_id, polling_interval=5, max_wait_time=180)
        
        # Create high-quality marketing video (full-background generation)
        print("\nCreating high-quality marketing video...")
        marketing_result = api.create_video(
            avatar_id=selected_avatar["id"],
            name="Marketing Campaign - Full Background",
            text="Welcome to our revolutionary platform! Let me personally show you how our solution can transform your business and drive incredible results.",
            is_photo=True,
            use_full_background=True  # High-quality full-background generation
        )
        
        if marketing_result.get("result") == "success":
            marketing_job_id = marketing_result["jobId"]
            print(f"Marketing video job started: {marketing_job_id}")
            
            # Wait for marketing video to complete
            final_status = api.wait_for_completion(marketing_job_id, polling_interval=15)
            
            if final_status.get("status") == "inference_complete":
                print("🎉 Marketing video is ready for download!")
                print(f"Video URL available in job status response")
            
    except requests.exceptions.RequestException as e:
        print(f"API request failed: {e}")
    except Exception as e:
        print(f"Error: {e}")


def handle_video_creation_errors():
    """Example: Robust error handling for video creation."""
    
    api = MiraflowPhotoAvatarAPI("YOUR_API_KEY")
    
    try:
        result = api.create_video(
            avatar_id="cmdms9d3s001no401kqwbr0q5",
            name="Error Handling Example",
            text="This demonstrates proper error handling.",
            is_photo=True,
            use_full_background=False
        )
        
        if result.get("result") == "failure":
            error_msg = result.get("error", "Unknown error")
            
            if "Avatar not found" in error_msg:
                print("Error: Avatar does not exist or is not accessible")
            elif "not enough credits" in error_msg:
                print("Error: Please add more credits to your account")
            else:
                print(f"Error: Video creation failed - {error_msg}")
        else:
            print(f"Success: Job created with ID {result['jobId']}")
            
    except requests.exceptions.RequestException as e:
        print(f"Network error: {e}")
    except Exception as e:
        print(f"Unexpected error: {e}")


if __name__ == "__main__":
    # Run the marketing campaign example
    create_personalized_marketing_campaign()
    
    # Uncomment to test error handling
    # handle_video_creation_errors()

Best Practices and Tips

🎯 Choosing the Right Generation Mode

  • Use face-cropped generation for: Rapid prototyping, A/B testing, preview generation, or when you need many videos quickly
  • Use full-background generation for: Final production videos, marketing campaigns, professional presentations, or public-facing content

⚡ Performance Optimization

1

Always check the isPhoto field before setting the im2vid_full parameter

2

Cache avatar information to reduce API calls when creating multiple videos

3

Implement retry logic for failed video creation attempts

🔒 Error Handling Best Practices

1

Always use response.raise_for_status() to catch HTTP errors early

2

Check the result field in successful API responses for business logic errors

3

Implement exponential backoff for network timeouts and rate limiting

4

Log detailed error information for debugging while showing user-friendly messages

What's Next?

Photo Avatars represent just the beginning of our mission to make AI video generation more accessible and powerful. With the new isPhoto field and im2vid_full parameter, you now have the flexibility to create everything from quick prototypes to production-ready marketing videos.

🚀 Ready to Get Started?

Start experimenting with Photo Avatars today! We already have a comprehensive collection of photo-based default avatars available, along with our existing video-based default avatars. Check the isPhoto field from the /api/avatars endpoint to explore our diverse avatar collection.

We're continuously improving our API based on developer feedback. If you have questions, suggestions, or want to share what you're building with Photo Avatars, don't hesitate to reach out. Happy coding! 🎉

Further Reading & Resources

📚 Related Blog Posts

How to Create AI Avatar Videos Using Miraflow API

Master the basics of AI avatar video creation with our comprehensive API tutorial

How to Create Stellar Avatar Videos

Learn advanced techniques for creating high-quality AI avatar content

📖 Additional Resources

1

Complete API Documentation - Explore all available endpoints and parameters

2

Case Studies - See how others are using Miraflow in production

3

Learning Center - Deep dive into AI avatar technology and best practices