Back to Docs

Pixel Factory

New

Image and video generation API powered by NVIDIA RTX PRO 6000 Blackwell GPUs

Pixel Factory - Image & Video Generation API

OpenAI-compatible image and video generation API with 14 models covering image generation, video generation, image-to-video, and upscaling — all running on NVIDIA RTX PRO 6000 Blackwell GPUs (96GB GDDR7).

What is Pixel Factory?

Pixel Factory is the platform's managed image and video generation service. Instead of provisioning your own GPU instance and running diffusion models, you pay per generation and we handle the infrastructure. Use the dashboard playground for interactive exploration or the programmatic API for production workloads. Pricing starts at $0.0005 per image.

Table of Contents

Overview

Pixel Factory provides:

  • OpenAI-compatible endpoint — drop-in replacement for the OpenAI images API, works with the official Python and Node SDKs
  • 14 models covering text-to-image, text-to-video, image-to-video, and 4x upscaling
  • Pay-per-generation pricing starting at $0.0005 per image (FLUX.1 Schnell)
  • Dashboard playground with model selection, advanced settings, preset aspect ratios, gallery, and download
  • Programmatic API for production integration
  • All inference runs on NVIDIA RTX PRO 6000 Blackwell GPUs with 96GB GDDR7

Authentication

All generation requests require an API key. Get your key from Dashboard → API Keys. Keys are prefixed with pk-.

Using Your API Key

# Include in Authorization header
Authorization: Bearer pk-your-api-key

The List Models endpoint (GET /api/v1/images/models) is public and does not require authentication.

API Endpoints

Base URL

https://YOUR_DASHBOARD_URL/api/v1

Endpoints Summary

EndpointMethodAuthDescription
/images/generationsPOSTRequiredGenerate images or videos
/images/modelsGETNoneList available models (public, CORS enabled)

POST /images/generations

Generate images or videos from a text prompt. Supports text-to-image, text-to-video, image-to-video, and upscaling depending on the model.

Request Body

{
  "model": "flux-1-schnell",     // Optional, defaults to flux-1-schnell
  "prompt": "A mountain at sunset", // Required
  "negative_prompt": "blurry",    // Optional
  "n": 1,                         // 1-4 images per request
  "size": "1024x1024",           // WIDTHxHEIGHT, multiples of 8
  "response_format": "b64_json", // "b64_json" or "url"
  "steps": 4,                    // Override default inference steps
  "cfg_scale": 1.0,              // Override default CFG scale
  "seed": 12345,                 // Optional for reproducibility
  "num_frames": 81,              // Video only: number of frames
  "fps": 16,                     // Video only: frame rate
  "image": "base64..."           // Required for i2v and upscale models
}

Response

{
  "created": 1708976543,
  "data": [
    { "b64_json": "iVBOR..." }
  ],
  "usage": {
    "model": "flux-1-schnell",
    "size": "1024x1024",
    "n": 1,
    "steps": 4,
    "duration_ms": 1250,
    "cost_cents": 5
  }
}

When response_format is "url", the data array contains objects with a url field instead of b64_json. URLs are temporary and expire after a short period.

Error Responses

HTTP StatusDescription
400Invalid request — bad parameters, missing prompt, invalid dimensions
401Missing or invalid API key
402Insufficient wallet balance (response includes current balance info)
500Generation failed on the server
503No GPU servers available

GET /images/models

List all available image and video generation models. This is a public endpoint — no authentication required. CORS headers are included for browser-based requests.

Response

{
  "object": "list",
  "data": [
    {
      "id": "flux-1-schnell",
      "object": "model",
      "created": 1708976543,
      "owned_by": "black-forest-labs",
      "type": "image",
      "display_name": "FLUX.1 Schnell",
      "architecture": "flux",
      "max_resolution": "2048x2048",
      "default_steps": 4,
      "default_cfg": 1.0,
      "price_per_image_cents": 0.05,
      "featured": true
    }
  ]
}

Model Object Fields

