# POST /v1/images/*

An OpenAI Images-compatible API for generating images or editing images based on references with GPT Image models. Usage is largely the same as with the OpenAI SDK: point `base_url` to 4AICode and replace `api_key` with your `sk-4ai-...` token.

Image generation is charged per request against your wallet balance. The [Image Generation](/images) page in the console is suitable for manual use, while the API is designed for integration into your own applications, workflows, and automation scripts.

For new projects, prefer GPT Image 2.5: `gpt-image-2.5-sunburst` is the most capable option for high-quality generation and precise editing, while `gpt-image-2.5-flare` is the fastest choice for high-quality everyday image generation. Existing integrations can continue using `gpt-image-2`.

## Endpoints

```text
POST https://relay.4aicode.com/v1/images/generations
POST https://relay.4aicode.com/v1/images/edits
```

## Supported Models

| Model | Use Case | Billing |
|---|---|---|
| `gpt-image-2.5-sunburst` | The most capable GPT Image 2.5 model for high-quality generation and precise editing | Charged per request against your wallet balance |
| `gpt-image-2.5-flare` | The fast GPT Image 2.5 model for high-quality everyday image generation | Charged per request against your wallet balance |
| `gpt-image-2` | Text-to-image generation and reference-based image editing | Charged per request against your wallet balance |

Each model is available after an administrator configures and enables its per-use price and selects it in an upstream model list. If the model is not enabled, the API returns `503 model_unavailable`.

## Text-to-Image Generation

### curl

```bash
curl https://relay.4aicode.com/v1/images/generations \
  -H "Authorization: Bearer sk-4ai-xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2.5-sunburst",
    "prompt": "A clean product shot of a black mechanical keyboard on a white desk",
    "size": "1024x1024",
    "quality": "medium",
    "response_format": "b64_json"
  }'
```

### Python

```python
import base64
from openai import OpenAI

client = OpenAI(
    base_url="https://relay.4aicode.com/v1",
    api_key="sk-4ai-xxxxxxxxxxxxxxxx",
)

resp = client.images.generate(
    model="gpt-image-2.5-sunburst",
    prompt="A clean product shot of a black mechanical keyboard on a white desk",
    size="1024x1024",
    quality="medium",
    response_format="b64_json",
)

image_base64 = resp.data[0].b64_json
with open("keyboard.png", "wb") as f:
    f.write(base64.b64decode(image_base64))
```

### TypeScript

```ts
import fs from "node:fs";
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://relay.4aicode.com/v1",
  apiKey: process.env.OPENAI_API_KEY,
});

const resp = await client.images.generate({
  model: "gpt-image-2.5-sunburst",
  prompt: "A clean product shot of a black mechanical keyboard on a white desk",
  size: "1024x1024",
  quality: "medium",
  response_format: "b64_json",
});

const image = resp.data[0]?.b64_json;
if (!image) throw new Error("image generation failed");
fs.writeFileSync("keyboard.png", Buffer.from(image, "base64"));
```

## Reference-Based Image Editing

`/v1/images/edits` supports two input methods:

- `multipart/form-data`: Upload files using the `image` or `image[]` field. The maximum size of each file is 20 MB.
- `application/json`: Pass a base64 data URL or an accessible image URL in `images[].image_url`.

### multipart curl

```bash
curl https://relay.4aicode.com/v1/images/edits \
  -H "Authorization: Bearer sk-4ai-xxxxxxxxxxxxxxxx" \
  -F model="gpt-image-2.5-sunburst" \
  -F prompt="Keep the product, replace the background with a bright studio setup" \
  -F size="1024x1024" \
  -F quality="medium" \
  -F response_format="b64_json" \
  -F image="@./product.png"
```

Multiple reference images:

```bash
curl https://relay.4aicode.com/v1/images/edits \
  -H "Authorization: Bearer sk-4ai-xxxxxxxxxxxxxxxx" \
  -F model="gpt-image-2.5-sunburst" \
  -F prompt="Combine these references into one cohesive hero image" \
  -F image[]="@./subject.png" \
  -F image[]="@./style.png"
```

### JSON Data URL

```bash
IMAGE_B64="$(base64 < product.png | tr -d '\n')"

curl https://relay.4aicode.com/v1/images/edits \
  -H "Authorization: Bearer sk-4ai-xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d "{
    \"model\": \"gpt-image-2.5-sunburst\",
    \"prompt\": \"Put this product in a premium ecommerce scene\",
    \"size\": \"1024x1024\",
    \"quality\": \"medium\",
    \"response_format\": \"b64_json\",
    \"images\": [
      { \"image_url\": \"data:image/png;base64,${IMAGE_B64}\" }
    ]
  }"
```

`file_id` currently returns an explicit error. To use a mask, provide it through the `mask` file field or pass `mask.image_url` in JSON.

## Parameters

| Parameter | Applicable Endpoints | Description |
|---|---|---|
| `model` | All | An enabled model ID from the table above |
| `prompt` | All | Required generation or editing instructions |
| `size` | All | `auto`, `1024x1024`, `1536x1024`, or `1024x1536` |
| `quality` | All | `auto`, `low`, `medium`, or `high`; GPT Image 2.5 also supports `xhigh` and `max` |
| `response_format` | All | `b64_json` or `url`; `url` returns a data URL |
| `output_format` | All | `png`, `jpeg`, or `webp` |
| `background` | All | Passed through to the upstream image tool |
| `output_compression` | All | Output compression ratio for formats that support compression |
| `stream` | All | Returns SSE when set to `true` |
| `partial_images` | All | Requests partial-image events in streaming mode |
| `image` / `image[]` | edits | Reference images provided via multipart |
| `images[].image_url` | edits | Reference image URL or data URL provided via JSON |
| `mask` / `mask.image_url` | edits | Optional mask |
| `input_fidelity` | edits | Reference-image fidelity, passed through to the upstream image tool |

## Response

Non-streaming requests return an OpenAI Images-style response:

```json
{
  "created": 1770000000,
  "data": [
    {
      "b64_json": "iVBORw0KGgo...",
      "revised_prompt": "..."
    }
  ],
  "size": "1024x1024",
  "quality": "medium",
  "output_format": "png",
  "usage": {
    "images": 1
  }
}
```

When `response_format=url`, `data[].url` contains a `data:image/png;base64,...` URL, with the image content returned directly in the response.

## Streaming Responses

Set `"stream": true` to return SSE.

Text-to-image generation events:

```text
event: image_generation.partial_image
data: {"type":"image_generation.partial_image","partial_image_index":0,"b64_json":"..."}

event: image_generation.completed
data: {"type":"image_generation.completed","b64_json":"...","usage":{"images":1}}
```

Reference-based image editing events use the `image_edit` prefix:

```text
event: image_edit.completed
data: {"type":"image_edit.completed","b64_json":"...","usage":{"images":1}}
```

## Billing and Records

Each successful generation is charged at the current per-request price for the selected model. The usage page, wallet transaction history, and backend usage log record the model, request count, cost, status, and trace ID. By default, the platform does not store your prompts or image content.

## Common Errors

| HTTP | code | Resolution |
|---|---|---|
| 400 | `invalid_request_error` | Check `prompt`, `model`, image fields, and multipart formatting |
| 401 | `unauthorized` | Check `Authorization: Bearer sk-4ai-...` |
| 429 | `insufficient_quota` / `rate_limit` | Add funds to your wallet or reduce concurrency |
| 503 | `model_unavailable` | Contact an administrator to enable per-request pricing for the selected image model |
| 502 | `upstream_error` | Retry later; if the issue persists, contact support with the trace ID |
