AI Art API Documentation

Leverage our powerful AI image generation API to create stunning AI art programmatically. Simple REST API calls to generate images from text prompts or transform existing images.

Advertise here
Advertise here

Important Notice

Our Image Generation APIs are currently not rate-limited and don't require API keys. However, we may implement rate limits in the future if we notice that the API is being abused or if the server becomes overloaded.

In such a case, free users would still be able to increase their limits by watching ads. While the API may be rate-limited in the future, we will always try our best to keep image generation free and unlimited for users generating images directly through the website UI.

API Overview

Our REST API allows you to generate AI images programmatically with the same powerful image generation capabilities available through our web interface. The API currently supports two main operations:

  • Text to Image: Generate high-quality images from detailed text descriptions using advanced AI models
  • Image to Image: Transform existing images using text prompts to guide the AI's modifications

Base URL

All API endpoints described in this documentation are relative to the following base URL:

https://aiart-zroo.onrender.com

Response Format

All API endpoints return responses in JSON format with HTTP status codes indicating success or failure. Successful responses include a success: true field, while error responses include an error message field.

Image URL Lifecycle

Images generated through the API are hosted on our servers and will remain accessible through the returned URLs for a reasonable period. For long-term storage, we recommend downloading and storing the images on your own servers.

Authentication

Currently, our API endpoints are publicly accessible without authentication requirements. However, to prevent abuse, we may implement authentication in the future.

Future Authentication

When authentication is implemented, it will likely use API keys that can be obtained from your dashboard after creating an account. We will provide ample notice before requiring authentication.

Request Tracking

While authentication is not required, we do track request patterns to prevent abuse. Excessive or suspicious usage patterns may result in temporary IP-based rate limiting.

Text to Image API

POST /api/generate

Generate an AI image based on a detailed text description. This endpoint uses state-of-the-art image generation models to create high-quality, customizable images.

Request Parameters

Send a JSON object with the following parameters in the request body:

Parameter Type Required Description
video_description string Yes Text description of the image you want to generate. The more detailed your description, the better the results. Try to include visual elements, style, mood, and composition details.
negative_prompt string No Text describing what you don't want in the image. For example: "blurry, distorted, low quality, pixelated, watermarks".
style_preset string No Style preset to influence the visual aesthetic of the generated image. Available options include: "3d-model", "analog-film", "anime", "cinematic", "digital-art", "enhance", "fantasy-art", "isometric", "line-art", "low-poly", "modeling-compound", "neon-punk", "origami", "photographic", "pixel-art", "tile-texture".
aspect_ratio string No Aspect ratio of the generated image. Default: "16:9". Available options: "1:1" (square), "4:3" (standard), "16:9" (widescreen), "9:16" (portrait), "3:4" (vertical).
output_format string No Image format to generate. Default: "png". Available options: "png", "jpg", "webp".
seed integer No Seed for reproducible image generation. Use a specific number for consistent results, or 0 for random generation (default). Using the same seed with identical parameters will produce similar images.

Example Requests

cURL
Python
JavaScript
curl -X POST https://aiart-zroo.onrender.com/api/generate \
  -H "Content-Type: application/json" \
  -d '{
    "video_description": "A futuristic city skyline at sunset, with flying cars and neon holographic billboards, cyberpunk style",
    "negative_prompt": "blurry, low quality, distorted faces, poor lighting",
    "style_preset": "neon-punk",
    "aspect_ratio": "16:9",
    "output_format": "png",
    "seed": 0
  }'
import requests
import json

url = "https://aiart-zroo.onrender.com/api/generate"
payload = {
    "video_description": "A futuristic city skyline at sunset, with flying cars and neon holographic billboards, cyberpunk style",
    "negative_prompt": "blurry, low quality, distorted faces, poor lighting",
    "style_preset": "neon-punk",
    "aspect_ratio": "16:9",
    "output_format": "png",
    "seed": 0
}

headers = {"Content-Type": "application/json"}
response = requests.post(url, headers=headers, json=payload)

if response.status_code == 200:
    result = response.json()
    print(f"Image URL: {result['image_url']}")
    # Download the image if needed
    # image_data = requests.get(result['image_url']).content
    # with open('generated_image.png', 'wb') as f:
    #     f.write(image_data)
else:
    print(f"Error: {response.text}")