FieldTypeDescription
idstringModel identifier to use in generation requests
typestring"image", "video", "i2v", or "upscale"
display_namestringHuman-readable model name
owned_bystringModel provider
architecturestringUnderlying model architecture
max_resolutionstringMaximum supported output resolution
default_stepsintegerDefault number of inference steps
default_cfgnumberDefault classifier-free guidance scale
price_per_image_centsnumberBase price in cents at 1024x1024
featuredbooleanWhether the model is featured/recommended

Available Models

Image Generation Models

Model IDProviderDefault StepsMax ResolutionPrice/ImageSpeed
flux-1-schnellBlack Forest Labs42048x2048$0.0005~1-2s
flux-1-devBlack Forest Labs202048x2048$0.0032~8-12s
flux-2-devBlack Forest Labs302048x2048$0.0060~15-20s
sdxl-1.0Stability AI302048x2048$0.0022~10-15s

Upscaling Model

Model IDProviderDefault StepsMax ResolutionPrice/ImageSpeed
4x-ultrasharpCommunity18192x8192$0.0010~3-5s

The 4x-ultrasharp model upscales an input image by 4x. Provide the source image via the image parameter (base64-encoded). The prompt parameter is not used for upscaling but must still be included (use an empty string).

Text-to-Video Models

Model IDProviderDefault StepsResolutionPrice/VideoSpeed
wan2.1-t2v-fastWan AI20480p$0.0050~15s
wan2.1-t2v-proWan AI30480p$0.0150~60s
wan2.2-t2v-14bWan AI30720p$0.0200~180s
ltx2-t2vLightricks30720p$0.0080~30s
cogvideox-1.5-5bTHUDM50768p$0.0100~90s
hunyuan-video-720pTencent30720p$0.0200~120s

Image-to-Video Models

Model IDProviderResolutionPrice/Video
wan2.1-i2v-480pWan AI480p$0.0200
wan2.1-i2v-720pWan AI720p$0.0300
wan2.2-i2v-14bWan AI720p$0.0300

Image-to-video models require the image parameter containing a base64-encoded start frame. The prompt describes the desired motion or animation.

Code Examples

Python (OpenAI SDK)

The Pixel Factory API is compatible with the official OpenAI Python SDK. Point it at your platform base URL and use your API key.

from openai import OpenAI
import base64

client = OpenAI(
    base_url="https://YOUR_DASHBOARD_URL/api/v1",
    api_key="pk-your-api-key"
)

response = client.images.generate(
    model="flux-1-schnell",
    prompt="A serene mountain landscape at golden hour",
    n=1,
    size="1024x1024",
    response_format="b64_json"
)

# Decode and save the image
image_data = base64.b64decode(response.data[0].b64_json)
with open("output.png", "wb") as f:
    f.write(image_data)

print(f"Image saved to output.png")

cURL

curl -X POST https://YOUR_DASHBOARD_URL/api/v1/images/generations \
  -H "Authorization: Bearer pk-your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "flux-1-schnell",
    "prompt": "Cyberpunk city street with neon lights",
    "size": "1344x768",
    "n": 1
  }'

JavaScript / TypeScript

const response = await fetch("https://YOUR_DASHBOARD_URL/api/v1/images/generations", {
  method: "POST",
  headers: {
    "Authorization": "Bearer pk-your-api-key",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    model: "flux-1-dev",
    prompt: "A photorealistic portrait in dramatic lighting",
    size: "1024x1024",
    n: 1
  })
});

const result = await response.json();
const imageBase64 = result.data[0].b64_json;

// Display in browser
const img = document.createElement("img");
img.src = `data:image/png;base64,${imageBase64}`;
document.body.appendChild(img);

JavaScript (Node.js — Save to File)

import fs from "fs";

const response = await fetch("https://YOUR_DASHBOARD_URL/api/v1/images/generations", {
  method: "POST",
  headers: {
    "Authorization": "Bearer pk-your-api-key",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    model: "flux-1-schnell",
    prompt: "A futuristic space station orbiting Earth",
    size: "1024x1024",
    n: 1
  })
});

const result = await response.json();
const buffer = Buffer.from(result.data[0].b64_json, "base64");
fs.writeFileSync("output.png", buffer);
console.log("Saved to output.png");

