# Nano Banana Pro API：Python で呼ぶ手順と画像編集、料金

> Nano Banana Pro API を Python で呼ぶ手順。モデル ID、編集フィールド、1K/2K/4K の選び方、1 枚あたりの料金と返ってくる JSON を解説。

- Canonical HTML: https://omniakey.com/ja/blog/nano-banana-pro-api
- Markdown: https://omniakey.com/ja/blog/nano-banana-pro-api.md
- Published: 2026-11-03 (updated 2026-11-03)
- Author: Kiki, COO at OmniaKey
- Language: ja
- Category: API setup
- Reading time: 9 min
- All posts: https://omniakey.com/blog/llms.txt

---

Nano Banana Pro は Google の `gemini-3-pro-image` です。OmniaKey なら `POST /v1/media/tasks` を 1 回投げるだけで呼べます。3:4 で 3 枚試したところ、返ってきたのは 896x1200、1792x2400、3584x4800 で、ポスターの文字はすべて正しく綴られていました。

## 先に結論

- **モデル：** `gemini-3-pro-image` が Google の GA モデル ID です。Vertex のモデルカードでは公開日が 2026 年 5 月 28 日になっています。
- **呼び方：** `POST https://api.omniakey.com/v1/media/tasks` に `Idempotency-Key` を付けて送り、`GET /v1/media/tasks/{id}` を succeeded になるまでポーリングし、`assets[0].url` をダウンロードします。
- **パラメータ：** `parameters.aspect_ratio` と `parameters.image_size` です。サイズは 1K、2K、4K で、K は大文字で書きます。
- **リクエスト上限：** ボディ全体で 1 MiB です。インラインの Base64 画像も含みます。
- **Google の料金：** 1K/2K が 1 枚 $0.134、4K が 1 枚 $0.24 です。Google の Gemini API 料金ページの数字です。
- **実際のトークン数：** 3 つのタスクは 1,133、1,225、2,480 の出力トークンを報告しました。画像トークン 100 万あたり $120 で計算すると、$0.136、$0.147、$0.298 になります。
- **編集：** `operation: "edit"` を指定し、元画像を `input.image` に `{data, mime_type}` の形で入れます。

