Image-to-Image
Image-to-image (img2img) generation is a feature of the Scenario API that allows you to transform an existing image based on a new prompt or specific parameters. This is incredibly useful for image variations, or modifying existing image while maintaining their core composition. This guide will detail the img2img endpoint, its parameters, and provide code examples.
Endpoint
The primary endpoint for img2img generation is:
POST https://api.cloud.scenario.com/v1/generate/img2img
- API Reference
Request Body
The request body should be a JSON object containing the parameters for your image generation request. Here is a comprehensive list of the available parameters:
Parameter | Type | Description | Default |
---|---|---|---|
prompt | string | Required. A textual description of the desired transformation or new content. | |
image | string | The asset ID or the data URL of your input image | |
negativePrompt | string | A textual description of what you want to avoid in the generated image. Available for Stable Diffusion models, not available for Flux models. | |
strength | number | Determines how much the generated image deviates from the original input image. A higher value means the AI will take more creative liberties, while a lower value will result in an output closer to the original. Range: 0.0 to 1.0. | 0.8 |
numSamples | integer | The number of images to generate. | 1 |
guidance | number | The guidance scale, which controls how closely the generated image follows the prompt. Higher values result in images that are more faithful to the prompt, while lower values allow for more creative freedom. | 7.5 |
numInferenceSteps | integer | The number of denoising steps. Higher values can lead to higher quality images, but also increase generation time. | 30 |
width | integer | The width of the generated image in pixels. | 512 |
height | integer | The height of the generated image in pixels. | 512 |
scheduler | string | The scheduler to use for the denoising process. Available for Stable Diffusion models, not available for Flux models. | "EulerAncestralDiscrete" |
modelId | string | Required. The ID of the model to use for generation. This can be a public model or your own custom-trained model. | |
seed | integer | A seed value for the random number generator. Using the same seed with the same parameters will produce the same image. |
Code Examples
Here are some examples of how to use the img2img endpoint in different programming languages.
cURL
curl -X POST \
-u "YOUR_API_KEY:YOUR_API_SECRET" \
-H "Content-Type: application/json" \
-d
'{
"prompt": "a mystical forest, glowing flora, ethereal light",
"image": "yourimageid",
"strength": 0.75,
"numSamples": 1,
"guidance": 3.5,
"numInferenceSteps": 28,
"modelId": "flux.1-dev"
}' \
https://api.cloud.scenario.com/v1/generate/img2img
Python
import requests
import time
api_key = "YOUR_API_KEY"
api_secret = "YOUR_API_SECRET"
# Step 1: Initiate img2img Generation
url = "https://api.cloud.scenario.com/v1/generate/img2img"
headers = {"Content-Type": "application/json"}
payload = {
"prompt": "a mystical forest, glowing flora, ethereal light",
"image": "yourImageId",
"strength": 0.75,
"numSamples": 1,
"guidance": 3.5,
"numInferenceSteps": 28,
"modelId": "flux.1-dev"
}
print("Initiating img2img generation...")
initial_response = requests.post(url, headers=headers, json=payload, auth=(api_key, api_secret))
if initial_response.status_code == 200:
initial_data = initial_response.json()
job_id = initial_data.get("job").get("jobId")
if job_id:
print(f"img2img generation job initiated. Job ID: {job_id}")
else:
print("Error: No jobId returned in the initial response.")
else:
print(f"Error initiating img2img generation: {initial_response.status_code} - {initial_response.text}")
Node.js
const fetch = require("node-fetch");
const apiKey = "YOUR_API_KEY";
const apiSecret = "YOUR_API_SECRET";
const credentials = Buffer.from(`${apiKey}:${apiSecret}`).toString("base64");
async function transformImage() {
const initialUrl = "https://api.cloud.scenario.com/v1/generate/img2img";
const headers = {
"Content-Type": "application/json",
Authorization: `Basic ${credentials}`,
};
const payload = {
prompt: "a mystical forest, glowing flora, ethereal light",
image: "yourImageId",
strength: 0.75,
numSamples: 1,
guidance: 3.5,
numInferenceSteps: 28,
modelId: "flux.1-dev",
};
console.log("Initiating img2img generation...");
try {
const initialResponse = await fetch(initialUrl, {
method: "POST",
headers: headers,
body: JSON.stringify(payload),
});
const initialData = await initialResponse.json();
if (initialResponse.ok) {
const jobId = initialData.job.jobId;
if (jobId) {
console.log(`img2img generation job initiated. Job ID: ${jobId}`);
} else {
console.error("Error: No jobId returned in the initial response.");
}
} else {
console.error(`Error initiating img2img generation: ${initialResponse.status} - ${JSON.stringify(initialData)}`);
}
} catch (error) {
console.error("Network or other error:", error);
}
}
transformImage();
Response
A successful response will return a JSON object containing your job.
{
"job": {
"jobId": "job_staging_sDjuCv2SPsURo6b2d8R6TZM8",
"jobType": "flux",
"metadata": {
"input": {
"modelId": "flux.1-dev",
"type": "img2img",
"baseModelId": "",
image: "yourImageId",
"prompt": "a mystical forest, glowing flora, ethereal light",
"negativePrompt": "",
"numSamples": 1,
"intermediateImages": false,
"guidance": 3.5,
"numInferenceSteps": 28,
"width": 1024,
"height": 1024,
"hideResults": false
},
"assetIds": []
},
"ownerId": "L7lMcxokRX-PtgcX9nntPQ",
"authorId": "0f5cf33de03587879c9e11a8edf646ea",
"createdAt": "2025-06-30T14:19:48.691Z",
"updatedAt": "2025-06-30T14:19:48.691Z",
"status": "queued",
"statusHistory": [
{
"status": "queued",
"date": "2025-06-30T14:19:48.691Z"
}
],
"progress": 0
},
"creativeUnitsCost": 5
}
Then you can poll the GET /jobs/{jobId}
endpoint every 3 seconds until the job is complete (status: "success") and then extract the assetIds from the metadata field. (API Reference)
Python
import time
import requests
api_key = "YOUR_API_KEY"
api_secret = "YOUR_API_SECRET"
job_id = "job_staging_sDjuCv2SPsURo6b2d8R6TZM8"
url = f"https://api.scenario.com/v1/jobs/{job_id}"
headers = {"Content-Type": "application/json"}
while True:
response = requests.get(url, headers=headers, auth=(api_key, api_secret))
response.raise_for_status()
data = response.json()
status = data["job"]["status"]
print(f"Job status: {status}")
if status == "success":
asset_ids = data["job"]["metadata"].get("assetIds", [])
print(f"Job complete. Asset IDs: {asset_ids}")
break
elif status in ["failure", "canceled"]:
raise Exception(f"Job ended with status: {status}")
time.sleep(3)
Node.js
const axios = require("axios");
const JOB_ID = "job_staging_sDjuCv2SPsURo6b2d8R6TZM8";
const apiKey = "YOUR_API_KEY";
const apiSecret = "YOUR_API_SECRET";
const credentials = Buffer.from(`${apiKey}:${apiSecret}`).toString("base64");
const pollJob = async () => {
const url = `https://api.scenario.com/v1/jobs/${JOB_ID}`;
const headers = {
Authorization: `Basic ${credentials}`
};
while (true) {
try {
const response = await axios.get(url, { headers });
const job = response.data.job;
const status = job.status;
console.log(`Job status: ${status}`);
if (status === "success") {
const assetIds = job.metadata.assetIds || [];
console.log("Job complete. Asset IDs:", assetIds);
break;
} else if (["failure", "canceled"].includes(status)) {
console.error(`Job ended with status: ${status}`);
break;
}
await new Promise((resolve) => setTimeout(resolve, 3000));
} catch (error) {
console.error("Error polling job:", error.message);
break;
}
}
};
pollJob();
Updated about 11 hours ago