🎨 Step 3: Generate Your First Image (Text-to-Image)

Now that you can authenticate, let's generate your first image using the text-to-image (txt2img) functionality. This is one of the most common ways to use the Scenario API, where you provide a textual description (prompt) and the AI generates an image based on it.

For this example, we will use a public model ID. In a real-world scenario, you would typically use your own trained model ID or a specific public model relevant to your needs. You can find more details on inference parameters in the Text to Image documentation.

Example: Text-to-Image Generation

Let's generate an image of "a futuristic city at sunset, highly detailed, cyberpunk style."

cURL

curl -X POST \
  -u "YOUR_API_KEY:YOUR_API_SECRET" \
  -H "Content-Type: application/json" \
  -d 
'''
{
    "prompt": "a futuristic city at sunset, highly detailed, cyberpunk style",
    "numSamples": 1,
    "guidance": 7.5,
    "numInferenceSteps": 30,
    "width": 512,
    "height": 512,
    "scheduler": "EulerAncestralDiscrete",
    "modelId": "YOUR_MODEL_ID" # Replace with a valid model ID, e.g., a public one or your own
}
''' \
  https://api.scenario.com/v1/generate/txt2img

Python

import requests
import time

# Set the base URL
base_url = 'https://api.cloud.scenario.com/v1'
model_id = 'flux.1-dev'  # Flux Dev public model

# Set the authentication header
headers = {
    'accept': 'application/json',
    'Authorization': 'Basic <<base64(key:secret)>>'
}

# Make a POST request to create an inference job
response = requests.post(f'{base_url}/generate/txt2img', json={
    'modelId': model_id,
    'prompt': (
        'close up portrait of a sci-fi character in red armor with cyber helmet, lights on cyber mask, full armor, insulated armor, angry, active pose, strong warrior, weapon, optimus prime style, bald head, lots of fine detail, sci-fi dark movie style, background: spaceship, photography, natural light, photorealism, cinematic rendering, ray tracing, highest quality, highest detail'
    ),
    'numInferenceSteps': 28,
    'numSamples': 2,
    'guidance': 3.5,
    'width': 1024,
    'height': 1024,
}, headers=headers)

# Check if the request was successful
if response.status_code == 200:
    data = response.json()
    print('Response:', data)

    # Ensure the response contains the jobId
    job_id = data.get('job', {}).get('jobId')
    if not job_id:
        print('Error: Job ID not found in the response.')
        exit(1)

    print(f'Job ID: {job_id}')

    # Function to poll the job status
    def poll_job_status(job_id):
        status = ''
        while status not in ['success', 'failure']:
            # Fetch the job details
            job_response = requests.get(f'{base_url}/jobs/{job_id}', headers=headers)
            
            if job_response.status_code != 200:
                print(f'Error fetching job status: {job_response.status_code}')
                print(job_response.json())  # Print error details
                exit(1)
            
            job_data = job_response.json()
            status = job_data.get('status')
            print(f'Job status: {status}')

            # Wait for a certain interval before polling again
            time.sleep(5)  # Polling every 5 seconds

        # Handle the final status
        if status == 'success':
            print('Job succeeded!')
            # Assuming the images or asset IDs are in job_data['metadata']['assetIds']
            images = job_data.get('metadata', {}).get('assetIds', [])
            print('Generated Images:', images)
        else:
            print('Job failed!')
            print('Job Data:', job_data)

    # Start polling the job status
    poll_job_status(job_id)
else:
    print(f'Error: {response.status_code}')
    print(response.json())  # Print error details if the POST request failed

Node.js

const fetch = require('node-fetch');
const base64 = require('base-64');

// Set the base URL and model ID
const baseUrl = 'https://api.cloud.scenario.com/v1';
const modelId = 'NKStdSjYQjaeFiTK9ps8dg'; // It's one of our signature public models

// Set the authentication header
const key = 'your_key';
const secret = 'your_secret';
const authHeader = 'Basic ' + base64.encode(`${key}:${secret}`);
const headers = {
  'accept': 'application/json',
  'Authorization': authHeader
};

// Make a POST request to create a job
fetch(`${baseUrl}/generate/txt2img`, {
  method: 'POST',
  headers: {
    ...headers,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    modelId: modelId,
    prompt: 'close up portrait of a sci-fi character in red armor with cyber helmet, lights on cyber mask, full armor, insulated armor, angry, active pose, strong warrior, weapon, optimus prime style, bald head, lots of fine detail, sci-fi dark movie style, background: spaceship, photography, natural light, photorealism, cinematic rendering, ray tracing, highest quality, highest detail',
    numInferenceSteps: 28,
    numSamples: 2,
    guidance: 3.5,
    width: 1024,
    height: 1024,
  })
})
.then(response => {
  if (response.ok) {
    return response.json();
  } else {
    throw new Error(`Error: ${response.status}`);
  }
})
.then(data => {
  console.log('Job Created:', data);
  const jobId = data.job.jobId;

  if (!jobId) {
    throw new Error('Error: Job ID not found in the response.');
  }

  // Function to poll the job status
  const pollJobStatus = async () => {
    let status = '';
    let jobDetails;
    while (status !== 'success' && status !== 'failure') {
      try {
        // Fetch the job details
        const jobResponse = await fetch(`${baseUrl}/jobs/${jobId}`, {
          method: 'GET',
          headers
        });
        jobDetails = await jobResponse.json();
        status = jobDetails.status;
        console.log(`Job status: ${status}`);
      } catch (error) {
        console.error('Error fetching job status:', error);
        break;
      }

      // Wait for a certain interval before polling again
      await new Promise(resolve => setTimeout(resolve, 5000)); // Polling every 5 seconds
    }

    // Handle the final status
    if (status === 'success') {
      console.log('Job succeeded!');
      console.log('Job Details:', jobDetails);
    } else {
      console.log('Job failed!');
      console.log('Job Details:', jobDetails);
    }
  };

  // Start polling the job status
  pollJobStatus();
})
.catch(error => {
  console.error(error);
});