Using the Object Composite API

This guide explains the Object Composite API and the key processing features it offers for generating composites with its various endpoints.

Overview

The Object Composite API operations offer Adobe's enterprise-grade image compositing capabilities and other more specific compositing operations that unlocks new compositional workflows.

The API enables intelligent object insertion, replacement, and harmonization within images, with powerful capabilities for integrating objects into background scenes with realistic lighting, shadows, and harmonization.

For Object Composite operations there are a few choices:

Object Composite

Object Composite is Adobe's enterprise-grade image compositing capability.

Execute this operations using a object composite request with the endpoint /v3/images/generate-object-composite-async.

Precise Composite

Precise Composite places the subject in the masked region and applies generative harmonization so the subject blends naturally with the background. Use when you want AI-driven harmonization and a single, consistent style.

Execute this operations using a precise composite request with the endpoint /v3/images/precise-composite.

Adaptive Composite

Adaptive Composite composites the subject seamlessly into the background at the masked location, with control over shadows and background preservation. Use when you need seamless product compositing, context-aware alignment, and parameters such as shadowIntensity and preserveBackground.

Execute this operations using an adaptive composite request with the endpoint /v3/images/adaptive-composite.

Inputs

The API is powerful in a variety of workflows but will often require these inputs:

Precise Composite feature parameters:

Adaptive Composite feature parameters:

For full technical details, see the Object Composite API Reference.

Direct object insertion

Using Adaptive Composite, customers can composite products into existing or custom-generated backgrounds, such as brand-specific environments produced with Firefly Custom Models.

Image of the background, a clean modern kitchen countertop

Background

Image of the product, a cereal box

Product

Image of the composite, the cereal box on the kitchen countertop

Composite

Key parameters

data-slots=heading, text, code

Example payload

This is a payload example.
{
  "background": {
    "image": {
      "source": {
        "url": "https://example.com/living-room.jpg"
      }
    },
    "fillAreaMask": {
      "source": {
        "url": "https://example.com/placement-mask.png"
      }
    }
  },
  "object": {
    "image": {
      "source": {
        "url": "https://example.com/chair.png"
      }
    },
    "mask": {
      "source": {
        "url": "https://example.com/chair-mask.png"
      }
    }
  },
  "harmonization": 0.7,
  "shadowIntensity": 1,
  "seeds": [333]
}
data-slots=heading, text, code

Python implementation

An example of a Python implementation.
import requests
import json

# Configuration
API_BASE = "https://firefly-api.adobe.io"
ACCESS_TOKEN = "your_access_token"
API_KEY = "your_api_key"

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

# Request payload
payload = {
    "background": {
        "image": {
            "source": {
                "url": "https://example.com/background.jpg"
            }
        },
        "fillAreaMask": {
            "source": {
                "url": "https://example.com/mask.png"
            }
        }
    },
    "object": {
        "image": {
            "source": {
                "url": "https://example.com/object.png"
            }
        },
        "mask": {
            "source": {
                "url": "https://example.com/object-mask.png"
            }
        }
    },
    "harmonization": 0.7,
    "preserveBackground": False,
    "shadowIntensity": 1,
    "seeds": [333],
    "output": {
        "mediaType": "image/png"
    }
}

# Submit job
response = requests.post(
    f"{API_BASE}/v3/images/adaptive-composite",
    headers=headers,
    json=payload
)

if response.status_code == 202:
    result = response.json()
    job_id = result["jobId"]
    status_url = result.get("statusUrl")
    print(f"Job submitted successfully. Job ID: {job_id}")
else:
    print(f"Error: {response.status_code}")
    print(response.json())
data-slots=heading, text, code

JavaScript implementation

An example of a JavaScript implementation.
const axios = require('axios');

const API_BASE = 'https://firefly-api.adobe.io';
const ACCESS_TOKEN = 'your_access_token';
const API_KEY = 'your_api_key';

async function adaptiveComposite() {
  const payload = {
    background: {
      image: {
        source: {
          url: 'https://example.com/background.jpg'
        }
      },
      fillAreaMask: {
        source: {
          url: 'https://example.com/mask.png'
        }
      }
    },
    object: {
      image: {
        source: {
          url: 'https://example.com/object.png'
        }
      },
      mask: {
        source: {
          url: 'https://example.com/object-mask.png'
        }
      }
    },
    harmonization: 0.7,
    preserveBackground: false,
    shadowIntensity: 1,
    seeds: [333],
    output: {
      mediaType: 'image/png'
    }
  };

  try {
    const response = await axios.post(
      `${API_BASE}/v3/images/adaptive-composite`,
      payload,
      {
        headers: {
          'Authorization': `Bearer ${ACCESS_TOKEN}`,
          'x-api-key': API_KEY,
          'Content-Type': 'application/json',
        }
      }
    );

    console.log('Job ID:', response.data.jobId);
    return response.data;
  } catch (error) {
    console.error('Error:', error.response?.data || error.message);
    throw error;
  }
}

async function checkJobStatus(jobId) {
  const url = `${API_BASE}/v3/status/${jobId}`;

  try {
    const response = await axios.get(url, {
      headers: {
        'Authorization': `Bearer ${ACCESS_TOKEN}`,
        'x-api-key': API_KEY
      }
    });

    return response.data;
  } catch (error) {
    console.error('Error checking status:', error.response?.data || error.message);
    throw error;
  }
}