OmniaKey の [Nano Banana Pro モデルページ](https://omniakey.com/ja/gemini-3-pro-image) では、旧スナップショット ID の `gemini-3-pro-image-preview` も同じ料金で使えます。

## モデル ID と用意するもの

コードに書くのは `gemini-3-pro-image` です。Google の [Vertex モデルカード](https://cloud.google.com/vertex-ai/generative-ai/docs/models/gemini/3-pro-image) では GA として掲載され、公開日は 2026 年 5 月 28 日、1K・2K・4K の出力に対応します。

`gemini-3-pro-image-preview` は同じモデルを指す ID です。OmniaKey の [画像モデルの表](https://docs.omniakey.com/en/media/image) でも "Same model, -preview snapshot id" と書かれ、1 回あたりの料金も同じです。

用意するものは 2 つです。

1. OmniaKey の API キー。環境変数に入れておきます：`export OMNIAKEY_API_KEY="your-key"`。
2. Python 3。下のスクリプトは標準ライブラリだけで動きます。urllib、json、time、uuid、base64、pathlib を使い、SDK のインストールは不要です。

## Python スクリプトの動かし方

手順は 3 つです。タスクを作り、状態をポーリングし、画像をダウンロードします。`nano_banana.py` として保存し、`python3 nano_banana.py` で実行してください。

```python
import base64
import json
import os
import time
import urllib.request
import uuid
from pathlib import Path

API = "https://api.omniakey.com/v1/media/tasks"
HEADERS = {
    "Authorization": f"Bearer {os.environ['OMNIAKEY_API_KEY']}",
    "Content-Type": "application/json",
}


def call(url, payload=None, headers=None, method=None):
    body = json.dumps(payload).encode() if payload is not None else None
    req = urllib.request.Request(url, data=body, headers=headers or HEADERS, method=method)
    with urllib.request.urlopen(req, timeout=60) as resp:
        return resp.status, json.loads(resp.read())


def create_task(prompt, aspect_ratio="3:4", image_size="2K", image_path=None):
    body = {
        "model": "gemini-3-pro-image",
        "type": "image",
        "operation": "generate" if image_path is None else "edit",
        "input": {"prompt": prompt},
        "parameters": {"aspect_ratio": aspect_ratio, "image_size": image_size},
    }
    if image_path:
        encoded = base64.b64encode(Path(image_path).read_bytes()).decode("utf-8")
        body["input"]["image"] = {"data": encoded, "mime_type": "image/png"}
    headers = {**HEADERS, "Idempotency-Key": str(uuid.uuid4())}
    status, task = call(API, body, headers, "POST")
    print("created", task["id"], "HTTP", status)
    return task


def wait(task_id, interval=3, timeout=300):
    deadline = time.time() + timeout
    while time.time() < deadline:
        _, task = call(f"{API}/{task_id}")
        print(task["status"], task["progress"]["percent"])
        if task["status"] in ("succeeded", "failed", "canceled"):
            return task
        time.sleep(interval)
    # A timeout is not a failure: keep the task id and poll it again.
    raise TimeoutError(f"task {task_id} is still running")


def download(task, out_path):
    asset = task["assets"][0]
    with urllib.request.urlopen(asset["url"], timeout=120) as resp:
        Path(out_path).write_bytes(resp.read())
    print("saved", out_path, asset["mime_type"], asset["byte_size"], "bytes")


if __name__ == "__main__":
    task = create_task(
        "A vintage travel poster for the Night Train from Zürich to Milano, "
        "departing 21:40 from platform 7. A steam train crosses a stone arch "
        "bridge below snowy mountains under a deep blue night sky, with a cream "
        "border. Spell every word exactly as written.",
        aspect_ratio="3:4",
        image_size="2K",
    )
    task = wait(task["id"])
    if task["status"] != "succeeded":
        raise SystemExit(f"{task['status']}: {task.get('error')}")
    download(task, "night-train.jpg")
```

`image_size` に書けるのは 1K、2K、4K のどれかです。Google の画像ガイドは「K は大文字で書くこと。小文字のパラメータ（1k など）は拒否されます」とはっきり書いています。2k ではなく 2K を送ってください。

`Idempotency-Key` は必須です。リクエストごとに新しい UUID を振るのがいちばん簡単です。同じキーを使い回すのは、まったく同じボディを再送するときだけにしてください。OmniaKey は元のタスクを HTTP 200 で返すので二重課金になりません。同じキーでボディが違う場合は 409 が返ります。

作成リクエストは 202 と id を返します。OmniaKey の [メディアタスクのドキュメント](https://docs.omniakey.com/en/media/overview) に流れが全部書いてあります。完了したタスクは、次のフィールドを持っています。

```json
{
  "id": "task_AbMRVqzSnVh0VwBj0S7NuMUxy5sZtfHP",
  "status": "succeeded",
  "progress": {"percent": 100, "stage": "completed"},
  "usage": {"total_tokens": 1133},
  "assets": [
    {
      "kind": "image",
      "mime_type": "…",
      "url": "https://…signed-url…"
    }
  ]
}
```

`assets[0].url` を読んだら、その場でダウンロードします。署名付きリンクの有効期限は 1 時間ほどで、タスクの記録は 24 時間残ります。形式は `mime_type` で分かります。Gemini のモデルはたいてい JPEG を返します。

同じスクリプトを 1:1・2K にして、中国語の看板を頼むとこうなります。

![れんが壁に掛けた黒い金属の看板。中国語の 3 行と電話番号が入っている](https://omniakey.com/_img/blog/nano-banana-pro-api/g2-sign.7e3e8e4d.1600.webp)

_2K・1:1：2048x2048、47.2 秒。中国語の 3 行と 010-6789 4321 はすべて正しく、最初の 0 の一部は錆で隠れています。_

## 既存の画像を編集する

`operation: "edit"` を指定し、元画像を `input.image` に `{data, mime_type}` の形で渡します。上のスクリプトは `image_path` を渡すだけでこの経路を通ります。

```python
task = create_task(
    "Hang this poster in a thin black frame on a warm white wall, with a brass "
    "picture light above it, a low wooden cabinet below and a trailing plant on "
    "the right. Keep the poster exactly as it is.",
    aspect_ratio="1:1",
    image_size="2K",
    image_path="night-train-2k.png",
)
```

実際に送られるボディは次のとおりです。

```json
{
  "model": "gemini-3-pro-image",
  "type": "image",
  "operation": "edit",
  "input": {
    "prompt": "Hang this poster in a thin black frame on a warm white wall…",
    "image": {"data": "…base64…", "mime_type": "image/png"}
  },
  "parameters": {"aspect_ratio": "1:1", "image_size": "2K"}
}
```

例の元画像は PNG なので、スクリプトは `image/png` を付けます。JPEG ならこの値を変えてください。参照画像を複数使うときは `input.images` に、同じ `{data, mime_type}` の形で並べます。Google のガイドでは参照画像は最大 14 枚です。`gemini-3-pro-image` の場合、内訳は物体 6 枚、人物 5 枚、スタイル参照 3 枚です。

ボディは 1 MiB 以内に収めます。Base64 にするとファイルは 3 割ほど大きくなるので、エンコードの前に元画像を縮小するか圧縮してください。今回の編集では 2K のポスターを使い、文字もレイアウトもそのまま残りました。

![壁に掛けた黒い額縁に入った夜行列車のポスター。上にピクチャーライト、右に観葉植物](https://omniakey.com/_img/blog/nano-banana-pro-api/g3-edit.98011b5c.1600.webp)

_2K・1:1 の編集：2048x2048、49.9 秒。ポスターの文字とデザインはそのまま残り、額縁はきれいな長方形になりました。_

## 1K・2K・4K で何が変わるか

同じ 3:4 のポスターのプロンプトを、3 つのサイズで 1 回ずつ実行しました。画素数は Google の 3:4 の表とぴったり一致しました。1K が 896x1200、2K が 1792x2400、4K が 3584x4800 です。ポスターの文字はどのサイズでも正しく出ました。

![1K の夜行列車ポスター。石橋を渡る蒸気機関車、雪山、濃い青の夜空](https://omniakey.com/_img/blog/nano-banana-pro-api/g1-1k.12bc0ed0.896.webp)

_1K・3:4：896x1200、28.4 秒。ポスターの 4 行はすべて正しく、機関車のランプとロッドは詰まって見えます。_

![同じ夜行列車ポスターの 2K 版。右の斜面に村と 2 本の尖塔が増えている](https://omniakey.com/_img/blog/nano-banana-pro-api/g1-2k.38a932bb.1600.webp)

_2K・3:4：1792x2400、48.2 秒。文字は同じで、右の斜面に村と尖塔が 2 本増えました。_

![同じ夜行列車ポスターの 4K 版。機関車の後ろに客車 3 両と炭水車が描かれている](https://omniakey.com/_img/blog/nano-banana-pro-api/g1-4k.6c8048ad.1600.webp)

_4K・3:4：3584x4800、66.9 秒。客車 3 両と炭水車まで描かれ、れんがの目地は太さがまちまちです。_

サイズで変わるのは細部で、文字の正確さは同じです。

- **1K：** 機関車の正面が込み合います。ランプ、車輪、連接棒が近寄って並びます。
- **2K：** 右の斜面に村と 2 本の尖塔が出て、煙突から淡い煙が上がり、石橋にはアーチが 7 つ見えます。
- **4K：** 客車 3 両と炭水車が分かれて描かれ、石積みの目地にも太さの差が出ます。機関車の下の機械は単純なままです。

時間もサイズに比例して伸びました。28.4 秒、48.2 秒、66.9 秒です。各サイズ 1 回だけの実行なので、この秒数は 1 回分の結果として読んでください。

Google は画像出力を 100 万トークンあたり $120 で計算し、表では 1K と 2K が 1,120 トークン、4K が 2,000 トークンです。これが Google 自身の見積もりになります。

```text
1,120 × $120 ÷ 1,000,000 = $0.134 per 1K image
1,120 × $120 ÷ 1,000,000 = $0.134 per 2K image
2,000 × $120 ÷ 1,000,000 = $0.24  per 4K image
```

こちらのタスクは Google の例より多くのトークンを報告しました。同じ計算を実測値でやるとこうです。

```text
1,133 × $120 ÷ 1,000,000 = $0.136 per 1K image
1,225 × $120 ÷ 1,000,000 = $0.147 per 2K image
2,480 × $120 ÷ 1,000,000 = $0.298 per 4K image
```

|サイズ|画素数（3:4）|実測の時間|実測トークン|Google の見積もり|
|-|-|-|-|-|
|1K|896x1200|28.4 秒|1,133|$0.134|
|2K|1792x2400|48.2 秒|1,225|$0.134|
|4K|3584x4800|66.9 秒|2,480|$0.24|

OmniaKey は画像 1 回につき定額で、トークンでは課金しません。だから上のトークン数が増えても請求額は変わりません。現在の 1 回あたりの料金は [モデルページ](https://omniakey.com/ja/gemini-3-pro-image) にあり、失敗したタスクは返金されます。同じ 3 枚を Google のトークン単価で見積もると $0.134、$0.134、$0.24 です。

## よく出るエラー

ここで挙げる失敗の多くは、フィールド名かファイルサイズの問題で、モデル自体の問題ではありません。OmniaKey のメディアのドキュメントに載っているものを並べます。

|HTTP|コードまたは状態|意味|対処|
|-|-|-|-|
|400|`invalid_request`|ボディの形式、未対応の操作、パラメータの誤り|JSON と下のフィールド名を確認する|
|503|`no_available_channel`|このモデルを扱うチャネルが今ない|モデルを変える。再試行しても直りません|
|—|`failed`|タスクは終わったが結果がない|`error.code` と `error.message` を読む|

`failed` は HTTP エラーではありません。作成リクエストは成功しているので、タスクをポーリングして `error` オブジェクトを読んでください。失敗とキャンセルのタスクは自動で返金されます。

元画像をそのまま Base64 にすると、ボディが 1 MiB を超えやすくなります。先に縮小し、ファイルサイズではなくエンコード後の長さを確認してください。

Google のガイドは小文字の `1k` を拒否します。1K、2K、4K のどれかを書いてください。

OmniaKey の画像のドキュメントも、Gemini モデルでは `size` とトップレベルの `mime_type` を拒否します。どちらも Gemini のパラメータではないためです。代わりに `parameters.aspect_ratio` と `parameters.image_size` を使い、出力形式はレスポンスの `mime_type` から読み取ってください。

## よくある質問

### Nano Banana Pro API のモデル ID は？

`gemini-3-pro-image` です。Google の Vertex モデルカードでは GA と公開日 2026 年 5 月 28 日が書かれていて、OmniaKey も同じ ID を受け付けます。旧 ID の `gemini-3-pro-image-preview` も OmniaKey では使えて、同じモデルを指します。

### Nano Banana Pro の画像 1 枚はいくら？

Google の見積もりは 1K/2K が $0.134、4K が $0.24 です。画像トークン 100 万あたり $120 で計算しています。こちらのタスクは 1,133、1,225、2,480 トークンだったので、同じ単価なら $0.136、$0.147、$0.298 です。OmniaKey はモデルページに 1 回あたりの料金を出しています。

### Nano Banana Pro は中国語の文字も描けますか？

描けます。2K の看板は中国語 3 行が正しく返ってきました。同福客栈、住宿 餐饮 茶水、010-6789 4321 で、11 桁の数字とハイフンも合っています。

### 1K・2K・4K のどれを選べばいい？

今回のようなポスターなら、2K が使いやすい真ん中です。3 サイズとも文字は正しく出たので、4K で増えるのは細部（客車が分かれる、れんがの目地が見える）で、文字の正確さではありません。896x1200 で足りる下書きなら 1K が速いです。

### 編集で 400 invalid\_request が返るときは？

ボディが 1 MiB を超えていないか、元画像が正しいフィールドに入っているか、Gemini モデルに `size` やトップレベルの `mime_type` を送っていないかを確認します。画像は `input.image` に `{data, mime_type}` の形で入れ、エンコード後のボディを 1 MiB 未満に保ち、パラメータは `aspect_ratio` と `image_size` だけにしてください。

## 出典

- [Google Cloud：Gemini 3 Pro Image のモデルカード](https://cloud.google.com/vertex-ai/generative-ai/docs/models/gemini/3-pro-image) — 2026 年 11 月 3 日確認。
- [Google：Gemini API の画像生成ガイド](https://ai.google.dev/gemini-api/docs/image-generation) — 2026 年 11 月 3 日確認。
- [Google：Gemini API の料金](https://ai.google.dev/gemini-api/docs/pricing) — 2026 年 11 月 3 日確認。
- [Google：Nano Banana Pro の発表](https://blog.google/technology/ai/nano-banana-pro/) — 2026 年 11 月 3 日確認。

## 更新履歴

- 2026-11-03：初版。同日、OmniaKey 経由で 5 回のテスト実行。
