Generating Images with API

You can add image generation capabilities to your applications using Mirako API. This guide will walk you through the process of generating images featuring your custom avatars using both asynchronous and synchronous methods.

Generation Modes

Mirako offers two generation modes:

  • Async Mode (/v1/image/async_generate): Returns a task ID that you poll for completion. Best for batch processing and webhook workflows.
  • Sync Mode (/v1/image/generate): Returns the image immediately. Best for real-time applications.

Async Image Generation

python
import requests
import time

# API configuration
API_KEY = "your_api_key_here"
BASE_URL = "https://mirako.co"

headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json"
}

def generate_avatar_image(prompt, aspect_ratio="16:9", seed=None):
    """Generate image with avatar using text prompt"""

    payload = {
        "prompt": prompt,
        "aspect_ratio": aspect_ratio
    }

    if seed:
        payload["seed"] = seed

    response = requests.post(
        f"{BASE_URL}/v1/image/async_generate",
        headers=headers,
        json=payload
    )

    if response.status_code == 200:
        result = response.json()
        task_id = result['data']['task_id']
        print(f"✅ Image generation started!")
        print(f"Task ID: {task_id}")
        return task_id
    else:
        print(f"❌ Error: {response.status_code}")
        print(response.text)
        return None

# Generate an image
avatar_id = "your_avatar_id"  # Replace with your actual avatar ID

task_id = generate_avatar_image(
    f"A professional headshot of {avatar_id} in a modern office environment, wearing a business suit, with soft lighting",
    aspect_ratio="1:1"
)

Checkout the API Reference - Image Generation for more details on the available parameters and options.

Monitoring Image Generation

Image Generation is an asynchronous process, so we need to check the status of the task to see when it is completed. You can do this by polling the status endpoint.

python
def check_image_status(task_id):
    """Check image generation status"""

    response = requests.get(
        f"{BASE_URL}/v1/image/async_generate/{task_id}/status",
        headers=headers
    )

    if response.status_code == 200:
        result = response.json()['data']
        status = result['status']

        print(f"Status: {status}")

        if status == "COMPLETED":
            image_data = result.get('image')
            print("🎉 Image generation completed!")
            return {"status": "completed", "image": image_data}

        elif status in ["IN_QUEUE", "IN_PROGRESS"]:
            print("⏳ Image generation in progress...")
            return {"status": "processing"}

        elif status in ["FAILED", "CANCELED", "TIMED_OUT"]:
            print(f"❌ Image generation failed: {status}")
            return {"status": "failed"}

        else:
            print(f"Unknown status: {status}")
            return {"status": "unknown"}
    else:
        print(f"Error checking status: {response.text}")
        return {"status": "error"}

def wait_for_image_completion(task_id, max_wait_time=180):  # 3 minutes
    """Wait for image generation to complete"""

    start_time = time.time()

    while time.time() - start_time < max_wait_time:
        result = check_image_status(task_id)

        if result["status"] == "completed":
            return result["image"]
        elif result["status"] == "failed":
            return None

        # Wait 5 seconds before next check
        time.sleep(5)

    print("⏰ Timeout: Image didn't complete within time limit")
    return None

# Wait for completion
if task_id:
    image_data = wait_for_image_completion(task_id)

    if image_data:
        print("✅ Image generated successfully!")
        # image_data is base64 encoded JPG
    else:
        print("❌ Image generation failed or timed out")

Sync Generation

For real-time applications that need immediate results, use the synchronous generation endpoint.

python
def generate_image_sync(prompt, aspect_ratio="16:9", seed=None):
    """Generate image synchronously - returns result immediately"""

    payload = {
        "prompt": prompt,
        "aspect_ratio": aspect_ratio
    }

    if seed:
        payload["seed"] = seed

    response = requests.post(
        f"{BASE_URL}/v1/image/generate",  # Note: /generate (not /async_generate)
        headers=headers,
        json=payload
    )

    if response.status_code == 200:
        result = response.json()
        image_base64 = result['data']['image']
        print("✅ Image generated successfully!")
        return image_base64
    else:
        print(f"❌ Error: {response.status_code}")
        print(response.text)
        return None

