Skip to content

Create and verify your first image

Topics: clients, generation, images, requests

This lesson takes one request from local construction to a verified WebP file. It starts with the API's cost-only dry run, then performs live generation only when you add --live.

Before you start

You need Python 3.12 or newer and an internet connection. The live step uses the shared AI Horde queue, so completion time depends on available workers. Anonymous requests do not require an account, but they receive lower priority than requests made with a registered API key.

Create a virtual environment and install the SDK:

python -m venv .venv
.venv\Scripts\activate
python -m pip install horde-sdk

On macOS or Linux, activate with source .venv/bin/activate.

Inspect the request

The example builds one 512 by 512 request. The dry_run field is the only difference between estimation and live submission.

def build_request(*, dry_run: bool) -> ImageGenerateAsyncRequest:
    """Build the same small request for estimation or generation."""
    return ImageGenerateAsyncRequest(
        apikey=ANON_API_KEY,
        prompt="A small glass greenhouse in a mossy forest, morning light",
        models=["AlbedoBase XL (SDXL)"],
        params=ImageGenerationInputPayload(width=512, height=512, steps=20, n=1),
        nsfw=False,
        censor_nsfw=True,
        dry_run=dry_run,
    )


def estimate(client: AIHordeAPISimpleClient) -> float:
    """Return the estimated kudos cost without creating an image."""
    response = client.image_generate_request_dry_run(build_request(dry_run=True))
    return response.kudos


def generate(client: AIHordeAPISimpleClient, output: Path) -> Path:
    """Generate one image, save it, and verify that Pillow can decode it."""
    status, _request_id = client.image_generate_request(build_request(dry_run=False))
    if not status.generations:
        raise RuntimeError("The request completed without an image")

    image = client.download_image_from_generation(status.generations[0])
    image.save(output)
    with Image.open(output) as saved:
        saved.verify()
    return output

The simple client owns polling and best-effort cleanup. The request model validates its shape before the first network call. See the request and response contracts for that boundary.

Estimate the cost

Run the example without flags:

python examples/docs/first_image.py

The response contains an estimate and creates no generation job:

Estimated cost: 2 kudos

The numeric value varies with Horde pricing and request parameters. A line beginning with Estimated cost: confirms that request construction, validation, and the dry-run API call succeeded.

Generate and verify the file

Opt in to the live request and choose the output path:

python examples/docs/first_image.py --live --output first-image.webp

The command first prints the current estimate. It then waits for the shared queue, downloads the first result, saves it, and asks Pillow to verify the encoded file:

Estimated cost: 2 kudos
Verified image: C:\path\to\first-image.webp

Open first-image.webp. You now have a complete result and no request ID to manage manually. The image generation how-to shows registered keys, callbacks, timeouts, and multiple results; the client layers explanation shows what the simple client handled for you.