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

# Image generation

> Generate images through an OpenAI-compatible endpoint with the same key, rate limits, and spend caps as chat.

The gateway also **generates** images: an OpenAI-compatible endpoint sits
alongside chat completions, authenticated with the same API key (as
`Authorization: Bearer` or `x-api-key`) and governed by the same
per-client rate limits as every other `/v1` route. Requests are synchronous —
multi-image or high-quality generations can take tens of seconds, so set client timeouts
accordingly.

```bash theme={"dark"}
curl https://api.aireserve.com/v1/images/generations \
  -H "Authorization: Bearer $AUDACITY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-2.5-flash-image",
    "prompt": "A watercolor painting of a fox in a snowy forest",
    "n": 1,
    "size": "1024x1024",
    "response_format": "url"
  }'
```

## Request parameters

| Field             | Required | Description                                                                          |
| ----------------- | -------- | ------------------------------------------------------------------------------------ |
| `model`           | yes      | Image model ID — see the table below                                                 |
| `prompt`          | yes      | Text description of the desired image(s); 1–32,000 characters                        |
| `n`               | no       | Number of images to generate — integer 1–10 (model-dependent)                        |
| `size`            | no       | Dimensions as a `"WxH"` string (e.g. `1024x1024`); supported values differ per model |
| `quality`         | no       | Provider-specific quality tier (e.g. `standard`, `hd`, `low`, `high`)                |
| `response_format` | no       | `url` (default) — a signed download link — or `b64_json` — inline base64 bytes       |
| `user`            | no       | End-user identifier forwarded to the provider for abuse attribution                  |

## Response

The response follows the OpenAI images shape — `created` (unix seconds), a
`data` array with one entry per generated image, and an optional
`usage` object on token-priced models:

```json theme={"dark"}
{
  "created": 1752000000,
  "data": [
    {
      "url": "https://storage.googleapis.com/…?X-Goog-Signature=…",
      "revised_prompt": "A watercolor painting of a fox…"
    }
  ],
  "usage": { "input_tokens": 12, "output_tokens": 1024, "total_tokens": 1036 }
}
```

* With `response_format: "url"` (the default), each image is stored by the gateway and returned as a **signed download URL valid for \~24 hours** — download promptly and persist on your side.
* With `response_format: "b64_json"`, each entry carries the base64-encoded PNG bytes inline instead.
* `revised_prompt` appears when the provider rewrites your prompt before generating.

## Models & pricing

| Model                    | Pricing                                                              |
| ------------------------ | -------------------------------------------------------------------- |
| `gemini-2.5-flash-image` | Token-based (≈ \$0.039 / image)                                      |
| `gpt-image-1`            | Token-based ($5.00 / 1M text input, $40.00 / 1M image output tokens) |

Token-based models report token counts in the response `usage` object. Every
request's cost is metered against your key exactly like chat traffic and counts toward
the same spend caps.

<Warning>
  **Imagen retirement.** Google is shutting down the entire Imagen family on
  **August 17, 2026**, and the whole line is now delisted from the gateway:
  `imagen-4`, `imagen-4-fast`, and `imagen-4-ultra` IDs
  all return errors. The migration target is `gemini-2.5-flash-image`
  (GA, token-based, ≈ \$0.039 / image); `gpt-image-1` also remains available.
</Warning>

<Note>
  **Reliability.** Upstream image backends occasionally stall with a 503 for a
  few minutes. There is deliberately **no automatic fallback** to a different
  image model — silently swapping models would change output style and quality — so callers
  should **retry** instead. The SDKs already retry 503s with jittered backoff
  up to their configured retry budget.
</Note>

## Using the SDKs

All five SDKs ship an image-generation helper as of **SDK v0.4.0**, with the
same auth, error mapping (401 → `AccessDeniedException`, 402 →
`ServiceQuotaExceededException`, 429 → `ThrottlingException`), and
retry policy as `Converse`:

<CodeGroup>
  ```python Python theme={"dark"}
  result = client.images.generate(
      model="gemini-2.5-flash-image",
      prompt="A watercolor painting of a fox in a snowy forest",
  )
  print(result["data"][0]["url"])   # signed download URL, valid ~24 h

  # Inline bytes instead: response_format="b64_json" → result["data"][0]["b64_json"]
  ```

  ```typescript TypeScript theme={"dark"}
  const result = await client.images.generate({
    model: "gemini-2.5-flash-image",
    prompt: "A watercolor painting of a fox in a snowy forest",
  });
  console.log(result.data[0].url); // signed download URL, valid ~24 h

  // Inline bytes instead: responseFormat: "b64_json" → result.data[0].b64Json
  ```

  ```go Go theme={"dark"}
  out, err := client.GenerateImage(ctx, &audacityruntime.GenerateImageInput{
      Model:  audacity.String("gemini-2.5-flash-image"),
      Prompt: audacity.String("A watercolor painting of a fox in a snowy forest"),
  })
  if err != nil {
      log.Fatal(err)
  }
  fmt.Println(out.Data[0].Url) // signed download URL, valid ~24 h

  // Inline bytes instead: ResponseFormat: audacity.String("b64_json") → out.Data[0].B64Json
  ```

  ```java Java theme={"dark"}
  GenerateImageResponse result = client.generateImage(b -> b
      .model("gemini-2.5-flash-image")
      .prompt("A watercolor painting of a fox in a snowy forest"));

  System.out.println(result.data().get(0).url()); // signed download URL, valid ~24 h

  // Inline bytes instead: .responseFormat("b64_json") → result.data().get(0).b64Json()
  ```

  ```rust Rust theme={"dark"}
  let result = client.generate_image()
      .model("gemini-2.5-flash-image")
      .prompt("A watercolor painting of a fox in a snowy forest")
      .send()
      .await?;

  println!("{}", result.data[0].url.as_deref().unwrap()); // signed URL, valid ~24 h

  // Inline bytes instead: .response_format("b64_json") → result.data[0].b64_json
  ```
</CodeGroup>

Errors reuse the chat-completions codes: 400 `invalid_request_error` for a
malformed body, 401 `invalid_api_key`, 402 `usage_cap_exceeded` when
a spend cap is reached (never retried), and 429 `rate_limit_exceeded` with a
`Retry-After` header. See [Errors & retries](/api-reference/errors) for the
full exception mapping in each SDK.
