> For the complete documentation index, see [llms.txt](https://docs.avis.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.avis.net/api-reference/endpoints/image-generation.md).

# Image Generation

Estimate cost (dry-run):

`POST /api/v1/image/estimate`

Asynchronous endpoint:

`POST /api/v1/image/generations/async`

Poll asynchronous job:

`GET /api/v1/image/generations/async/:generationId`

### Request Fields

| Field                        | Type      | Required | Validation                                                                    | Description                                                                                                                                                                                                                                                                                                                      |
| ---------------------------- | --------- | -------- | ----------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `model`                      | string    | Yes      | String                                                                        | User-facing model identifier from `/ai/models`.                                                                                                                                                                                                                                                                                  |
| `content`                    | object\[] | Yes      | Non-empty array                                                               | Ordered request content. Supports text and image inputs.                                                                                                                                                                                                                                                                         |
| `size`                       | string    | No       | Must match `<width>x<height>` with positive integers, for example `1024x1024` | Requested output image size. Providers may translate this into their own aspect-ratio or size tiers.                                                                                                                                                                                                                             |
| `numberOfImages`             | integer   | No       | Minimum `1`, maximum `15`                                                     | Expected number of output images. Also state the desired number of pictures in the text prompt because some models can return fewer images than requested. Actual generated count varies by model and provider. BytePlus multi-image models cap total images at `15`, counting both reference images and expected output images. |
| `guidanceScale`              | number    | No       | Minimum `1`, maximum `10`                                                     | Prompt adherence versus creative freedom. Higher values follow the prompt more closely. This is not universal: the current adapter forwards it to BytePlus image models, and BytePlus support is model-specific. Unsupported models may ignore or reject it.                                                                     |
| `outputFormat`               | string    | No       | `png`, `jpeg`, or `webp`                                                      | Requested output file format. `webp` is for OpenAI gpt-image (Ofox `openai/*`); BytePlus image models accept `png`/`jpeg` only. Provider/model support is narrower than the DTO, and unsupported models may ignore or reject the value.                                                                                          |
| `quality`                    | string    | No       | `auto`, `high`, `medium`, or `low`                                            | Rendering quality. OpenAI gpt-image only (Ofox `openai/*`); ignored for other providers/models. Higher quality costs more.                                                                                                                                                                                                       |
| `background`                 | string    | No       | `transparent`, `opaque`, or `auto`                                            | Background transparency. OpenAI gpt-image only (Ofox `openai/*`). `transparent` requires `outputFormat` of `png` or `webp`.                                                                                                                                                                                                      |
| `outputCompression`          | integer   | No       | Minimum `0`, maximum `100`                                                    | Compression level for `webp`/`jpeg` output. OpenAI gpt-image only (Ofox `openai/*`).                                                                                                                                                                                                                                             |
| `watermark`                  | boolean   | No       | Boolean                                                                       | Whether to add an "AI generated" watermark when supported.                                                                                                                                                                                                                                                                       |
| `optimizePromptOptions`      | object    | No       | Object                                                                        | BytePlus-only prompt optimization controls. Currently supports `mode`; other current image adapters do not forward this field.                                                                                                                                                                                                   |
| `optimizePromptOptions.mode` | string    | No       | `standard` or `fast`                                                          | BytePlus prompt optimization mode. `standard` favors quality; `fast` favors lower latency where supported by the selected BytePlus model.                                                                                                                                                                                        |
| `maxTokens`                  | integer   | No       | Minimum `1`                                                                   | Maximum tokens to generate for providers that accept token controls in image generation. Some image models do not support this field; BytePlus image generation strips it before sending the provider request, while OpenRouter image generation forwards it.                                                                    |
| `layerDecomposition`         | boolean   | No       | Boolean                                                                       | Decompose the input image into a base image + up to 16 layers. BytePlus `dola-seedream-5-0-pro` only. See Layer Separation below.                                                                                                                                                                                                |

### Layer Separation (`dola-seedream-5-0-pro`)

Set `layerDecomposition: true` to decompose a single input image into a base image plus up to 16 separated element layers (up to 17 output images total). Available on `dola-seedream-5-0-pro` only.

> **You cannot request an exact output count.** `numberOfImages` is fixed at `1` in this mode (see constraints below) — how many layers come back is decided by the model based on what it detects in the image, not a number you set. Your only influence is indirect, via the prompt (see the three methods below); precise `<bbox>` coordinate targeting comes closest to controlling the count, since each targeted region tends to produce one layer. The hard ceiling is 16 layers + 1 base = 17 images, and above 16 detected elements some layer information may be lost.

**Constraints in this mode:**

* Exactly one input image (`content` must contain exactly one `imageUrl`/`imageBase64`/`imageAssetId` part) — multiple images are rejected.
* `size` is not accepted; use `resolution` instead (`"1K"`, `"1.5K"`, `"2K"`, or `"auto"`, default `"auto"`). `ratio` is ignored — the base image's aspect ratio always matches the input image.
* `numberOfImages` must be omitted or `1`.
* `outputFormat` applies to the base image only; every layer is always returned as `png`.
* **No partial success**: if any single layer fails to generate, the whole request fails.
* Above 16 detected elements, some layer information may be lost.

**Three ways to control what gets separated (via `prompt`/text content):**

1. No prompt — auto-detect and separate all major elements.
2. Natural-language description — describe intent; you may also annotate the input image (scribbles, circles) to help with positioning.
3. Precise coordinate targeting — use `<bbox>` tags in the prompt with normalized coordinates.

**Recomposing layers:** `images[0]` is the base image (`zIndex: 0`); the rest are layers ordered by increasing `zIndex` (bottom to top). Each layer is cropped tightly to its element, not a full-canvas transparent image — reposition it into the base image's coordinate system using `images[].boundingBox.absolute` (`[left, top, right, bottom]` in pixels, origin at the base image's top-left corner) before compositing.

