DocsImages: understand and generate

Images: understand and generate

Use casesIntermediate20 min

You'll get a model to answer questions about photos and screenshots, and to draw pictures from a description once generation is back on.

You need: a fetch_... key (create one), a balance (top up), Python and pip install openai.

1Asking about an image

  1. 1
    Install the SDK

    pip install openai

  2. 2
    Save the code

    Copy the code below into vision.py.

  3. 3
    Ask a question
    bash
    export ZUKKO_API_KEY="fetch_..."
    python vision.py screenshot.png "What does this error mean and how do I fix it?"
    python vision.py https://example.com/photo.jpg "Describe this product for a marketplace listing"

    Pass the image as a file or a public link. The model can't download private or expiring links.

vision.py
import base64
import mimetypes
import os
import sys

from openai import OpenAI

client = OpenAI(
    base_url="https://api.zukko.pro/v1",
    api_key=os.environ["ZUKKO_API_KEY"],
    timeout=120,
)
MODEL = os.environ.get("ZUKKO_MODEL", "claude-haiku-5-5")  # the model must accept images

2Which model to use

The model must accept images — see the "Image input" column in Models & pricing.

ModelInput / output, $ per 1M tokensWhen to use
claude-haiku-5-50.05 / 0.2Receipts, screenshots, simple photos
gpt-6-sol0.13 / 0.63All-rounder
claude-sonnet-50.4 / 2Small print, tables, diagrams
qwen3.8-omni-flash0.03 / 0.08Cheapest

These don't accept images: deepseek-v4.1-flash, gemini-3.8-flash, kimi-k3.1-pro, glm-5.3, gpt-6-luna. Live list: GET /v1/models/info, field supports_vision.

3A receipt into JSON

Put receipt.py next to vision.py and run python receipt.py receipt.jpg. The code checks that the lines add up to the total — review mismatches by hand.

receipt.py
import json
import sys

from vision import client, image_to_data_url

RECEIPT_FORMAT = {
    "type": "json_schema",
    "json_schema": {
        "name": "receipt",
        "strict": True,
        "schema": {
            "type": "object",
            "properties": {
                "store": {"type": "string"},

4In a Telegram bot

Add the handler to the bot from Telegram bot with AI: the user sends a photo with a question in the caption. The model in ZUKKO_MODEL must accept images.

bot.py (add)
import base64


async def on_photo(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    photo = update.message.photo[-1]  # Telegram sends several sizes; take the largest
    file = await photo.get_file()
    data = base64.b64encode(await file.download_as_bytearray()).decode()
    question = update.message.caption or "What is in this picture?"

    response = await client.chat.completions.create(
        model=MODEL,  # the model must accept images, e.g. claude-haiku-5-5
        messages=[
            {
                "role": "user",

5Generating images

The endpoint is POST /v1/images/generations, OpenAI format. Generation takes up to 3 minutes, so set a 300-second client timeout. The curl version needs jq. All parameters: POST /v1/images/generations.

import base64
import os

from openai import OpenAI

client = OpenAI(
    base_url="https://api.zukko.pro/v1",
    api_key=os.environ["ZUKKO_API_KEY"],
    timeout=300,  # generation can take up to 3 minutes
)

result = client.images.generate(
    model="openai-gpt-image-2-text-to-image",
    prompt="A cozy coffee shop on an autumn evening, warm light from the windows, watercolor",
    size="1024x1024",
    quality="high",
    response_format="b64_json",
)

with open("picture.png", "wb") as f:
    f.write(base64.b64decode(result.data[0].b64_json))
print("Saved: picture.png")

6If it doesn't work

What you seeWhat to do
400, or the model "can't see" the imageUse a model that accepts images, e.g. claude-haiku-5-5
An error about the image URLDownload the image and send it as a file (data URL)
The model misreads receipt numbersRetake the photo closer, use claude-sonnet-5
json.JSONDecodeError in receipt.pyRetry; raise max_tokens for long receipts
503 model_disabled when generatingImage models are temporarily off — watch GET /v1/models
402 insufficient_balance or 504 image_generation_timeout402 — top up. 504 — retry, simplify the prompt

Other codes: API errors.

Images: understand and generate · Zukko Docs