Text-to-Video Generation

curl -X POST https://YOUR_DASHBOARD_URL/api/v1/images/generations \
  -H "Authorization: Bearer pk-your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "wan2.1-t2v-fast",
    "prompt": "A butterfly emerging from a cocoon, macro photography",
    "num_frames": 81,
    "fps": 16
  }'

Text-to-Video (Python)

import base64

response = client.images.generate(
    model="wan2.1-t2v-fast",
    prompt="Ocean waves crashing on a rocky shore, cinematic",
    extra_body={
        "num_frames": 81,
        "fps": 16
    }
)

# The response contains a base64-encoded video (mp4)
video_data = base64.b64decode(response.data[0].b64_json)
with open("output.mp4", "wb") as f:
    f.write(video_data)

print("Video saved to output.mp4")

Image-to-Video

Animate a still image into a video. Provide the start frame as a base64-encoded image via the image parameter, and describe the desired motion in the prompt.

import base64

# Read your start image
with open("start_frame.png", "rb") as f:
    image_b64 = base64.b64encode(f.read()).decode()

response = client.images.generate(
    model="wan2.1-i2v-480p",
    prompt="Camera slowly zooms in, subtle motion",
    extra_body={
        "image": image_b64,
        "num_frames": 81,
        "fps": 16
    }
)

# Save the generated video
video_data = base64.b64decode(response.data[0].b64_json)
with open("animated.mp4", "wb") as f:
    f.write(video_data)

Image-to-Video (cURL)

# First, base64-encode your image
IMAGE_B64=$(base64 -i start_frame.png)

curl -X POST https://YOUR_DASHBOARD_URL/api/v1/images/generations \
  -H "Authorization: Bearer pk-your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "wan2.1-i2v-720p",
    "prompt": "Gentle wind blows through the scene",
    "image": "'$IMAGE_B64'",
    "num_frames": 81,
    "fps": 16
  }'

4x Upscaling

Upscale a low-resolution image by 4x using the 4x-ultrasharp model. The prompt field is not used for upscaling but must be included.

import base64

# Read the low-resolution image
with open("low_res.png", "rb") as f:
    image_b64 = base64.b64encode(f.read()).decode()

response = client.images.generate(
    model="4x-ultrasharp",
    prompt="",  # Not used for upscaling
    extra_body={"image": image_b64}
)

# Save the upscaled image
upscaled_data = base64.b64decode(response.data[0].b64_json)
with open("upscaled.png", "wb") as f:
    f.write(upscaled_data)

print("Upscaled image saved to upscaled.png")

Upscaling (cURL)

IMAGE_B64=$(base64 -i low_res.png)

curl -X POST https://YOUR_DASHBOARD_URL/api/v1/images/generations \
  -H "Authorization: Bearer pk-your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "4x-ultrasharp",
    "prompt": "",
    "image": "'$IMAGE_B64'"
  }'

Batch Generation (Multiple Images)

Generate up to 4 images in a single request using the n parameter. All images are generated from the same prompt and settings.

import base64

response = client.images.generate(
    model="flux-1-schnell",
    prompt="Abstract geometric patterns in vibrant colors",
    n=4,
    size="1024x1024",
    response_format="b64_json"
)

# Save all generated images
for i, image in enumerate(response.data):
    image_data = base64.b64decode(image.b64_json)
    with open(f"output_{i}.png", "wb") as f:
        f.write(image_data)

print(f"Saved {len(response.data)} images")

Reproducible Results with Seeds

# Generate the same image twice using a fixed seed
response1 = client.images.generate(
    model="flux-1-dev",
    prompt="A red fox in a snowy forest",
    size="1024x1024",
    extra_body={"seed": 42}
)

response2 = client.images.generate(
    model="flux-1-dev",
    prompt="A red fox in a snowy forest",
    size="1024x1024",
    extra_body={"seed": 42}
)

# Both responses will produce identical images

Request Parameters Reference

All Parameters

