# GPT base + Banana 2.1 High {#section-1 .rd-guide-title}

GPT Image 2.5 first draws a draft of about 1K, then Banana 2.0, Banana 2.1 or Banana Pro rebuilds it at 1K, 2K or 4K. The API is compatible with OpenAI Images and is billed per image at the same price for all three sizes.

## 1 Quick start {#quickstart}

Use an API key bound to the **`gpt基地+banana2.1 high 支持2k 4k` group (177)**. The example generates one **2K 16:9** image without `response_format` (the default returns an image `url`), then downloads and opens it. Pass one local reference image to run a **4K image edit** instead. Each run is billed at the group price. The examples use `gpt-image-2.5-banana2.1`; for a faster, cheaper option use `gpt-image-2.5-banana2` (Banana 2.0) by changing only `model`.

### 1.1 Python 3: complete flow {#quick-python}

Works on Windows, macOS and Linux. It uses only the Python standard library, so no SDK is needed.

Save the code below as `gpt-banana21-high-quickstart.py` and enter your API key when prompted:

- Text to image, 2K 16:9: `python3 gpt-banana21-high-quickstart.py`
- Image edit, 4K: `python3 gpt-banana21-high-quickstart.py reference.png` (uploads one local PNG / JPEG / WebP)

On Windows, use `py -3` instead of `python3`. A request usually takes 60--105 seconds. The script prints the file path and the actual size, then tries to open the result in your browser. Prompts and messages in the examples are kept in their original Chinese.

``` python
import base64
import getpass
import json
from pathlib import Path
import sys
from urllib.error import HTTPError
from urllib.request import Request, urlopen
import uuid
import webbrowser

BASE_URL = "https://yyds.seqnode.com/v1"
USER_AGENT = "YM2API-Quickstart/1.0"
# 不带参数：文生图 2K 16:9；带一个本地图片路径：图生图 4K（1:1）。
# 省略 response_format 时默认返回图片链接（url）；需要 Base64 时加 "response_format": "b64_json"。
# 更快、更便宜可把 model 改为 "gpt-image-2.5-banana2"（香蕉 2.0，$0.05/张）。
GENERATE = {
    "model": "gpt-image-2.5-banana2.1",
    "prompt": "雨后的城市街角咖啡馆，木质招牌写着'CAFE 1897'，暖色灯光，电影感。",
    "size": "2048x1152",
    "n": 1
}
EDIT = {
    "model": "gpt-image-2.5-banana2.1",
    "prompt": "保留参考图的主体、构图和文字，改成冬夜雪景，细节清晰。",
    "size": "4K",
    "n": "1"
}


def post(path, api_key, body, content_type):
    headers = {"Authorization": "Bearer " + api_key, "Content-Type": content_type, "User-Agent": USER_AGENT}
    with urlopen(Request(BASE_URL + path, data=body, headers=headers), timeout=300) as response:
        return json.load(response)


def multipart(fields, image_path):
    boundary = "----ym2api" + uuid.uuid4().hex
    chunks = []
    for name, value in fields.items():
        chunks.append(f'--{boundary}\r\nContent-Disposition: form-data; name="{name}"\r\n\r\n{value}\r\n'.encode("utf-8"))
    data = image_path.read_bytes()
    if data.startswith(b"\x89PNG\r\n\x1a\n"):
        mime, filename = "image/png", "reference.png"
    elif data.startswith(b"\xff\xd8\xff"):
        mime, filename = "image/jpeg", "reference.jpg"
    elif len(data) >= 12 and data[:4] == b"RIFF" and data[8:12] == b"WEBP":
        mime, filename = "image/webp", "reference.webp"
    else:
        raise ValueError("参考图需为 PNG、JPEG 或 WebP。")
    chunks.append(f'--{boundary}\r\nContent-Disposition: form-data; name="image"; filename="{filename}"\r\n'
                  f"Content-Type: {mime}\r\n\r\n".encode("utf-8") + data + b"\r\n")
    chunks.append(f"--{boundary}--\r\n".encode("utf-8"))
    return b"".join(chunks), "multipart/form-data; boundary=" + boundary


def main():
    api_key = getpass.getpass("输入 API Key：").strip()
    if not api_key:
        raise ValueError("请输入有效的 API Key。")
    if len(sys.argv) > 1:
        body, content_type = multipart(EDIT, Path(sys.argv[1]))
        result = post("/images/edits", api_key, body, content_type)
    else:
        body = json.dumps(GENERATE, ensure_ascii=False).encode("utf-8")
        result = post("/images/generations", api_key, body, "application/json; charset=utf-8")
    item = next(iter(result.get("data") or []), {})
    if item.get("url"):
        # 图片链接保留 1 小时；下载时不要携带 API Key。
        with urlopen(Request(item["url"], headers={"User-Agent": USER_AGENT}), timeout=120) as response:
            data = response.read()
    elif item.get("b64_json"):
        data = base64.b64decode(item["b64_json"], validate=True)
    else:
        raise ValueError("响应没有最终图片。请检查响应和使用记录，再决定是否重试。")
    if data.startswith(b"\x89PNG\r\n\x1a\n"):
        extension = ".png"
    elif data.startswith(b"\xff\xd8\xff"):
        extension = ".jpg"
    elif len(data) >= 12 and data[:4] == b"RIFF" and data[8:12] == b"WEBP":
        extension = ".webp"
    else:
        raise ValueError("返回数据不是可识别的 PNG、JPEG 或 WebP。")
    path = Path.cwd() / ("gpt-banana21-" + uuid.uuid4().hex + extension)
    with path.open("xb") as output:
        output.write(data)
    print(f"图片已保存：{path}（实际尺寸 {result.get('size', '未知')}）")
    if not webbrowser.open(path.as_uri()):
        print("请到以上路径手动打开图片。")


if __name__ == "__main__":
    try:
        main()
    except HTTPError as error:
        print(f"HTTP {error.code}：{error.read(2000).decode('utf-8', errors='replace')}")
        raise SystemExit(1)
    except Exception as error:
        print(f"运行失败：{error}")
        raise SystemExit(1)
```

