Leonardo AI × Claude
Setup Guide · Workflow 03

LeonardoAI × Claude

Generate images by just asking Claude. Powered by Leonardo's Nano Banana Pro with prompt enhancement always on.

Nano Banana Pro
1024×1024 default
~$0.21 per image

What you need

A Leonardo AI account with API credit — leonardo.ai
Claude Code — so you can generate images by just asking. It handles everything else.

Three steps to get running

Step 01

Create a Leonardo AI account

  1. Go to leonardo.ai and sign up.
  2. Click API in the left sidebar.
  3. Under API Keys, click + Create New Key. Name it anything.
  4. Copy the key. It looks like xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
  5. Go to API Credit → Buy Credit and top up. You need credit before generating.
Each image costs ~$0.21. A $10 top-up gives you ~47 images.
Tip: Enable Automatic Top-Up under API Credit settings. Prevents errors when you run out mid-session.
Step 02

Set up the script

Open Claude Code in your project folder. Send this entire message — replace YOUR_API_KEY with your actual key:

Paste this into Claude Code
Create tools/leonardo.py with this code and set the API key to YOUR_API_KEY:
#!/usr/bin/env python3
import sys, time, json, urllib.request

API_KEY = "PASTE_YOUR_KEY_HERE"
V2_URL  = "https://cloud.leonardo.ai/api/rest/v2"
V1_URL  = "https://cloud.leonardo.ai/api/rest/v1"
MODEL   = "gemini-image-2"        # Nano Banana Pro

HEADERS = {
    "accept": "application/json",
    "content-type": "application/json",
    "authorization": f"Bearer {API_KEY}",
}

def post(base, path, body):
    req = urllib.request.Request(f"{base}{path}", data=json.dumps(body).encode(), headers=HEADERS, method="POST")
    with urllib.request.urlopen(req) as res: return json.loads(res.read())

def get(base, path):
    req = urllib.request.Request(f"{base}{path}", headers=HEADERS)
    with urllib.request.urlopen(req) as res: return json.loads(res.read())

def generate(prompt):
    print(f"Generating: {prompt!r}")
    resp = post(V2_URL, "/generations", {
        "model": MODEL,
        "parameters": {"prompt": prompt, "width": 1024, "height": 1024, "quantity": 1, "prompt_enhance": "ON"},
        "public": False,
    })
    gen_id = resp["generate"]["generationId"]
    cost   = resp["generate"]["cost"]["amount"]
    print(f"Job ID: {gen_id} | Est. cost: ${cost}")
    for _ in range(30):
        time.sleep(5)
        data   = get(V1_URL, f"/generations/{gen_id}")
        status = data["generations_by_pk"]["status"]
        print(f"  status: {status}")
        if status == "COMPLETE":
            return [img["url"] for img in data["generations_by_pk"]["generated_images"]]
        if status == "FAILED":
            raise RuntimeError("Generation failed.")
    raise TimeoutError("Timed out after 150 seconds.")

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print('Usage: python3 tools/leonardo.py "your prompt here"')
        sys.exit(1)
    urls = generate(" ".join(sys.argv[1:]))
    print("\nDone! Image URL(s):")
    for url in urls: print(f"  {url}")

Claude creates the file with your key already set. No manual editing.

Step 03

Tell Claude to always use it

Send Claude this:

Paste this into Claude Code
Add this to my CLAUDE.md: every time I ask to generate an image, use Leonardo AI with Nano Banana Pro by running tools/leonardo.py. Do not use any other tool or rewrite the script.

Claude finds the file and adds the rule. After that, just say "generate an image of a person at a desk" and Claude handles the rest. No terminal, no commands.

Prompt tips

Prompt enhancement is always on. Keep prompts short. Subject + mood + setting is enough. The AI fills in the rest.

Instead of this Write this
"highly detailed cinematic photo of a young Filipino man sitting at a modern dark desk with glowing screens and lime green lighting" "young Filipino man at a dark desk, lime green lighting"
"professional corporate headshot with studio lighting, bokeh background, sharp focus" "professional headshot, studio lighting"
"futuristic AI marketing dashboard on a dark monitor with glowing data visualizations" "marketing dashboard, dark screen, glowing charts"

Sizes

FormatWidthHeight
Square / Instagram (default)10241024
Portrait 4:510241280
Landscape 16:912801024

Change width and height in the script. Or just tell Claude "make this one portrait" and it edits the file.

When to use AI images

Never use AI images for

Troubleshooting

HTTP Error 401

API key is wrong or not copied correctly.

HTTP Error 402

Not enough API credit. Top up at leonardo.ai.

Generation failed

Prompt may have been flagged. Try rewording it.

python3: command not found

Install Python from python.org.

Rule

AI images for mood. Real photos for anything that has to be real.