Text-to-Image

Text-to-image (txt2img) generation is a fundamental feature of the Scenario API, allowing you to create images from textual descriptions, or "prompts." This guide will walk you through the process of using the txt2img endpoint, detailing the available parameters and providing code examples to help you get started.

Endpoint

The endpoint for txt2img generation is:

POST https://api.cloud.scenario.com/v1/generate/txt2img- 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:

ParameterTypeDescriptionDefault
promptstringRequired. A textual description of the image you want to generate.
negativePromptstringA textual description of what you want to avoid in the generated image. Available for Stable Diffusion models, not available for Flux models.
numSamplesintegerThe number of images to generate.1
guidancenumberThe 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
numInferenceStepsintegerThe number of denoising steps. Higher values can lead to higher quality images, but also increase generation time.30
widthintegerThe width of the generated image in pixels.512
heightintegerThe height of the generated image in pixels.512
schedulerstringThe scheduler to use for the denoising process."EulerAncestralDiscrete"
modelIdstringRequired. The ID of the model to use for generation. This can be a public model or your own custom-trained model.
seedintegerA 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 txt2img endpoint in different programming languages.

Python

import requests

api_key = "YOUR_API_KEY"
api_secret = "YOUR_API_SECRET"

url = "https://api.cloud.scenario.com/v1/generate/txt2img"
headers = {"Content-Type": "application/json"}

payload = {
    "prompt": "a majestic lion in a grassy savanna, golden hour, photorealistic",
    "numSamples": 1,
    "guidance": 3.5,
    "numInferenceSteps": 28,
    "width": 1024,
    "height": 1024,
    "modelId": "flux.1-dev"
}

response = requests.post(url, headers=headers, json=payload, auth=(api_key, api_secret))

if response.status_code == 200:
    data = response.json()
    print("Image generation successful!")
else:
    print(f"Error: {response.status_code} - {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 generateImage() {
  const url = "https://api.cloud.scenario.com/v1/generate/txt2img";
  const headers = {
    "Content-Type": "application/json",
    Authorization: `Basic ${credentials}`,
  };

  const payload = {
    prompt: "a majestic lion in a grassy savanna, golden hour, photorealistic",
    numSamples: 1,
    guidance: 3.5,
    numInferenceSteps: 28,
    width: 1024,
    height: 1024,
    modelId: "flux.1-dev",
  };

  try {
    const response = await fetch(url, {
      method: "POST",
      headers: headers,
      body: JSON.stringify(payload),
    });

    const data = await response.json();

    if (response.ok) {
      console.log("Image generation ongoing!");
    } else {
      console.error(`Error: ${response.status} - ${JSON.stringify(data)}`);
    }
  } catch (error) {
    console.error("Network or other error:", error);
  }
}

generateImage();

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": "txt2img",
                "baseModelId": "",
                "prompt": "a majestic lion in a grassy savanna, golden hour, photorealistic",
                "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

job_id = "job_staging_sDjuCv2SPsURo6b2d8R6TZM8"
url = f"https://api.scenario.com/v1/jobs/{job_id}"
headers = {
    "Authorization": "Bearer YOUR_API_KEY"
}

while True:
    response = requests.get(url, headers=headers)
    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();