# Sell images

This page shows how to sell images. Pick a path, give the agent the route, then register and quote the deployment. [Quote a media model](https://inference.ai.exchange/docs/provider-media-quote.md) has the features, the sizes and the prices.

## Choose a path

| Path                                                 | Use it when                                                                                 |
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| [OpenAI-compatible API](https://inference.ai.exchange/docs/provider-openai.md#images) | Your API has `POST /images/generations` and answers in the OpenAI format. You run no agent. |
| [Your own agent](https://inference.ai.exchange/docs/provider-dispatch.md#images)      | Your upstream has other routes. Send an `image` event for each image.                       |

The rest of this page is for the reference agent. It reads these routes from your upstream.

## Give the agent this route

The agent calls `POST {base}/images/generations` with `Authorization: Bearer <key>`. Set `{base}` in `LIQUID_UPSTREAM_BASE_URL`.

```json
{
  "model": "acme-image-1",
  "prompt": "A trading floor made of water",
  "n": 2,
  "size": "1024x1024",
  "output_format": "png",
  "response_format": "b64_json"
}
```

- `n` is always present. The other fields are present only when the buyer set them.
- When the buyer gave reference images, the agent adds `images`, a list of `{ "image_url": … }`.
- When the buyer sent `resolution` or `aspect_ratio`, `size` is the pixel size that the exchange picked.
- The agent sends `seed`, `background` and `output_compression` only for a control that you declared. See [Declare the controls](#declare-the-controls).
- The agent adds the fixed fields that you pin for the endpoint.

Answer with `data`, a list of images. Each image has `b64_json` or `url`. An entry with neither is not an image, and the agent does not count it.

```json
{ "data": [{ "b64_json": "iVBORw0KGgo…" }, { "b64_json": "iVBORw0KGgo…" }] }
```

The agent charges the images that you return, not the images that the buyer asked for. If `data` is empty, the job fails and the exchange tries the next offer.

## Declare the controls

A buyer's `seed`, `background`, `output_compression` and `stream` reach only an offer that declared `image.seed`, `image.background`, `image.output_compression` or `image.stream`. The first-party OpenAI adapter declares `image.background` and `image.output_compression` for a `gpt-image` model, and `image.seed` when the route has a seed rule. It never declares `image.stream`.

To send draft images for `image.stream`, write your own agent and send `image_partial` events. See [Images](https://inference.ai.exchange/docs/provider-dispatch.md#images).

## Register and quote

Register the deployment with `kind` set to `image_generation`. List the `sizes` and `formats` that it makes, and `max_count`. The tiers and shapes that buyers ask for come from `sizes`. [Register deployments](https://inference.ai.exchange/docs/provider-models.md) has the fields.

- To price for each image, quote an `output_image` line in `pricing`. Add a `variant` with `size` or `quality` for a price that depends on them.
- If your upstream bills tokens, set `pricing_unit` to `tokens` and `image_output_tokens_max`. Quote `input_text` and `output_text` lines in `pricing`. Your answer must then include `usage`, or the job fails.

See [Quote a media model](https://inference.ai.exchange/docs/provider-media-quote.md#an-image-model) for an example.

## Limits

- The agent reads the whole answer before it sends the first image. A call that sends no byte for two minutes fails.
- A failed call ends the attempt. The exchange charges nothing and tries the next offer.
- The reference agent sends no partial image.