# Example usage
avatar_id = "your_avatar_id"
image_base64 = generate_image_sync(
    f"Professional headshot of {avatar_id} in modern office, wearing business suit",
    aspect_ratio="1:1"
)

# Save to file
if image_base64:
    import base64
    with open("generated_image.jpg", "wb") as f:
        f.write(base64.b64decode(image_base64))
    print("Image saved to generated_image.jpg")

Checkout the API Reference - Sync Image Generation for more details.

Generate Using Images as Reference

You can use existing images as inputs alongside your text prompt. This enables use cases like product placement, style transfer, and background replacement.

Using Labeled Images

Labeled images allow you to reference specific input images within your text prompt using [label] syntax. By providing labels to your reference images, you give the AI model better context about what each image represents, making it easier to understand your intent and generate more accurate results. Labels can be descriptive names (like "tshirt", "background"), specific identifiers (like "style_001"), or any meaningful reference that helps clarify your prompt.

While labeling is highly recommended for clarity and better results, it's not mandatory - you can include images without labels if needed.

Requirements:

  • Format: JPG or PNG images
  • Size: Each image is best under 1MB, with a dimension within 1024x1024 pixels
  • Encoding: Data-URL base64 format (e.g., data:image/jpeg;base64,...)
  • Maximum: Up to 5 labeled images per request
python
import base64

def encode_image_to_data_url(image_path):
    """Convert image file to data-url base64 format"""
    with open(image_path, "rb") as f:
        image_data = base64.b64encode(f.read()).decode()

    # Detect image format
    ext = image_path.lower().split('.')[-1]
    mime_type = "image/jpeg" if ext in ['jpg', 'jpeg'] else "image/png"

    return f"data:{mime_type};base64,{image_data}"

# Example: Avatar wearing a specific t-shirt
avatar_id = "f47ac10b-58cc-4372-a567-0e02b2c3d479"  # Your avatar ID

labeled_images = [
    {
        "label": "tshirt",
        "data": encode_image_to_data_url("tshirt_design.jpg")
    }
]

# Use with async generation
def generate_with_labeled_images(prompt, labeled_images, aspect_ratio="16:9"):
    """Generate image using text prompt and reference images"""

    payload = {
        "prompt": prompt,
        "aspect_ratio": aspect_ratio,
        "images": labeled_images  # Array of {label, data}
    }

    response = requests.post(
        f"{BASE_URL}/v1/image/async_generate",
        headers=headers,
        json=payload
    )

    if response.status_code == 200:
        result = response.json()
        task_id = result['data']['task_id']
        print(f"✅ Image generation started!")
        return task_id
    else:
        print(f"❌ Error: {response.status_code}")
        return None

# Reference avatar ID and labeled image in prompt using [label] syntax
task_id = generate_with_labeled_images(
    prompt=f"Professional photo of {avatar_id} wearing the [tshirt] in urban setting with natural lighting",
    labeled_images=labeled_images,
    aspect_ratio="16:9"
)

# Then poll for completion using wait_for_image_completion()

Aspect Ratios and Formats

Supported Aspect Ratios

Image generation supports the following aspect ratios:

Aspect Ratio Description
16:9 Widescreen - Great for presentations, banners
1:1 Square - Perfect for social media posts, profile pictures
4:3 Standard - Good for presentations, displays
3:2 Photo format - Natural photo proportions, good for prints
2:3 Portrait photo - Vertical photo format, good for portraits
3:4 Portrait - Good for mobile screens, vertical content
9:16 Vertical - Perfect for stories, mobile content

Output Formats

Generated images are returned in JPEG format, base64-encoded.

Dive Deeper