> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aion.to/llms.txt
> Use this file to discover all available pages before exploring further.

# Image models

> Generate images through Aion, receive JSON or streamed events, and save completed images.

> [!WARNING]
>
> The Aion Images API is experimental. Its contract and available model capabilities can change.

Image models return generated images as base64 data. Your application receives and saves the output.
Use the [Python helpers](#python-sdk) for automatic authentication and response handling, or call the
[HTTP endpoint](#http-api) directly. The request shape follows the OpenRouter Images API standard.

## Before you start

Open **Resources > Models**, select **Image**, and choose a model that offers the Images operation.
An image input capability alone does not enable image generation.
The image catalog is also available at `GET https://api.aion.to/v1/images/models`.

The caller needs `model.execute` and sufficient organization credits.
Use [deployment client credentials](https://docs.aion.to/docs/resources/model-service.md#deployment-client-credentials) with the Python SDK.
For direct HTTP calls, use the common [Model Service authentication](https://docs.aion.to/docs/resources/model-service.md#authentication).
This operation does not need File Service access.

Set `AION_IMAGE_MODEL` to your chosen model ID for the examples below.
Controls such as size, resolution, quality, format, and output count vary by route.
Check the model's available controls before adding them to a request.
The model-wide list combines controls for discovery; it does not guarantee that every combination works together.

## Python SDK

Install `aionto-sdk` in your application environment:

```bash theme={null}
pip install --upgrade aionto-sdk
```

The helpers read your existing Aion configuration and use current credentials for each request.
Inside an agent request, they preserve its attribution, including a forwarded usage-attribution header.
Outside a request, they omit attribution headers so Aion can resolve the deployment's Daemon Identity.
An active request with missing attribution fails instead of silently changing the responsible identity.
You do not need to build headers or pass an API key to each helper.

### Get the JSON response

Save this as `generate-image.py` and run it in your configured deployment-client environment.

```python theme={null}
import os

from aion.api.images import generate_images

result = generate_images(
    os.environ["AION_IMAGE_MODEL"],
    "A simple blue circle icon on a white background",
)
print(f"Received {len(result['data'])} image(s)")
print("Quoted Aion credits:", result.get("usage", {}).get("cost"))
```

The result contains `data`, a list of images with `b64_json`, and optional `usage`.
The complete JSON response is held in client memory. To call from an agent coroutine, use the async variant:

```python theme={null}
import os

from aion.api.images import generate_images_async


async def generate() -> dict:
    return await generate_images_async(
        os.environ["AION_IMAGE_MODEL"],
        "A simple blue circle icon on a white background",
    )
```

### Save completed images

The SDK returns image data without creating files. Your application chooses names, storage, and retention.
For a local file, decode the base64 value and write the bytes. Save this helper as `image_files.py`:

```python theme={null}
import base64
from pathlib import Path
from uuid import uuid4


def save_image(image: dict) -> Path:
    directory = Path("generated-images")
    directory.mkdir(exist_ok=True)
    extension = {
        "image/png": ".png", "image/jpeg": ".jpg",
        "image/webp": ".webp", "image/avif": ".avif",
    }.get(image.get("media_type"), ".bin")
    path = directory / f"{uuid4()}{extension}"
    path.write_bytes(base64.b64decode(image["b64_json"], validate=True))
    return path
```

Add this after the JSON example to save its output:

```python theme={null}
from image_files import save_image

for image in result["data"]:
    print(save_image(image))
```

Each completed image creates a file under `generated-images/`. If the response omits its media type, the helper uses
`.bin`; inspect the bytes to determine a format before renaming it. Allow memory for both base64 and decoded bytes.

### Receive streamed events

Use `stream_images` in a `with` block. It parses native SSE and handles routes that return JSON instead.
Save this as `stream-image.py` beside `image_files.py`:

```python theme={null}
import os

from aion.api.images import stream_images
from image_files import save_image

with stream_images(
    os.environ["AION_IMAGE_MODEL"],
    "A simple blue circle icon on a white background",
) as events:
    for event in events:
        if event["type"] == "image_generation.completed":
            print(save_image(event))
```

For an agent coroutine, use `async with stream_images_async(...)` and `async for`:

```python theme={null}
import asyncio
import os

from aion.api.images import stream_images_async
from image_files import save_image


async def generate_and_save() -> None:
    async with stream_images_async(
        os.environ["AION_IMAGE_MODEL"],
        "A simple blue circle icon on a white background",
    ) as events:
        async for event in events:
            if event["type"] == "image_generation.completed":
                print(await asyncio.to_thread(save_image, event))
```

These iterators yield JSON events, not binary file chunks. Each event can contain a complete base64 image.
The SDK buffers each event; a JSON fallback buffers the complete response and produces completed-image events.
It attaches the fallback's whole-response usage only to the last image, so that price is not repeated for every image.
Consume events as they arrive instead of collecting them in a list when memory matters.

The context closes the response on completion, early exit, cancellation, or an error.
An incomplete stream raises `AionImageError`; files already saved remain available.
No helper retries generation automatically.
See the [Python API reference](https://docs.aion.to/sdk/python/api/images.md) for options and errors.

The existing LangGraph, Google ADK, and Codex model adapters remain Text clients.
The OpenAI Images resource uses a different endpoint. Use these helpers for Aion's native Images operation.

## HTTP API

Set `AION_API_KEY` to your personal key and `AION_IMAGE_MODEL` to a model ID from the image catalog.
This example saves the complete JSON response to `image-response.json`:

```bash theme={null}
python3 - <<'PYTHON'
import json
import os
from pathlib import Path

Path("image-request.json").write_text(json.dumps({
    "model": os.environ["AION_IMAGE_MODEL"],
    "prompt": "A simple blue circle icon on a white background",
    "stream": False,
}))
PYTHON
curl --fail-with-body --max-time 480 https://api.aion.to/v1/images \
  -H "Authorization: Bearer $AION_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @image-request.json \
  --output image-response.json
```

The JSON response has this shape. The base64 value is a placeholder.
The cost illustrates Aion credits, not a fixed rate.

```json theme={null}
{
  "created": 1792969200,
  "data": [{"b64_json": "BASE64_IMAGE_BYTES", "media_type": "image/png"}],
  "usage": {"prompt_tokens": 32, "completion_tokens": 1000, "cost": 40}
}
```

There is no hosted image URL, retention window, job-poll endpoint, or later download endpoint.
Your client owns the returned output. A JSON body can arrive in HTTP chunks; those chunks are not SSE events.

### Optional SSE and JSON fallback

Set `stream: true` to request native SSE. Check the actual response `Content-Type` before parsing the body.
Use `text/event-stream` as SSE and `application/json` as the JSON shape above.
Do not parse an image result as a chat-completion chunk.

| SSE data type | Meaning |
| - | - |
| `image_generation.partial_image` | Optional preview, not a completed result. |
| `image_generation.completed` | A completed image in `b64_json`, with optional media type and usage. |
| `error` | Generation failed. Earlier completed images can remain usable and billable. |
| `[DONE]` | End marker. Missing this marker means the stream did not finish normally. |

Model details show streaming support as **Available**, **Unsupported**, or **Unknown**.
Some routes return only JSON, even when the request sets `stream: true`.
Previews depend on the selected route and can contain a complete base64 image. Allow for large event payloads.

## Controls and limits

`model` and a nonempty `prompt` are required.
Optional controls include `n`, `size`, `resolution`, `aspect_ratio`, `quality`, `output_format`, `background`,
`output_compression`, `seed`, `input_references`, `provider`, `stream`, `session_id`, `trace`, and `user`.
Use only controls and combinations verified for the selected model and route.
`X-Session-Id` supplies a session ID only when the body omits `session_id`.
These descriptive fields do not select the principal or payer.

Reference images use `input_references` with supported HTTPS URLs or inline data URLs.
Aion does not import these references into File Service. The generation route retrieves remote references.
The request limits include inline base64 overhead. Model limits can be lower than Aion limits.

| Limit | Default |
| - | - |
| Request body | 32 MiB |
| JSON response or one SSE event | 64 MiB |
| Complete SSE response | 256 MiB |
| Completed images | Up to 10 |
| Reference images | Up to 16 |
| Input upload | 60 seconds |
| Generation | 5 minutes from admission |
| Final delivery | 60 seconds |
| Client and proxy allowance | At least 8 minutes |

## Prices and failure behavior

The catalog quotes Aion credits in each applicable unit: image, megapixel, token, request, or another reported unit.
Rows retain their route, resolution, and quality qualifiers. Per-token display uses one million tokens.
Hybrid models have separate Text and Image price views. Missing rates mean unavailable, not free.

When present, `usage.cost` is an Aion credit quote for the returned result. Fractional credits are valid.
Aion can omit the quote if a reliable price is unavailable. Output can still succeed.
The quote uses the applicable organization pricing policy; it is not a final settlement receipt.
It excludes other billable attempts. Policy changes or later usage information can change the settled charge.
The final charge uses completed-generation usage, not the requested image count alone.

> [!WARNING]
>
> A valid completed generation can use credits even if client delivery fails afterward.
> Aion does not retain the output for a later download.
> Do not automatically repeat a request after an ambiguous failure.

Previews and failures before any completed generation do not create an image-generation charge.
A client disconnect cancels upstream work. A completion that already reached Aion remains billable.

Invalid controls fail before generation. HTTP 429 means the image runtime is busy.
Temporary catalog or runtime failures can return HTTP 503. A failure after SSE headers can end the stream.
A native `error` event also indicates failure. Preserve completed images and report an incomplete result to the user.
Aion permits one retry after an explicit upstream rate-limit rejection, within the original deadline.
It does not retry ambiguous paid work or repeat generation to recover missing usage prices.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.