All articles
April 2, 20268 min read·ImageAPI Team

How to Use the FLUX API in Python (Step by Step)

A working Python tutorial for generating AI images with the FLUX API in under five minutes. Covers auth, prompt design, error handling, and saving images to disk.

PythonFLUXTutorials

If you searched for a Python tutorial on the FLUX API, you probably want one that runs the first time you paste it into a file. This is that tutorial. By the end you will have a script that takes a prompt, calls the API, and writes a PNG to your folder. No GPU. No model downloads. No virtual environment headaches.

We will use the standard requests library so you can drop the example into Flask, FastAPI, Django, or a CLI script without changing anything. If you prefer httpx or aiohttp the request shape stays identical.

What you need before starting

  • Python 3.9 or newer.
  • An API key. Create one in the dashboard under API Keys, then keep it out of source control.
  • The requests library. Install with pip install requests.

The smallest working example

Save this as generate.py. Replace the API key with yours and run it. The script writes the result as output.png in the same folder.

import os
import base64
import requests

API_KEY = os.environ["IMAGEAPI_KEY"]
ENDPOINT = "https://api.imageapi.org/api/v1/generate"

payload = {
    "prompt": "a quiet street in kyoto at golden hour, photographic, 35mm",
    "model": "flux-2-klein-9b",
    "width": 1024,
    "height": 1024,
    "num_inference_steps": 30,
}

headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}

resp = requests.post(ENDPOINT, json=payload, headers=headers, timeout=120)
resp.raise_for_status()
body = resp.json()

image_field = body["data"]["image"]

if image_field.startswith("data:"):
    encoded = image_field.split(",", 1)[1]
    raw = base64.b64decode(encoded)
else:
    raw = requests.get(image_field, timeout=60).content

with open("output.png", "wb") as f:
    f.write(raw)

print("Saved output.png")

Picking the right model for your prompt

FLUX 1 Schnell is the fastest. Good for drafts and prototypes. FLUX 2 Klein 9B is the balanced default. It handles portraits, product photos, and most marketing creative without much tuning. FLUX 2 Dev is the slowest and the most accurate. Use it when you want clean text rendering or photoreal portraits.

Pass the model slug in the model field. If you are unsure which to start with, leave it blank and the API will route to a sensible default for your plan.

Writing prompts that actually work

A common mistake is trying to be poetic. The model rewards specificity. Tell it the subject, the setting, the lighting, and the camera. Stop there. Adding ten more adjectives usually makes the result worse.

  • Subject: what is in the frame. A red sports car. A bowl of ramen. A woman wearing a wool coat.
  • Setting: where it is. Wet city street. Wooden table. Snowy field at dusk.
  • Lighting: soft window light. Harsh midday sun. Studio softbox. Neon signage.
  • Camera or style: 35mm film, shallow depth of field. Studio product shot. Watercolor painting.

Handling errors the right way

Production code needs to handle three things. Rate limits, timeouts, and the model returning an unusable image. Do not retry blindly on a 429. Read the Retry-After header and back off.

import time
import requests

def generate_with_retry(payload, headers, max_attempts=3):
    for attempt in range(1, max_attempts + 1):
        resp = requests.post(ENDPOINT, json=payload, headers=headers, timeout=120)
        if resp.status_code == 429:
            wait = int(resp.headers.get("Retry-After", "5"))
            time.sleep(wait)
            continue
        resp.raise_for_status()
        return resp.json()
    raise RuntimeError("All attempts exhausted")

Generating many images in one call

If you need a grid of variations or a small set for an article, send the items array instead of one prompt. Each entry can have its own size and seed. The API runs them in parallel up to your concurrency limit.

payload = {
    "items": [
        {"prompt": "a calico cat on a window sill", "width": 768, "height": 768},
        {"prompt": "a sleeping orange tabby", "width": 768, "height": 768},
        {"prompt": "a black cat reading a book", "width": 768, "height": 768},
    ]
}

Where to go next

Once your script works, point it at the prompt enhancer endpoint to expand short ideas into richer prompts, or wire the result into your CMS. The same auth and JSON shape applies across every endpoint.

Frequently asked questions

Do I need a GPU to use the FLUX API in Python?
No. The model runs on the API side. Your Python script only sends an HTTP request and receives an image. Any laptop or server can run it.
Can I use async Python with this API?
Yes. Replace requests with httpx or aiohttp. The request and response shape are identical. The endpoint accepts standard JSON over HTTPS.
How do I keep my API key safe in a Python project?
Read it from an environment variable, never hardcode it, and add the .env file to .gitignore. For production use a secret manager such as AWS Secrets Manager or Doppler.
What is the maximum image size?
Most models accept 256 to 1024 on each side. FLUX 2 models go up to 1024 by 1024 cleanly. Larger sizes increase generation time and cost.

Try the API used in this article

Free tier, transparent pricing, and a single REST endpoint for FLUX, Stable Diffusion, and Leonardo models.

Related reading