> **Cost:** each returned image (base + every layer) is billed as a separate output image — a single layer-separation call can return up to 17 images, i.e. up to \~17× the cost of a normal single-image request. There is no way to know the layer count in advance, so `POST /image/estimate` cannot preview the true cost for this mode.

#### Layer Separation Request Example

```
POST /api/v1/image/generations/async
```

```json
{
  "model": "dola-seedream-5-0-pro",
  "content": [
    { "type": "text", "text": "Precisely separate the image into layers." },
    { "type": "imageUrl", "url": "https://your-accessible-url/input.png" }
  ],
  "resolution": "2K",
  "layerDecomposition": true,
  "watermark": true
}
```

#### Layer Separation Response Example (abridged)

```json
{
  "images": [
    { "url": "https://...", "zIndex": 0 },
    {
      "url": "https://...",
      "zIndex": 1,
      "boundingBox": { "absolute": [383, 120, 1655, 384], "normalized": [187, 59, 808, 188] },
      "name": "Seedream title text",
      "description": "The 'Seedream' title in a large yellow serif font"
    },
    {
      "url": "https://...",
      "zIndex": 7,
      "boundingBox": { "absolute": [698, 624, 1328, 2047], "normalized": [341, 305, 648, 1000] },
      "name": "Scarlet macaw",
      "description": "A brightly colored scarlet macaw perched on a moss-covered branch"
    }
  ],
  "usage": { "generatedImages": 8, "totalTokens": 23107 }
}
```

`images[0]` (`zIndex: 0`) is the base image and has no `boundingBox`/`name`/`description`. Every subsequent element is a layer — use `boundingBox.absolute` to place it back into the base image's coordinate system.

### Image Content Parts

All content parts require a `type` discriminator.

| Type          | Fields                               | Description                                                                                                                          |
| ------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------ |
| `text`        | `text: string`                       | Prompt text. Multiple text parts are joined by providers that require a single prompt.                                               |
| `imageUrl`    | `url: string`                        | Publicly fetchable image URL. Must pass URL validation.                                                                              |
| `imageBase64` | `data: string`, `mediaType?: string` | Raw base64 image bytes or a full data URL. `mediaType` is required for raw base64 and must be one of the supported image MIME types. |

Supported image MIME types:

`image/jpeg`, `image/png`, `image/gif`, `image/webp`, `image/bmp`, `image/tiff`, `image/heic`, `image/heif`, `image/avif`.

### Estimate Cost

Call `POST /api/v1/image/estimate` with the exact body you intend to send to the generation endpoint to preview the cost before committing. No credit is deducted and nothing is persisted.