const generateImage = async () => {
  const url = 'https://aiart-zroo.onrender.com/api/generate';
  const payload = {
    video_description: "A futuristic city skyline at sunset, with flying cars and neon holographic billboards, cyberpunk style",
    negative_prompt: "blurry, low quality, distorted faces, poor lighting",
    style_preset: "neon-punk",
    aspect_ratio: "16:9",
    output_format: "png",
    seed: 0
  };

  try {
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(payload)
    });
    
    const result = await response.json();
    if (response.ok) {
      // Display the image if needed
      // const img = document.createElement('img');
      // img.src = result.image_url;
      // document.body.appendChild(img);
    } else {
      console.error('Error:', result.error);
    }
  } catch (error) {
    console.error('Request failed:', error);
  }
};

Response

The API returns a JSON object with the following properties:

{
  "success": true,
  "message": "Image generated successfully",
  "image_url": "https://aiart-zroo.onrender.com/images/generated_image_123456.png"
}

Advanced Usage Tips

  • Detailed Prompts: For best results, provide detailed descriptions with specific visual elements, styles, and composition details.
  • Negative Prompting: Use negative prompts to avoid unwanted elements or styles in your generated images.
  • Style Consistency: Use the same seed value to create variations of an image while maintaining a similar style and composition.
  • Resolution Control: Different aspect ratios result in different resolutions. Choose the appropriate aspect ratio for your use case.

Imagen 4 Text to Image API

Model Switching: Stable Diffusion 3.5 Ultra & Imagen 4

Exciting Update! You can now seamlessly switch between Stable Diffusion 3.5 Ultra and Imagen 4 models directly on the Text-to-Image page. Simply select Imagen 4 from the Select Model dropdown before generating your next masterpiece.

Experience Imagen 4 Now

Powered by GhostAPI:

Imagen 4 is integrated via GhostAPI. For direct API usage, visit https://api.infip.pro/docs.
AiArt is not responsible for the content or services available on external sites. All rights for GhostAPI belong to its respective owner.

Image to Image API

POST /api/img2img

Transform an existing image based on a text prompt. This endpoint allows you to start with a base image and guide the AI to modify it according to your text description.

Request Parameters

Send a multipart/form-data request with the following parameters:

Parameter Type Required Description
image file Yes The image file to transform. Supported formats: JPG, PNG, WEBP. Maximum file size: 10MB. For best results, use images with clear subjects and good lighting.
prompt string Yes Text prompt describing how you want the image to be transformed. Be specific about the changes you want to see in the final image.
negative_prompt string No Text describing what you don't want in the transformed image. For example: "blurry, distorted, low quality".
strength float No How much to transform the image, ranging from 0.0 to 1.0. Lower values preserve more of the original image, while higher values apply more changes based on the prompt. Default: 0.7
style_preset string No Style preset to influence the aesthetic of the transformation. Same options as the Text to Image API: "3d-model", "analog-film", "anime", "cinematic", "digital-art", "enhance", "fantasy-art", "isometric", "line-art", "low-poly", "modeling-compound", "neon-punk", "origami", "photographic", "pixel-art", "tile-texture"
aspect_ratio string No Aspect ratio of the output image. Default: "1:1". Available options: "1:1", "4:3", "16:9", "9:16", "3:4".
output_format string No Image format of the output. Default: "png". Available options: "png", "jpg", "webp".
seed integer No Seed for reproducible image transformation. Use a specific number for consistent results across multiple transformations, or 0 for random generation (default).

Example Requests

cURL
Python
JavaScript
curl -X POST https://aiart-zroo.onrender.com/api/img2img \
  -F "image=@/path/to/your/image.jpg" \
  -F "prompt=Transform this into a watercolor painting with vibrant colors and detailed brushstrokes" \
  -F "negative_prompt=blurry, low quality, distorted" \
  -F "strength=0.8" \
  -F "style_preset=cinematic" \
  -F "aspect_ratio=1:1" \
  -F "output_format=png" \
  -F "seed=0"
import requests

url = "https://aiart-zroo.onrender.com/api/img2img"