ParameterTypeDefaultDescription
modelstring"flux-1-schnell"Model to use for generation. See Available Models for the full list.
promptstringrequiredText description of the desired output. For upscaling, pass an empty string.
negative_promptstring""What to avoid in the generation (e.g., "blurry, low quality, artifacts").
ninteger1Number of images to generate (1-4). Videos are always 1 per request.
sizestring"1024x1024"Output dimensions as WIDTHxHEIGHT. Both values must be multiples of 8.
stepsintegermodel defaultNumber of inference/denoising steps. Higher values generally produce better quality but take longer.
cfg_scalenumbermodel defaultClassifier-free guidance scale. Higher values follow the prompt more closely but can reduce variety.
seedintegerrandomSeed for deterministic/reproducible results. Same seed + same parameters = same output.
response_formatstring"b64_json""b64_json" returns base64-encoded data inline. "url" returns a temporary download URL.
num_framesinteger81Video models only. Number of frames to generate.
fpsinteger16Video models only. Output frame rate.
imagestringBase64-encoded image. Required for image-to-video and upscale models.

Resolution Constraints

  • Both width and height must be multiples of 8
  • Minimum dimension: 256px
  • Maximum dimension: varies per model — most image models support up to 2048x2048, the upscaler supports up to 8192x8192
  • Common aspect ratios: 1024x1024 (1:1), 1344x768 (16:9), 768x1344 (9:16)

Pricing

Pixel Factory uses pay-per-generation pricing. Costs are deducted from your wallet balance after each successful generation.

Pricing Rules

  • Base price is set per model at 1024x1024 resolution (see model tables above)
  • Higher resolutions scale by megapixels: cost × (width × height) / (1024 × 1024)
  • Videos scale by frame count: cost × (num_frames / 81)
  • Multiple images (n > 1) multiply the cost by n
  • Minimum charge: $0.01 per request

Example Cost Calculations

ScenarioCalculationCost
1x FLUX.1 Schnell @ 1024x1024$0.0005 × 1$0.01 (minimum)
4x FLUX.1 Schnell @ 1024x1024$0.0005 × 4 = $0.002$0.01 (minimum)
1x FLUX.1 Dev @ 2048x2048$0.0032 × (2048×2048)/(1024×1024) = $0.0032 × 4$0.0128
1x Wan 2.1 T2V Pro @ 81 frames$0.0150 × (81/81)$0.0150
1x Wan 2.1 T2V Pro @ 162 frames$0.0150 × (162/81) = $0.0150 × 2$0.0300
1x HunyuanVideo 720p @ 81 frames$0.0200 × 1$0.0200

You can check your current wallet balance in the dashboard or via the billing API. The usage object in the generation response includes cost_cents so you can track spend programmatically.

Dashboard Playground

The Pixel Factory playground is available in your dashboard under the Pixel Factory tab. It provides a visual interface for experimenting with all models without writing code.

Features

  • Mode toggle — switch between Image and Video generation modes
  • Model selector — choose from all 14 available models
  • Prompt editor — text area with support for negative prompts
  • Advanced settings — inference steps, CFG scale, negative prompt, and seed
  • Preset aspect ratios — 1:1, 16:9, 9:16 with one click
  • Video controls — frame count and FPS sliders for video models
  • Image upload — drag-and-drop image upload for image-to-video and upscale models
  • Gallery view — all generated images displayed in a grid with lightbox preview
  • Real-time cost estimate — see the estimated cost before generating
  • Download — download individual images and videos directly from the gallery

Error Handling

Error Response Format

{
  "error": {
    "message": "Prompt is required",
    "type": "invalid_request",
    "code": "missing_prompt"
  }
}

Error Codes

HTTP StatusError TypeDescriptionWhat to Do
400invalid_requestBad parameters, missing prompt, invalid dimensionsCheck the request body against the parameter reference
401authentication_errorMissing or invalid API keyVerify your API key starts with pk- and is in the Authorization header
402insufficient_balanceWallet balance is too low for the requested generationAdd funds in Dashboard → Billing. Response includes your current balance.
500generation_failedThe GPU server failed to generate the outputRetry the request. If persistent, try a different model or simplify the prompt.
503service_unavailableNo GPU servers are available to handle the requestWait and retry. This is temporary and typically resolves within seconds.