[Download the Python example](gpt-banana21-high-quickstart.py). If the result does not open automatically, open the printed path yourself.

### 1.2 PowerShell 7: complete flow {#quick-powershell}

For Windows users with PowerShell 7. Paste the whole block into a terminal and enter your API key when prompted. Leave `$referenceImage` empty to generate a 2K 16:9 image; set it to a local image path to upload that image and generate at 4K.

``` powershell
$apiKey = Read-Host "输入 API Key" -MaskInput
if ([string]::IsNullOrWhiteSpace($apiKey)) { throw "请输入有效的 API Key。" }
# 留空：文生图 2K 16:9；填写本地图片路径（如 "C:\images\reference.png"）：图生图 4K（1:1）。
$referenceImage = ""
# 省略 response_format 时默认返回图片链接（url）；需要 Base64 时加 response_format = "b64_json"。
# 更快、更便宜可把 model 改为 "gpt-image-2.5-banana2"（香蕉 2.0，$0.05/张）。
$headers = @{ Authorization = "Bearer $apiKey"; "User-Agent" = "YM2API-Quickstart/1.0" }
if ([string]::IsNullOrWhiteSpace($referenceImage)) {
    $payload = @{
        model = "gpt-image-2.5-banana2.1"
        prompt = "雨后的城市街角咖啡馆，木质招牌写着'CAFE 1897'，暖色灯光，电影感。"
        size = "2048x1152"
        n = 1
    }
    $request = @{
        Uri = "https://yyds.seqnode.com/v1/images/generations"
        Method = "Post"
        Headers = $headers
        ContentType = "application/json; charset=utf-8"
        Body = [Text.Encoding]::UTF8.GetBytes(($payload | ConvertTo-Json -Depth 12))
        TimeoutSec = 300
        ErrorAction = "Stop"
    }
} else {
    $form = @{
        model = "gpt-image-2.5-banana2.1"
        prompt = "保留参考图的主体、构图和文字，改成冬夜雪景，细节清晰。"
        size = "4K"
        n = "1"
        image = Get-Item -LiteralPath $referenceImage -ErrorAction Stop
    }
    $request = @{
        Uri = "https://yyds.seqnode.com/v1/images/edits"
        Method = "Post"
        Headers = $headers
        Form = $form
        TimeoutSec = 300
        ErrorAction = "Stop"
    }
}
$result = Invoke-RestMethod @request
$item = $result.data | Select-Object -First 1
if ($item.url) {
    # 图片链接保留 1 小时；下载时不要携带 API Key。
    $temp = Join-Path $PWD ("gpt-banana21-" + [guid]::NewGuid().ToString("N") + ".download")
    Invoke-WebRequest -Uri $item.url -UserAgent "YM2API-Quickstart/1.0" -OutFile $temp -TimeoutSec 120 -ErrorAction Stop
    $bytes = [IO.File]::ReadAllBytes($temp)
    Remove-Item -LiteralPath $temp
} elseif ($item.b64_json) {
    $bytes = [Convert]::FromBase64String($item.b64_json)
} else { throw "响应中没有图片。请保留响应和使用记录排查。" }
# 根据文件头识别格式，不按 output_format 命名。
if ($bytes.Length -lt 12) { throw "返回的图片数据过短。请保留响应排查。" }
$hex = [BitConverter]::ToString($bytes, 0, 12).Replace("-", "")
$extension = if ($hex.StartsWith("89504E470D0A1A0A")) { ".png" }
    elseif ($hex.StartsWith("FFD8FF")) { ".jpg" }
    elseif ([Text.Encoding]::ASCII.GetString($bytes, 0, 4) -eq "RIFF" -and
        [Text.Encoding]::ASCII.GetString($bytes, 8, 4) -eq "WEBP") { ".webp" }
    else { throw "返回数据不是可识别的 PNG、JPEG 或 WebP。请保留响应排查。" }
$file = Join-Path $PWD ("gpt-banana21-" + [guid]::NewGuid().ToString("N") + $extension)
$stream = [IO.File]::Open($file, [IO.FileMode]::CreateNew)
try { $stream.Write($bytes, 0, $bytes.Length) } finally { $stream.Dispose() }
Write-Host "图片已保存：$file（实际尺寸 $($result.size)）"
Invoke-Item -LiteralPath $file -ErrorAction Continue
```