# Open the image file
with open('/path/to/your/image.jpg', 'rb') as img_file:
    files = {
        'image': ('image.jpg', img_file, 'image/jpeg')
    }
    
    data = {
        'prompt': 'Transform this into a watercolor painting with vibrant colors and detailed brushstrokes',
        'negative_prompt': 'blurry, low quality, distorted',
        'strength': '0.8',
        'style_preset': 'cinematic',
        'aspect_ratio': '1:1',
        'output_format': 'png',
        'seed': '0'
    }
    
    response = requests.post(url, files=files, data=data)
    
    if response.status_code == 200:
        result = response.json()
        print(f"Transformed image URL: {result['image_url']}")
        print(f"Seed used: {result['seed']}")
        
        # Download the transformed image
        # image_data = requests.get(result['image_url']).content
        # with open('transformed_image.png', 'wb') as f:
        #     f.write(image_data)
    else:
        print(f"Error: {response.text}")
const transformImage = async (imageFile) => {
  const url = 'https://aiart-zroo.onrender.com/api/img2img';
  
  const formData = new FormData();
  formData.append('image', imageFile);
  formData.append('prompt', 'Transform this into a watercolor painting with vibrant colors and detailed brushstrokes');
  formData.append('negative_prompt', 'blurry, low quality, distorted');
  formData.append('strength', '0.7');
  formData.append('style_preset', 'cinematic');
  formData.append('aspect_ratio', '1:1');
  formData.append('output_format', 'png');
  formData.append('seed', '0');

  try {
    const response = await fetch(url, {
      method: 'POST',
      body: formData
    });
    
    const result = await response.json();
    if (response.ok) {
      // Display the transformed image
      // const img = document.createElement('img');
      // img.src = result.image_url;
      // document.body.appendChild(img);
    }
  } catch (error) {
  }
};
      // img.src = result.image_url;
      // document.body.appendChild(img);
    }
  } catch (error) {
  }
};

// Example usage with a file input element
// document.getElementById('imageInput').addEventListener('change', (e) => {
//   if (e.target.files.length > 0) {
//     transformImage(e.target.files[0]);
//   }
// });

Response

The API returns a JSON object with the following properties:

{
  "success": true,
  "message": "Image transformed successfully",
  "image_url": "https://aiart-zroo.onrender.com/processed_images/img2img_transform_123456.png",
  "seed": 123456
}

Best Practices

  • Image Quality: Upload clear, high-quality images for best results. Low-resolution or blurry images may result in poor transformations.
  • Strength Parameter: Adjust the strength parameter to control how much the original image is modified. Values close to 0.0 will result in subtle changes, while values close to 1.0 will result in significant transformations.
  • Specific Prompts: Be specific about what aspects of the image you want to change or preserve.
  • Preserving Content: To preserve specific elements from the original image, mention them explicitly in your prompt.
  • Style Experiments: Try different style_preset values to achieve different artistic effects. Style presets can dramatically change the appearance of the final image.

Image to Video API

POST /api/img2video

Generate a short video from a single image using Stability AI's video diffusion model. This endpoint initiates the asynchronous video generation process.

Request Parameters

Send a multipart/form-data request with the following parameters:

Parameter Type Required Description
image File Yes The source image to animate into a video
seed Integer No Seed for generation randomness (0 = random) - Default: 0
cfg_scale Float No How strongly the video adheres to the input image (0-10) - Default: 1.5
motion_bucket_id Integer No Controls amount of motion in video (1-255) - Default: 127

Response

The response will be a JSON object with the following structure:

Success (200 OK)
{
  "success": true,
  "id": "a1b2c3d4e5f6...", // The generation ID to use for polling
  "message": "Video generation started. Poll for results using the returned ID."
}
                            
Error (400/500)
{
  "error": "Error message details"
}
                            

Poll for Results

Since video generation is an asynchronous process, you need to poll for results using the generation ID.

GET /api/img2video/result/{id}

Path Parameters

Parameter Description
id The generation ID returned from the initial request

Response

The response will depend on the status of the generation:

In Progress (202 Accepted)
{
  "status": "in-progress",
  "message": "Video generation is still in progress. Try again in a few seconds."
}
                            
Complete (200 OK)
{
  "status": "complete",
  "video_url": "/processed_videos/video_a1b2c3d4_12345.mp4", // URL to access the video
  "finish_reason": "SUCCESS",
  "seed": "12345"
}
                            

Example Usage

Python
JavaScript
import requests
import time
import os

# API endpoint to start generation
upload_url = "https://aiart-zroo.onrender.com/api/img2video"

# Path to image file
image_path = "path/to/your/image.jpg"

# Optional parameters
params = {
    "seed": 0,  # random seed
    "cfg_scale": 1.5,  # default value
    "motion_bucket_id": 127  # default value
}