> **Note:** The returned cost is indicative only. The actual amount charged may differ — the final cost is only known after generation completes.

#### Request Example

```
POST /api/v1/image/estimate
```

```json
{
  "model": "seedream-4-0",
  "content": [
    {
      "type": "text",
      "text": "Create two clean product mockup images on a neutral background."
    }
  ],
  "size": "1024x1024",
  "numberOfImages": 2,
  "watermark": false
}
```

#### Response Fields

| Field               | Type   | Description                                                                               |
| ------------------- | ------ | ----------------------------------------------------------------------------------------- |
| `estimatedUserCost` | number | Estimated cost in USD. Matches what would be reserved by `POST /image/generations/async`. |
| `currency`          | string | Always `"USD"`.                                                                           |

#### Response Example

```json
{
  "data": {
    "estimatedUserCost": 0.12,
    "currency": "USD"
  },
  "success": true,
  "status": 200
}
```

Once the cost is acceptable, submit the same body to `POST /api/v1/image/generations/async` to generate.

### Generation Request Example

```
POST /api/v1/image/generations/async
```

```json
{
  "model": "seedream-4-0",
  "content": [
    {
      "type": "text",
      "text": "Create two clean product mockup images on a neutral background."
    }
  ],
  "size": "1024x1024",
  "numberOfImages": 2,
  "watermark": false
}
```

### ImageResult Fields

| Field                             | Type       | Required | Description                                                                                                       |
| --------------------------------- | ---------- | -------- | ----------------------------------------------------------------------------------------------------------------- |
| `images`                          | object\[]  | Yes      | Generated image outputs.                                                                                          |
| `images[].url`                    | string     | No       | Provider URL for the generated image when returned as a URL. Provider URLs can expire.                            |
| `images[].downloadUrl`            | string     | No       | Presigned R2 download link for the archived output. This URL expires; re-fetch instead of storing it permanently. |
| `images[].assetId`                | string     | No       | Asset id of the archived image. Reuse via `imageAssetId` in later requests.                                       |
| `images[].zIndex`                 | integer    | No       | Layer stacking order: `0` for the base image, increasing toward the top. `layerDecomposition` only.               |
| `images[].boundingBox`            | object     | No       | Position of this layer within the base image. Absent on the base image itself. `layerDecomposition` only.         |
| `images[].boundingBox.absolute`   | integer\[] | No       | `[left, top, right, bottom]` in pixels, origin `(0,0)` at the base image's top-left corner.                       |
| `images[].boundingBox.normalized` | integer\[] | No       | Same as `absolute`, quantized to `[0, 1000]` and truncated at `1000`.                                             |
| `images[].name`                   | string     | No       | Short model-generated label for this layer, e.g. `"Seedream title text"`. `layerDecomposition` only.              |
| `images[].description`            | string     | No       | Richer description of this layer (color, state, material). `layerDecomposition` only.                             |
| `usage`                           | object     | No       | Provider-reported usage.                                                                                          |
| `usage.generatedImages`           | number     | No       | Number of images counted by the provider.                                                                         |
| `usage.totalTokens`               | number     | No       | Total tokens consumed when reported.                                                                              |
| `usage.inputTokens`               | number     | No       | Text plus image input tokens when reported.                                                                       |
| `usage.outputTokens`              | number     | No       | Text plus image output tokens when reported.                                                                      |
| `usage.inputImageTokens`          | number     | No       | Subset of input tokens attributed to image input.                                                                 |
| `usage.outputImageTokens`         | number     | No       | Subset of output tokens attributed to generated image output.                                                     |
| `usage.usdCost`                   | number     | No       | Provider-reported USD cost when the provider reports a billing figure.                                            |

### Async Image Status Fields

| Field          | Type   | Required | Description                                                           |
| -------------- | ------ | -------- | --------------------------------------------------------------------- |
| `status`       | string | Yes      | Current job status: `queued`, `processing`, `succeeded`, or `failed`. |
| `generationId` | string | Yes      | Generation id returned when the async job was accepted.               |
| `result`       | object | No       | `ImageResult`, present after success.                                 |
| `error`        | string | No       | Failure message when `status` is `failed`.                            |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.avis.net/api-reference/endpoints/image-generation.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