Python Error Handling Example

from openai import OpenAI, APIError, AuthenticationError
import time

client = OpenAI(
    base_url="https://YOUR_DASHBOARD_URL/api/v1",
    api_key="pk-your-api-key"
)

def generate_with_retry(prompt, model="flux-1-schnell", max_retries=3):
    for attempt in range(max_retries):
        try:
            response = client.images.generate(
                model=model,
                prompt=prompt,
                size="1024x1024",
                n=1
            )
            return response
        except AuthenticationError:
            print("Invalid API key - check your credentials")
            raise
        except APIError as e:
            if e.status_code == 402:
                print("Insufficient balance - add funds at dashboard")
                raise
            elif e.status_code == 503:
                wait = 2 ** attempt
                print(f"Service unavailable, retrying in {wait}s...")
                time.sleep(wait)
            elif e.status_code == 500:
                wait = 2 ** attempt
                print(f"Generation failed, retrying in {wait}s...")
                time.sleep(wait)
            else:
                raise
    raise Exception("Max retries exceeded")

JavaScript Error Handling Example

async function generateImage(prompt, model = "flux-1-schnell", retries = 3) {
  for (let attempt = 0; attempt < retries; attempt++) {
    const response = await fetch("https://YOUR_DASHBOARD_URL/api/v1/images/generations", {
      method: "POST",
      headers: {
        "Authorization": "Bearer pk-your-api-key",
        "Content-Type": "application/json"
      },
      body: JSON.stringify({ model, prompt, size: "1024x1024", n: 1 })
    });

    if (response.ok) {
      return await response.json();
    }

    const error = await response.json();

    if (response.status === 401) {
      throw new Error("Invalid API key");
    }
    if (response.status === 402) {
      throw new Error(`Insufficient balance: ${error.error.message}`);
    }
    if (response.status === 503 || response.status === 500) {
      const wait = Math.pow(2, attempt) * 1000;
      console.log(`Retrying in ${wait}ms...`);
      await new Promise(r => setTimeout(r, wait));
      continue;
    }

    throw new Error(error.error.message);
  }
  throw new Error("Max retries exceeded");
}

Rate Limits & Best Practices

Limits

  • Maximum 4 images per request (set via the n parameter)
  • Videos are always 1 per request
  • Concurrent request limits depend on your account tier

Choosing the Right Model

Model Selection Guide

  • Fast iterations / drafts: Use flux-1-schnell — 1-2 seconds, $0.0005/image
  • Production-quality images: Use flux-1-dev or flux-2-dev for the best results
  • SDXL ecosystem: Use sdxl-1.0 if you need compatibility with SDXL-based workflows
  • Quick video drafts: Start with wan2.1-t2v-fast (~15s, $0.005)
  • Final video quality: Upgrade to wan2.1-t2v-pro or hunyuan-video-720p
  • Upscaling: Use 4x-ultrasharp for 4x resolution increase

Prompt Tips

  • Be specific — detailed prompts produce better results. Include style, lighting, composition, and subject details.
  • Use negative prompts to avoid common artifacts like "blurry, low quality, distorted, watermark, text"
  • Set a seed for reproducible results during development, then remove it for variety in production
  • Iterate quickly with flux-1-schnell to refine your prompt, then switch to a higher-quality model for the final output

Performance Tips

  • Use the default step count unless you have a specific reason to change it — defaults are tuned for optimal quality/speed
  • Smaller resolutions are faster — generate at 1024x1024 and upscale with 4x-ultrasharp if you need high resolution
  • Use response_format: "url" if you only need to download the image later, to reduce response payload size
  • Batch images with n=4 when you want multiple variations — this is more efficient than 4 separate requests

Cost Optimization

  • Start with flux-1-schnell at $0.0005/image for prompt engineering
  • Use 1024x1024 and upscale only when needed
  • For videos, prototype with wan2.1-t2v-fast before committing to more expensive models
  • Monitor spend via the usage.cost_cents field in API responses
  • Set up budget alerts in Dashboard → Billing to avoid surprises

Need Help?

Contact us at our support team via the Support tab — we offer 24/7 support for all customers.