# Prepare the file for upload
files = {
    "image": (os.path.basename(image_path), open(image_path, "rb"))
}

# Start generation
response = requests.post(upload_url, files=files, data=params)
generation_data = response.json()

if not response.ok:
    print(f"Error starting generation: {generation_data.get('error')}")
    exit(1)

# Get the generation ID
generation_id = generation_data["id"]
print(f"Generation started with ID: {generation_id}")

# Poll for results
result_url = f"https://aiart-zroo.onrender.com/api/img2video/result/{generation_id}"

# Poll every 5 seconds for up to 10 minutes
max_attempts = 120
for attempt in range(max_attempts):
    print(f"Checking status... (attempt {attempt+1}/{max_attempts})")
    response = requests.get(result_url)
    
    if response.status_code == 202:
        # Still in progress
        time.sleep(5)
        continue
    
    if response.status_code == 200:
        # Complete
        result = response.json()
        print(f"Video generation complete!")
        print(f"Video URL: https://aiart-zroo.onrender.com{result['video_url']}")
        print(f"Finish reason: {result['finish_reason']}")
        print(f"Seed: {result['seed']}")
        break
    
    # Error
    print(f"Error checking status: {response.text}")
    break
else:
    print("Generation timed out after 10 minutes")
async function generateVideo() {
  const imageInput = document.getElementById('imageInput');
  const statusDiv = document.getElementById('status');
  
  if (!imageInput.files.length) {
    statusDiv.innerHTML = 'Please select an image file';
    return;
  }
  
  // Create form data
  const formData = new FormData();
  formData.append('image', imageInput.files[0]);
  formData.append('seed', 0); // Use random seed
  formData.append('cfg_scale', 1.5); // Default value
  formData.append('motion_bucket_id', 127); // Default value
  
  statusDiv.innerHTML = 'Starting video generation...';
  
  try {
    // Start generation
    const response = await fetch('/api/img2video', {
      method: 'POST',
      body: formData
    });
    
    if (!response.ok) {
      const error = await response.json();
      throw new Error(error.error || 'Unknown error');
    }
    
    const data = await response.json();
    const generationId = data.id;
    
    statusDiv.innerHTML = `Generation started with ID: ${generationId}
Polling for results...`; // Poll for results const maxAttempts = 120; // 10 minutes at 5-second intervals for (let attempt = 0; attempt < maxAttempts; attempt++) { // Wait 5 seconds between checks await new Promise(resolve => setTimeout(resolve, 5000)); statusDiv.innerHTML = `Checking status... (attempt ${attempt+1}/${maxAttempts})`; const resultResponse = await fetch(`/api/img2video/result/${generationId}`); if (resultResponse.status === 202) { // Still in progress continue; } if (resultResponse.status === 200) { // Complete const result = await resultResponse.json(); statusDiv.innerHTML = `

Video generation complete!

Finish reason: ${result.finish_reason}

Seed: ${result.seed}

`; break; } // Error const error = await resultResponse.json(); throw new Error(error.error || 'Unknown error'); } } catch (error) { statusDiv.innerHTML = `Error: ${error.message}`; } }

Parameters Explanation

cfg_scale

Controls how strictly the video adheres to the input image. Lower values (closer to 0) give the model more freedom, potentially creating more dramatic motion but possibly less faithful to the original image. Higher values (up to 10) force the video to stay closer to the input image in terms of content and composition.

Default: 1.5

motion_bucket_id

Controls the intensity of motion in the generated video. Lower values (closer to 1) result in subtle, minimal movement. Higher values (up to 255) create more dramatic, exaggerated motion throughout the video.

Default: 127

seed

Controls the randomness of the generation. Using the same seed with the same input image and parameters will produce similar (though not necessarily identical) results. Use 0 for a random seed each time, or specify a specific value for more reproducible results.

Default: 0 (random)

Notes

  • The generated videos are typically a few seconds long
  • Results are stored for 24 hours before being automatically deleted
  • Each successful generation costs 20 credits
  • Generation typically takes between 10-30 seconds depending on server load
  • Maximum file size for input images is 10MB
  • Supported image formats: JPEG and PNG
  • Supported image dimensions: 1024x576, 576x1024, 768x768 pixels

Error Handling

When an error occurs, the API returns a JSON object with an error message and an appropriate HTTP status code. We recommend implementing proper error handling in your applications to gracefully handle these scenarios.

{
  "error": "Error message describing what went wrong"
}

Common Error Status Codes

Status Code Description Common Causes Recommended Action
400 Bad Request Missing required parameters, invalid input format, or unsupported values Check your request parameters and ensure they match the API specifications
401 Unauthorized Authentication failure (currently not implemented, but may be added in the future) Ensure your API key or credentials are valid
404 Not Found The requested resource or endpoint does not exist Verify the API endpoint URL is correct
413 Payload Too Large Uploaded file is too large Ensure your image file is under the maximum size limit (10MB)
415 Unsupported Media Type Uploaded file format is not supported Use supported image formats: JPG, PNG, WEBP
429 Too Many Requests Rate limit exceeded Implement backoff and retry strategies in your client
500 Internal Server Error Something went wrong on the server Retry the request later or contact support if the issue persists

Error Handling Examples

Python
JavaScript
import requests
import time

def generate_image_with_retry(prompt, max_retries=3, backoff_factor=2):
    url = "https://aiart-zroo.onrender.com/api/generate"
    payload = {"video_description": prompt}
    headers = {"Content-Type": "application/json"}
    
    for attempt in range(max_retries):
        try:
            response = requests.post(url, headers=headers, json=payload)
            
            # Success case
            if response.status_code == 200:
                return response.json()
                
            # Rate limiting case
            elif response.status_code == 429:
                retry_after = int(response.headers.get('Retry-After', backoff_factor * (2 ** attempt)))
                print(f"Rate limited. Retrying after {retry_after} seconds.")
                time.sleep(retry_after)
                continue
                
            # Server error case
            elif response.status_code >= 500:
                wait_time = backoff_factor * (2 ** attempt)
                print(f"Server error. Retrying after {wait_time} seconds.")
                time.sleep(wait_time)
                continue
                
            # Other errors - fail immediately
            else:
                error_data = response.json()
                print(f"API Error: {error_data.get('error', 'Unknown error')}")
                return error_data
                
        except Exception as e:
            print(f"Request failed: {str(e)}")
            wait_time = backoff_factor * (2 ** attempt)
            time.sleep(wait_time)
    
    return {"error": "Max retries exceeded"}
async function generateImageWithRetry(prompt, maxRetries = 3, backoffFactor = 2) {
  const url = 'https://aiart-zroo.onrender.com/api/generate';
  const payload = { video_description: prompt };
  
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      const response = await fetch(url, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload)
      });
      
      // Parse JSON response even in error cases
      const data = await response.json();
      
      // Success case
      if (response.ok) {
        return data;
      }
      
      // Rate limiting case
      if (response.status === 429) {
        const retryAfter = parseInt(response.headers.get('Retry-After') || backoffFactor * (2 ** attempt));
        console.log(`Rate limited. Retrying after ${retryAfter} seconds.`);
        await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
        continue;
      }
      
      // Server error case
      if (response.status >= 500) {
        const waitTime = backoffFactor * (2 ** attempt);
        console.log(`Server error. Retrying after ${waitTime} seconds.`);
        await new Promise(resolve => setTimeout(resolve, waitTime * 1000));
        continue;
      }
      
      // Other errors - fail immediately
      console.error(`API Error: ${data.error || 'Unknown error'}`);
      return data;
      
    } catch (error) {
      console.error(`Request failed: ${error.message}`);
      const waitTime = backoffFactor * (2 ** attempt);
      await new Promise(resolve => setTimeout(resolve, waitTime * 1000));
    }
  }
  
  return { error: 'Max retries exceeded' };
}

Rate Limits

Currently, our API endpoints don't have strict rate limits imposed. However, we monitor usage patterns and may implement rate limiting in the future to ensure fair usage and service stability for all users.

Future Rate Limiting

When rate limits are implemented, requests exceeding the limit will receive a 429 (Too Many Requests) response with a Retry-After header indicating when you can resume making requests. Free users will be able to increase their limits by watching ads through our web interface.

Best Practices

To ensure the best experience with our API, we recommend the following practices:

  • Implement Caching: Cache generated images when possible to avoid redundant API calls.
  • Add Retry Logic: Implement exponential backoff and retry strategies to handle rate limiting and temporary service disruptions.
  • Batch Requests: If you need to generate multiple images, stagger your requests over time rather than sending them all at once.
  • Process During Off-peak Hours: Schedule bulk processing during off-peak hours when possible.

By following these guidelines, you help us maintain a reliable service for everyone while maximizing the effectiveness of your API usage.