// Usage
(async () => {
  const job = await adaptiveComposite();
  const status = await checkJobStatus(job.jobId);
  console.log('Job Status:', status);
})();

Background preservation

Users can insert objects while maintaining the original background details within the masked area when they enable Background Preservation mode. Even within the masked area, the background details are preserved in the composite. Some strong use cases for background preservation are:

Background image of a hand holding a phone in front of a bookcase Background image

Product image, the back of a phone Product image

Mask image, a rectangle around the phone Mask area image (white area is the dynamic, changeable area)

Generated composite showing the back of the phone Example composite with background preservation

Key parameters

data-slots=heading, text, code

Example payload

This is a payload example.
{
  "background": {
    "image": {
      "source": {
        "url": "https://example.com/textured-floor.jpg"
      }
    },
    "fillAreaMask": {
      "source": {
        "url": "https://example.com/placement-area.png"
      }
    }
  },
  "object": {
    "image": {
      "source": {
        "url": "https://example.com/vase.png"
      }
    }
  },
  "preserveBackground": true,  // Enable Background Preservation mode
  "harmonization": 0.8,  // Harmonization strength (0-1)
  "seeds": [333]  // A single seed value for the composite
}
data-slots=heading, text, code

Python implementation

An example of a Python implementation.
import requests
import json

# Configuration
API_BASE = "https://firefly-api.adobe.io"
ACCESS_TOKEN = "your_access_token"
API_KEY = "your_api_key"

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

# Request payload
payload = {
    "background": {
        "image": {
            "source": {
                "url": "https://example.com/wooden-floor.jpg"
            }
        },
        "fillAreaMask": {
            "source": {
                "url": "https://example.com/placement-mask.png"
            }
        }
    },
    "object": {
        "image": {
            "source": {
                "url": "https://example.com/furniture.png"
            }
        }
    },
    "preserveBackground": True,  # Keep floor texture visible
    "harmonization": 0.8,
    "shadowIntensity": 1,
    "seeds": [42, 84, 126],  # Generate 3 variations
    "output": {
        "mediaType": "image/png"
    }
}

# Submit job
response = requests.post(
    f"{API_BASE}/v3/images/adaptive-composite",
    headers=headers,
    json=payload
)

if response.status_code == 202:
    result = response.json()
    job_id = result["jobId"]
    status_url = result.get("statusUrl")
    print(f"Job submitted successfully. Job ID: {job_id}")
else:
    print(f"Error: {response.status_code}")
    print(response.json())
data-slots=heading, text, code

JavaScript implementation

An example of a JavaScript implementation.
const axios = require('axios');

const API_BASE = 'https://firefly-api.adobe.io';
const ACCESS_TOKEN = 'your_access_token';
const API_KEY = 'your_api_key';

async function adaptiveComposite() {
  const payload = {
    background: {
      image: {
        source: {
          url: 'https://example.com/wooden-floor.jpg'
        }
      },
      fillAreaMask: {
        source: {
          url: 'https://example.com/placement-mask.png'
        }
      }
    },
    object: {
      image: {
        source: {
          url: 'https://example.com/furniture.png'
        }
      }
    },
    preserveBackground: true,  // Keep floor texture visible
    harmonization: 0.8,
    shadowIntensity: 1,
    seeds: [42, 84, 126],  // Generate 3 variations
    output: {
      mediaType: 'image/png'
    }
  };

  try {
    const response = await axios.post(
      `${API_BASE}/v3/images/adaptive-composite`,
      payload,
      {
        headers: {
          'Authorization': `Bearer ${ACCESS_TOKEN}`,
          'x-api-key': API_KEY,
          'Content-Type': 'application/json',
        }
      }
    );

    console.log('Job ID:', response.data.jobId);
    return response.data;
  } catch (error) {
    console.error('Error:', error.response?.data || error.message);
    throw error;
  }
}

async function checkJobStatus(jobId) {
  const url = `${API_BASE}/v3/status/${jobId}`;

  try {
    const response = await axios.get(url, {
      headers: {
        'Authorization': `Bearer ${ACCESS_TOKEN}`,
        'x-api-key': API_KEY
      }
    });

    return response.data;
  } catch (error) {
    console.error('Error checking status:', error.response?.data || error.message);
    throw error;
  }
}

// Usage
(async () => {
  const job = await adaptiveComposite();
  const status = await checkJobStatus(job.jobId);
  console.log('Job Status:', status);
})();

Cancel a job

The API allows you to cancel in-progress jobs with the PUT /v3/cancel/{jobId} endpoint to save resources and processing time.

Use the cancellation request to cancel a job:

curl -X PUT "https://firefly-api.adobe.io/v3/cancel/{jobId}" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "x-api-key: YOUR_API_KEY"

When polling a cancelled job's status, you'll receive:

{
  "status": "cancelled",
  "jobId": "job-id-here",
  "error_code": "job_cancelled",
  "message": "Job was cancelled by user request"
}

Additional resources

To get started with your own development, start with Composite Authentication. For more details on the Composite Operations APIs, see the Composite Operations APIs API Reference.