[Download the PowerShell example](gpt-banana21-high-quickstart.ps1).

### 1.3 cURL: inspect the raw request {#quick-http}

These commands are for Bash (Linux, macOS or Git Bash) and only ask for your API key. The response is written to `response.json`, overwriting any existing file.

**Text to image, 2K 16:9 (returns a url by default):** save the following as UTF-8 `gpt-banana21-high-request.json`, or [download the request JSON](gpt-banana21-high-request.json).

``` json
{
  "model": "gpt-image-2.5-banana2.1",
  "prompt": "雨后的城市街角咖啡馆，木质招牌写着'CAFE 1897'，暖色灯光，电影感。",
  "size": "2048x1152",
  "n": 1
}
```

``` bash
read -rsp 'API Key: ' API_KEY; printf '\n'
curl --silent --show-error --fail-with-body --max-time 300 "https://yyds.seqnode.com/v1/images/generations" \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  --data-binary '@gpt-banana21-high-request.json' \
  --output response.json --write-out 'HTTP %{http_code}\n'
```

**Image edit at 4K with one reference image:** run in the folder that contains `reference.png`. It reuses `API_KEY` from the previous block (run that block's first line first if you run this one alone). Let cURL build the multipart headers; do not set `Content-Type` yourself.

``` bash
curl --silent --show-error --fail-with-body --max-time 300 "https://yyds.seqnode.com/v1/images/edits" \
  -H "Authorization: Bearer $API_KEY" \
  -F "model=gpt-image-2.5-banana2.1" \
  -F "prompt=保留参考图的主体、构图和文字，改成冬夜雪景，细节清晰。" \
  -F "image=@reference.png" \
  -F "size=4K" \
  -F "n=1" \
  --output response.json --write-out 'HTTP %{http_code}\n'
unset API_KEY
```

After HTTP 200, read `data[0].url` from `response.json` and download it within 1 hour. With `jq` installed:

``` bash
curl --fail --location --max-time 120 --output result.img "$(jq -r '.data[0].url' response.json)"
```

Do not send your API key when downloading the image. Check the file header to see whether `result.img` is PNG or JPEG, then rename it.

## 2 Access and how it works {#access}

**Base URL:** `https://yyds.seqnode.com/v1`, the same as the site's other OpenAI-compatible guides.

**Authentication:** `Authorization: Bearer YOUR_API_KEY`. Create the key on the [API Key page](/keys) and bind it to the group `gpt基地+banana2.1 high 支持2k 4k` (group ID 177). The key determines the group; do not put `group_id` in the request body.

### 2.1 Pipeline {#pipeline}

Each request runs two steps on the server; the client calls once:

1. **GPT draft:** GPT Image 2.5 draws a draft of about 1K from the prompt and aspect ratio. For edits it uses all of your reference images, including `https://` URLs.
2. **Banana rebuild:** depending on the model, Banana 2.0 (`gpt-image-2.5-banana2`), Banana 2.1 (`gpt-image-2.5-banana2.1`) or Banana Pro (`gpt-image-2.5-banana-pro`) rebuilds the draft at the target size and ratio. The rebuild also receives:
    - your original `prompt`, used to spell any text visible in the image correctly;
    - for edits, your uploaded reference images (multipart files, or `data:` URLs in `images[].image_url`), up to 6, downscaled to a 1536 px long edge, so logos, text, faces and fine details match the originals. Remote `https://` reference URLs are used only by the first step and are not passed to the rebuild.

Composition, subjects and legible text are generally kept. The second step is an **AI rebuild, not a pixel-exact upscale**, so details are redrawn. Put the exact text you want in quotes in the prompt; see [Results and known limitations](#limits).

### 2.2 Models {#models}

This group offers three models. All use GPT Image 2.5 for the draft; the model picks Banana 2.0, 2.1 or Pro for the rebuild. `GET https://yyds.seqnode.com/v1/models` (same authentication header) returns all three ids. Any other model name returns 400 `invalid_model`.

| Model | Second step | Price (every resolution) | Default thinking |
| --- | --- | --- | --- |
| `gpt-image-2.5-banana2` | Banana 2.0 (Nano Banana 2 / gemini-3.1-flash-image) | $0.05 per image | Not sent; set via [`generationConfig`](#generation-config) |
| `gpt-image-2.5-banana2.1` | Banana 2.1 (Nano Banana 2.1) | $0.06 per image | Requests High; effect depends on the upstream channel |
| `gpt-image-2.5-banana-pro` | Banana Pro (Nano Banana Pro / gemini-3-pro-image) | $0.065 per image | Not sent; set via [`generationConfig`](#generation-config) |

2.1 requests Thinking High by default; whether it takes effect depends on the upstream channel. 2.0 and Pro send no thinking level by default; you can set one in `generationConfig`.

2.0 is usually faster and cheaper. The examples on this page use 2.1; to use 2.0, change only `model`.

## 3 Endpoints and parameters {#endpoints}

| Method and path | Purpose | Body |
| --- | --- | --- |
| `POST /v1/images/generations` | Text to image | JSON |
| `POST /v1/images/edits` | Image edit, up to 15 references | `multipart/form-data` or JSON |
| `GET /v1/models` | List models | None |

Common parameters for both generation endpoints:

| Parameter | Required | Notes |
| --- | --- | --- |
| `model` | Yes | `gpt-image-2.5-banana2`, `gpt-image-2.5-banana2.1` or `gpt-image-2.5-banana-pro`; see [Models](#models) |
| `prompt` | Yes | Subject, scene and style; for edits, the change you want |
| `size` | No | `1K` / `2K` / `4K` or `WIDTHxHEIGHT`; see [Size and ratio](#size). Defaults to 1K 1:1 |
| `n` | No | Must be `1` or omitted |
| `response_format` | No | Omitted: returns a `url` (default). `b64_json` / `base64`: returns Base64. `url`: returns a link. `url` is recommended for 4K |
| `quality` | No | Accepted, but does not change the output size |
| `generationConfig` | No | Banana-stage options; see [generationConfig](#generation-config) |

### 3.1 Text to image: JSON {#generations}

**Endpoint:** `POST /v1/images/generations`, `Content-Type: application/json`.

``` json
{
  "model": "gpt-image-2.5-banana2.1",
  "prompt": "竖版音乐节海报，标题 SUMMER WAVE 2026，霓虹配色，排版清晰",
  "size": "2048x3072",
  "n": 1
}
```

`2048x3072` is 2:3 with a 3072 long edge, so it falls in the 2K tier.

### 3.2 Image edit: file upload {#edits-multipart}

**Endpoint:** `POST /v1/images/edits`, `multipart/form-data`. Send reference images in `image` or `image[]` file fields, one field per image, up to 15. Other parameters are the same as for text to image and are sent as form fields. The first 6 images are also given to the Banana rebuild to restore text, logos, faces and other details.

``` bash
curl --max-time 300 "https://yyds.seqnode.com/v1/images/edits" \
  -H "Authorization: Bearer $YM2API_KEY" \
  -F "model=gpt-image-2.5-banana2.1" \
  -F "prompt=保留图1的人物，采用图2的配色，白色背景" \
  -F "image[]=@reference-1.png" \
  -F "image[]=@reference-2.png" \
  -F "size=2048x2048" \
  -o response.json
```

### 3.3 Image edit: image URL / data URL {#edits-json}

**Endpoint:** `POST /v1/images/edits`, JSON. Put references in `images[].image_url` as a complete data URL or a public HTTPS image link (the link must return the image file directly). Data-URL references (up to 6) are also given to the Banana rebuild; HTTPS links are used only for the GPT draft. Prefer data URLs or file uploads when details must match. This example explicitly requests Base64.

``` json
{
  "model": "gpt-image-2.5-banana2.1",
  "prompt": "保留图1的主体，采用图2的配色，白色背景",
  "images": [
    {"image_url": "https://YOUR_IMAGE_HOST/reference-1.png"},
    {"image_url": "data:image/png;base64,YOUR_REFERENCE_2_BASE64"}
  ],
  "size": "2048x2048",
  "n": 1,
  "response_format": "b64_json"
}
```

### 3.4 generationConfig: tune the Banana stage (optional) {#generation-config}

`generationConfig` is a Gemini-native object that is merged only into the second (Banana rebuild) request; it does not affect the GPT Image 2.5 draft. Send it as an object in JSON requests, or as a JSON string in a multipart field of the same name.

| Key | Notes |
| --- | --- |
| `thinkingConfig.thinkingLevel` | Thinking level, e.g. `"High"`. 2.1 requests Thinking High by default; whether it takes effect depends on the upstream channel; 2.0 and Pro send none by default and can set one here |
| `temperature`, `topP`, `topK`, `seed` | Sampling parameters |
| `imageConfig.imageSize` | `"1K"` / `"2K"` / `"4K"`; can replace the tier in `size` |
| `imageConfig.aspectRatio` | One of the [10 supported ratios](#size-rules); can replace the ratio in `size` |

Service rules: `responseModalities` always includes IMAGE; `candidateCount` is ignored (always one image); `includeThoughts` is always false. If `imageConfig` and `size` are both given and disagree, the request returns 400 (`conflicting_aspect_ratio` / `conflicting_image_size`). Invalid JSON, an array, or more than 16 KB returns 400 `invalid_generation_config`.

JSON example (2.1, Thinking High, temperature 0.7, 2K 16:9, `imageConfig` instead of `size`):

``` json
{
  "model": "gpt-image-2.5-banana2.1",
  "prompt": "雨夜霓虹街道，招牌写着 \"OPEN 24H\"，电影感，细节清晰",
  "n": 1,
  "generationConfig": {
    "thinkingConfig": {
      "thinkingLevel": "High"
    },
    "temperature": 0.7,
    "imageConfig": {
      "imageSize": "2K",
      "aspectRatio": "16:9"
    }
  }
}
```

Multipart example (2.0 with thinking enabled, 4K):

``` bash
curl --max-time 300 "https://yyds.seqnode.com/v1/images/edits" \
  -H "Authorization: Bearer $YM2API_KEY" \
  -F "model=gpt-image-2.5-banana2" \
  -F "prompt=保留参考图的构图和文字，细节更清晰" \
  -F "image=@reference.png" \
  -F 'generationConfig={"thinkingConfig":{"thinkingLevel":"High"},"imageConfig":{"imageSize":"4K"}}' \
  -o response.json
```

### 3.5 Not supported {#unsupported}

- Streaming (`stream`) is not supported and returns 400 `stream_not_supported`.
- Only 1 image per request; `n` greater than 1 returns 400. Send separate requests for more images.
- There are no Chat Completions, Responses or Messages endpoints; use only the Images endpoints above.

## 4 Size, ratio and actual output {#size}

### 4.1 Writing size {#size-rules}

- **`1K` / `2K` / `4K`:** picks the tier directly, at 1:1.
- **`WIDTHxHEIGHT`:** for example `2048x1152`. Width and height set the ratio and the tier: long edge ≤ 1600 is 1K; ≤ 3200 is 2K; larger is 4K. Each side is limited to 6000.
- **Omitted:** 1K 1:1.

Supported ratios: 1:1, 3:2, 2:3, 4:3, 3:4, 5:4, 4:5, 16:9, 9:16, 21:9, with about 3% tolerance. Other ratios return 400 `unsupported_aspect_ratio`; images are not cropped or stretched automatically.

| Desired output | `size` example |
| --- | --- |
| 1K square | omit, or `1K`, `1024x1024` |
| 2K landscape 16:9 | `2048x1152` |
| 2K portrait 2:3 | `2048x3072` |
| 4K square | `4K` or `4096x4096` |
| 4K landscape 16:9 | `3840x2160` |
| 4K portrait 9:16 | `2160x3840` |

### 4.2 Measured output pixels {#measured}

`size` sets the ratio and tier. **The actual pixels are whatever the returned image has** and may differ from the requested width and height. Measured results:

| Request | Actual output |
| --- | --- |
| 1K 1:1 | 1024×1024 |
| 2K 16:9 (`2048x1152`) | 2752×1536 |
| 4K 1:1 (`4096x4096`) | 4096×4096 |
| 4K 2:3 | 3392×5056 |
| 4K 3:2 | 5056×3392 |

If you need an exact size, resize or crop after downloading.

## 5 Reading the response and saving the image {#response}

Response when `response_format` is omitted or set to `"url"` (the link is a placeholder):

``` json
{
  "created": 1792242895,
  "data": [{"url": "https://img.yydsbest.com/YOUR_IMAGE_ID"}],
  "size": "2752x1536",
  "output_format": "png",
  "quality": "high"
}
```

- `data[0].url`: returned by default; a site-hosted image link **kept for 1 hour**. Download it promptly, without your API key.
- `data[0].b64_json`: returned when you explicitly set `response_format: "b64_json"` (or `"base64"`); decode and save it. A 4K Base64 response can reach 20--30 MB, so `url` is recommended for 4K.
- `size`: the actual output pixels.
- `output_format`: informational only, usually `jpeg`; files delivered by the site may be PNG-encoded. Check the file header when saving: `89 50 4E 47` is PNG, `FF D8 FF` is JPEG.

The Python and PowerShell quick-start examples already download, detect the format and save the image.

## 6 Latency, billing and timeouts {#billing}

| Tier | Typical time |
| --- | --- |
| 1K | about 60 s |
| 2K | about 60--75 s |
| 4K | about 90--105 s |

The table shows typical times for 2.1; 2.0 is usually faster. The response arrives only after both steps finish, so it takes noticeably longer than a single generation. Set the client timeout to **at least 300 seconds**. After a timeout, check your usage records before resubmitting to avoid duplicate images.

**Billing:** 2.0 $0.05 per image, 2.1 $0.06 per image, Pro $0.065 per image (same price at every resolution); failed requests are not charged. Your usage records show the actual charge.

## 7 Error codes {#errors}

Error responses are JSON. Read `error.message`, and use `error.code` when present as listed below. Some parameters (such as `n` and the aspect ratio) may be checked by the gateway first; those responses only contain `error.type`, `error.message` and `error.request_id`, without `code`, so use the HTTP status and the message.

| HTTP | `error.code` | Cause and action |
| --- | --- | --- |
| 400 | `invalid_model` | Model is not `gpt-image-2.5-banana2`, `gpt-image-2.5-banana2.1` or `gpt-image-2.5-banana-pro`; see [Models](#models) |
| 400 | `invalid_image_count` | `n` is not 1; set it to 1 or omit it |
| 400 | `stream_not_supported` | Remove `stream` |
| 400 | `invalid_image_size` | Malformed `size` or a side over 6000 |
| 400 | `conflicting_aspect_ratio` | `generationConfig.imageConfig.aspectRatio` disagrees with the ratio in `size`; keep only one |
| 400 | `conflicting_image_size` | `generationConfig.imageConfig.imageSize` disagrees with the tier in `size`; keep only one |
| 400 | `invalid_generation_config` | `generationConfig` is not a valid JSON object (e.g. an array) or exceeds 16 KB |
| 400 | `unsupported_aspect_ratio` | Ratio not supported; use a [supported ratio](#size-rules) |
| 400 | `missing_prompt` | `prompt` is empty |
| 400 | `missing_image` | `/v1/images/edits` called without a reference image |
| 400 | `invalid_image_request` | Invalid draft request; fix it as the `message` says |
| 400 | `image_safety_rejected` | Failed the image safety check; change the prompt or references |
| 413 | `image_too_large` | Uploaded reference too large; compress it and retry |
| 429 | `image_channel_busy` | Channel busy; retry later with less concurrency |
| 502 | `image_generation_failed` | GPT draft failed; retry later |
| 502 | `banana_rebuild_failed` | Banana rebuild failed; retry later |
| 502 | `image_upstream_error` | Temporary channel error; retry later |
| 504 | `image_generation_timeout` | Timed out; check usage records before retrying |

For 401 / 403, check that the Bearer key is correct and bound to group 177. When reporting a problem, include the model, request time, HTTP status and `request_id`; never put your API key in screenshots or public logs.

## 8 Results and known limitations {#limits}

From comparison tests of GPT drafts and rebuilt results:

- **Good for:** portraits, anime, typographic posters and legible text. Composition, identity, art style and readable text (Chinese, Japanese, English) are generally kept and become sharper.
- **Put the text you want in the prompt:** the rebuild reads your original `prompt` to spell visible text correctly. Quote the exact wording, for example: a sign reading "OPEN 24H".
- **Edit details:** uploaded files or data-URL references (first 6) are given to the rebuild, so logos, text, faces and details follow the references. `https://` reference links are not used by the rebuild.
- **Unnamed tiny text is still a risk:** the risk is lower for text named in the prompt. Blurry small text that neither the prompt nor the references can determine is kept soft rather than invented, but tiny text or numbers the prompt does not mention (watch faces, packaging fine print) may still differ from the intent.
- **Color:** the result may be slightly warmer overall.
- **Precise details:** check product appearance, packaging text and logos item by item; if needed, generate directly with [Banana 2.1](group139-banana21-api.html) at the target size.

[Comparison examples (6 prompts: original / Lanczos / Banana 2K / 4K)](compare/image2-banana21-v2/index.html)

[Compared with GPT Image 2.5 Flare / Sunburst 4K (4 prompts)](compare/banana-vs-flare-sunburst/index.html)

This group is not suitable when you need a pixel-faithful upscale.
