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
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.
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.
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
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.