Adobe Firefly API
Adobe Firefly API Complete Reference¶
This section provides comprehensive examples for all Adobe Firefly API endpoints available in Vision Studio, including image generation, editing, and utility operations.
Prerequisites¶
import requests
import json
import base64
# Your API endpoint and key
API_URL = "http://localhost:8527/api/v1/firefly"
API_KEY = "your-api-key"
headers = {
"X-API-Key": API_KEY,
"Content-Type": "application/json"
}
Authentication¶
Get Access Token¶
Obtain an access token for Adobe Firefly API operations.
Image Generation¶
1. Generate Images¶
Create high-quality images using Adobe Firefly's various models and configurations.
Basic Image Generation with Image 3 Model¶
data = {
"access_token": access_token,
"x_model_version": "image3",
"prompt": "A majestic mountain landscape with crystal-clear lake reflecting snow-capped peaks during golden hour",
"content_class": "photo",
"size": {
"height": 2048,
"width": 2048
},
"upsampler_type": "default"
}
response = requests.post(
f"{API_URL}/image/generation/generate-image",
headers=headers,
json=data
)
Advanced Generation with Image 4 Ultra Model¶
data = {
"access_token": access_token,
"x_model_version": "image4_ultra",
"prompt": "Ultra-detailed portrait of a wise elderly woman with intricate traditional jewelry",
"content_class": "photo",
"negative_prompt": "blurry, distorted, low quality, artificial",
"prompt_biasing_locale_code": "en-US",
"seeds": [1, 2, 3], # Generate 3 variations with specific seeds
"size": {
"height": 2688,
"width": 1536
},
"visual_intensity": 7,
"upsampler_type": "default"
}
response = requests.post(
f"{API_URL}/image/generation/generate-image",
headers=headers,
json=data
)
Art Style Generation¶
data = {
"access_token": access_token,
"x_model_version": "image3",
"prompt": "Abstract geometric composition with vibrant colors and dynamic shapes",
"content_class": "art",
"size": {
"height": 1792,
"width": 2304
},
"visual_intensity": 9,
"upsampler_type": "default"
}
response = requests.post(
f"{API_URL}/image/generation/generate-image",
headers=headers,
json=data
)
Generation with Structure Reference¶
# First, upload a reference image for structure
structure_reference = {
"source": {
"url": "https://example.com/structure_reference.jpg"
}
}
data = {
"access_token": access_token,
"x_model_version": "image3",
"prompt": "Transform this composition into a futuristic cityscape",
"content_class": "photo",
"size": {
"height": 1344,
"width": 768
},
"structure": {
"imageReference": structure_reference,
"strength": 80 # 0-100, higher means stronger adherence to structure
},
"seeds": [42],
"upsampler_type": "default"
}
response = requests.post(
f"{API_URL}/image/generation/generate-image",
headers=headers,
json=data
)
Generation with Style Reference¶
# Style reference with presets
style_reference = {
"source": {
"url": "https://example.com/style_reference.jpg"
}
}
data = {
"access_token": access_token,
"x_model_version": "image3",
"prompt": "A serene garden scene with flowing water and lush vegetation",
"content_class": "art",
"size": {
"height": 1152,
"width": 896
},
"style": {
"imageReference": style_reference,
"strength": 65,
"presets": ["impressionist", "vibrant"] # Available presets for style
},
"visual_intensity": 6,
"upsampler_type": "default"
}
response = requests.post(
f"{API_URL}/image/generation/generate-image",
headers=headers,
json=data
)
Custom Model Generation¶
data = {
"access_token": access_token,
"x_model_version": "image3_custom",
"custom_model_id": "your-custom-model-uuid-here", # Required for custom models
"prompt": "Generate an image in my custom style",
"content_class": "photo",
"size": {
"height": 2048,
"width": 2048
},
"seeds": [1, 2], # Generate 2 variations
"upsampler_type": "default"
}
response = requests.post(
f"{API_URL}/image/generation/generate-image",
headers=headers,
json=data
)
2. Generate Similar Images (Variations)¶
Create variations of an existing image while maintaining its core characteristics.
# Reference image for variation
reference_image = {
"source": {
"url": "https://example.com/original_image.jpg"
# Or use upload_id: "uploaded-uuid-from-upload-endpoint"
}
}
data = {
"access_token": access_token,
"x_model_version": "image3",
"image": reference_image,
"seeds": [1, 2, 3, 4] # Generate 4 variations
}
response = requests.post(
f"{API_URL}/image/generation/generate-variation",
headers=headers,
json=data
)
Image Editing¶
1. Generate Product Background¶
Composite products into new background environments with precise placement control.
Basic Product Background¶
# Product image and mask
product_image = {
"source": {
"url": "https://example.com/product_cutout.png"
}
}
mask_image = {
"source": {
"url": "https://example.com/product_mask.png"
}
}
data = {
"access_token": access_token,
"prompt": "Modern minimalist kitchen with marble countertops and natural lighting",
"image": product_image,
"mask": mask_image,
"content_class": "photo",
"placement": {
"alignment": {
"horizontal": "center",
"vertical": "center"
},
"insert": {
"center": 0,
"top": 0,
"bottom": 0,
"left": 0,
"right": 0
}
},
"seeds": [123],
"size": {
"height": 2048,
"width": 2048
}
}
Custom Placement Product Background¶
data = {
"access_token": access_token,
"prompt": "Luxurious bedroom setting with warm ambient lighting",
"image": product_image,
"mask": mask_image,
"content_class": "photo",
"placement": {
"alignment": {
"horizontal": "left",
"vertical": "bottom"
},
"insert": {
"center": 0,
"top": 100,
"bottom": 50,
"left": 200,
"right": 0
}
},
"size": {
"height": 1792,
"width": 2304
},
"seeds": [456, 789] # Generate 2 variations
}
response = requests.post(
f"{API_URL}/image/editing/generate-product-background",
headers=headers,
json=data
)
Styled Product Background¶
# Style reference for the background
style_reference = {
"source": {
"url": "https://example.com/interior_style.jpg"
}
}
data = {
"access_token": access_token,
"prompt": "Elegant living room with sophisticated decor",
"image": product_image,
"mask": mask_image,
"content_class": "photo",
"placement": {
"alignment": {
"horizontal": "right",
"vertical": "top"
},
"insert": {
"center": 0,
"top": 0,
"bottom": 100,
"left": 0,
"right": 150
}
},
"style": {
"imageReference": style_reference,
"strength": 70,
"presets": ["modern", "elegant"]
},
"size": {
"height": 2688,
"width": 1536
}
}
response = requests.post(
f"{API_URL}/image/editing/generate-product-background",
headers=headers,
json=data
)
2. Expand Image (Outpainting)¶
Extend images beyond their original boundaries with AI-generated content.
Basic Image Expansion¶
# Source image to expand
source_image = {
"source": {
"url": "https://example.com/portrait.jpg"
}
}
# Mask defining expansion areas
expansion_mask = {
"source": {
"url": "https://example.com/expansion_mask.png"
},
"invert": False # False means white areas will be expanded
}
data = {
"access_token": access_token,
"image": source_image,
"mask": expansion_mask,
"placement": {
"alignment": {
"horizontal": "center",
"vertical": "center"
},
"insert": {
"center": 0,
"top": 200, # Expand upward by 200px
"bottom": 200, # Expand downward by 200px
"left": 300, # Expand left by 300px
"right": 300 # Expand right by 300px
}
},
"prompt": "Natural forest background with tall pine trees",
"seeds": [111, 222],
"size": {
"height": 2048,
"width": 2048
}
}
response = requests.post(
f"{API_URL}/image/editing/expand-image",
headers=headers,
json=data
)
Selective Expansion¶
data = {
"access_token": access_token,
"image": source_image,
"mask": expansion_mask,
"placement": {
"alignment": {
"horizontal": "left",
"vertical": "bottom"
},
"insert": {
"center": 0,
"top": 500, # Expand only upward for sky
"bottom": 0,
"left": 0,
"right": 0
}
},
"prompt": "Dramatic cloudy sky with golden sunset",
"seeds": [333]
}
response = requests.post(
f"{API_URL}/image/editing/expand-image",
headers=headers,
json=data
)
3. Inpainting (Fill Image)¶
Fill specific areas of images with new AI-generated content.
Basic Inpainting¶
# Source image with areas to fill
source_image = {
"source": {
"url": "https://example.com/scene_with_gaps.jpg"
}
}
# Mask defining areas to fill
fill_mask = {
"source": {
"url": "https://example.com/fill_mask.png"
},
"invert": False # White areas will be filled
}
data = {
"access_token": access_token,
"image": source_image,
"mask": fill_mask,
"prompt": "Beautiful flowering garden with colorful roses and butterflies",
"negative_prompt": "dead plants, wilted flowers, brown leaves",
"prompt_biasing_locale_code": "en-US",
"seeds": [777],
"size": {
"height": 2048,
"width": 2048
}
}
response = requests.post(
f"{API_URL}/image/editing/inpaint",
headers=headers,
json=data
)
Advanced Inpainting with Multiple Variations¶
data = {
"access_token": access_token,
"image": source_image,
"mask": fill_mask,
"prompt": "Modern architectural elements with clean geometric lines",
"negative_prompt": "cluttered, messy, old, weathered",
"seeds": [100, 200, 300, 400], # Generate 4 different fills
"size": {
"height": 1792,
"width": 2304
}
}
response = requests.post(
f"{API_URL}/image/editing/inpaint",
headers=headers,
json=data
)
Content Removal Inpainting¶
# Remove objects by filling with background
data = {
"access_token": access_token,
"image": source_image,
"mask": fill_mask,
"prompt": None, # No prompt for background filling
"negative_prompt": "objects, people, text, signs",
"seeds": [555],
"size": {
"height": 2048,
"width": 2048
}
}
response = requests.post(
f"{API_URL}/image/editing/inpaint",
headers=headers,
json=data
)
Job Management¶
Check Job Status¶
Monitor the progress and retrieve results of asynchronous operations.
job_id = "your-job-id-from-generation-request"
response = requests.get(
f"{API_URL}/status/{job_id}",
headers={"access_token": access_token}
)
Cancel Job¶
Cancel a running generation job.
job_id = "your-job-id-to-cancel"
response = requests.put(
f"{API_URL}/cancel/{job_id}",
headers={"access_token": access_token}
)
File Upload¶
Upload Images¶
Upload images to Adobe's storage for use in generation and editing operations.
# Upload an image file
with open("your_image.jpg", "rb") as image_file:
files = {"file": image_file}
upload_headers = {"access_token": access_token}
response = requests.post(
f"{API_URL}/upload",
headers=upload_headers,
files=files
)
Advanced Example: Concurrent Image Generation¶
Here's an example of making multiple concurrent generation requests using asyncio and aiohttp:
import asyncio
import aiohttp
import time
async def generate_image_async(session, prompt, request_id, access_token):
"""Generate a single image asynchronously."""
url = f"{API_URL}/image/generation/generate-image"
data = {
"access_token": access_token,
"x_model_version": "image3",
"prompt": prompt,
"content_class": "photo",
"size": {
"height": 1024,
"width": 1024
},
"seeds": [request_id + 100], # Use request_id to ensure unique seeds
"upsampler_type": "default"
}
headers_async = {
"X-API-Key": API_KEY,
"Content-Type": "application/json"
}
start_time = time.time()
try:
async with session.post(url, headers=headers_async, json=data) as response:
result = await response.json()
duration = time.time() - start_time
return {
"request_id": request_id,
"prompt": prompt,
"status": response.status,
"duration": duration,
"result": result
}
except Exception as e:
return {
"request_id": request_id,
"prompt": prompt,
"status": -1,
"duration": time.time() - start_time,
"error": str(e)
}
async def check_job_status_async(session, job_id, access_token):
"""Check job status asynchronously."""
url = f"{API_URL}/status/{job_id}"
headers_async = {
"access_token": access_token
}
try:
async with session.get(url, headers=headers_async) as response:
result = await response.json()
return {
"job_id": job_id,
"status": response.status,
"result": result
}
except Exception as e:
return {
"job_id": job_id,
"status": -1,
"error": str(e)
}
async def generate_multiple_images_concurrently():
"""Generate multiple images concurrently and monitor their completion."""
# First, get access token
token_response = requests.post(f"{API_URL}/token", headers=headers)
if not token_response.json()["success"]:
print("Failed to get access token")
return
access_token = token_response.json()["data"]["access_token"]
prompts = [
"A peaceful mountain lake surrounded by autumn foliage",
"Modern architectural building with glass facade at sunset",
"Vibrant street art mural with geometric patterns",
"Cozy coffee shop interior with warm lighting",
"Abstract digital art with flowing colors and shapes"
]
# Configure session for concurrent requests
timeout = aiohttp.ClientTimeout(total=300) # 5 minute timeout
connector = aiohttp.TCPConnector(limit=10)
async with aiohttp.ClientSession(connector=connector, timeout=timeout) as session:
# Phase 1: Start all generation jobs concurrently
print(f"Starting {len(prompts)} concurrent image generation requests...")
start_time = time.time()
generation_tasks = [
generate_image_async(session, prompt, i, access_token)
for i, prompt in enumerate(prompts)
]
generation_results = await asyncio.gather(*generation_tasks)
# Extract job IDs from successful requests
job_ids = []
for result in generation_results:
if result["status"] == 200 and result["result"]["success"]:
job_id = result["result"]["data"]["job_id"]
job_ids.append(job_id)
print(f"✅ Started job {job_id} for: {result['prompt'][:50]}...")
else:
error_msg = result.get('error', f"HTTP {result['status']}")
print(f"❌ Failed to start: {result['prompt'][:50]}... - {error_msg}")
if not job_ids:
print("No jobs started successfully")
return
# Phase 2: Monitor job completion
print(f"\nMonitoring {len(job_ids)} jobs for completion...")
completed_jobs = []
max_wait_time = 300 # 5 minutes maximum wait
check_interval = 5 # Check every 5 seconds
elapsed_time = 0
while len(completed_jobs) < len(job_ids) and elapsed_time < max_wait_time:
# Check status of all pending jobs
pending_job_ids = [jid for jid in job_ids if jid not in completed_jobs]
status_tasks = [
check_job_status_async(session, job_id, access_token)
for job_id in pending_job_ids
]
status_results = await asyncio.gather(*status_tasks)
for status_result in status_results:
if status_result["status"] == 200:
job_data = status_result["result"]["data"]
job_status = job_data.get("status", "unknown")
job_id = status_result["job_id"]
if job_status == "completed":
completed_jobs.append(job_id)
# Get the generated images
outputs = job_data.get("outputs", [])
print(f"✅ Job {job_id} completed with {len(outputs)} images")
for i, output in enumerate(outputs):
if "image" in output and "url" in output["image"]:
print(f" Image {i+1}: {output['image']['url']}")
elif job_status == "failed":
completed_jobs.append(job_id) # Count as completed to stop waiting
error_msg = job_data.get("error", "Unknown error")
print(f"❌ Job {job_id} failed: {error_msg}")
# Wait before next check if there are still pending jobs
if len(completed_jobs) < len(job_ids):
await asyncio.sleep(check_interval)
elapsed_time += check_interval
total_time = time.time() - start_time
# Final summary
successful_jobs = len([jid for jid in completed_jobs])
print(f"\n📊 Summary:")
print(f" Total time: {total_time:.1f} seconds")
print(f" Jobs started: {len(job_ids)}")
print(f" Jobs completed: {successful_jobs}")
if elapsed_time >= max_wait_time:
remaining = len(job_ids) - len(completed_jobs)
print(f" ⚠️ {remaining} jobs still pending (timeout reached)")
# Run the concurrent generation
if __name__ == "__main__":
asyncio.run(generate_multiple_images_concurrently())
This concurrent example demonstrates: - Two-phase approach: Start all generation jobs concurrently, then monitor completion - Proper session management with timeouts and connection limits - Job status monitoring with polling until completion - Comprehensive error handling for both generation and status checking - Performance metrics and detailed progress reporting - Realistic timeout handling for long-running generation tasks
Available Model Sizes¶
Image3 Model Sizes¶
- 2048×2048 (Square)
- 1024×1024 (Small Square)
- 2304×1792 (Landscape)
- 1792×2304 (Portrait)
- 2688×1536 (Wide)
- 2688×1512 (Wide Alt)
- 1344×768 (Small Wide)
- 1344×756 (Small Wide Alt)
- 1152×896 (Medium Landscape)
- 896×1152 (Medium Portrait)
Image4 Model Sizes¶
- 2048×2048 (Square)
- 2304×1792 (Landscape)
- 1792×2304 (Portrait)
- 2688×1536 (Wide)
- 1440×2560 (Mobile Portrait)
Best Practices¶
- Use appropriate model versions: Choose between Image3, Image4 Standard, and Image4 Ultra based on quality requirements
- Manage seeds effectively: Use unique seeds for variations, consistent seeds for reproducibility
- Optimize placement parameters: Fine-tune alignment and insert values for precise product positioning
- Handle async operations: Always monitor job status for completion rather than assuming immediate results
- Upload management: Use upload endpoint for repeated use of images to avoid re-uploading
- Size constraints: Respect model-specific size limitations and file size limits (15MB max)
- Concurrent operations: Use proper session management and timeouts for concurrent requests
- Error handling: Implement robust retry logic for failed jobs and network issues