# Nano Banana Pro APIの使い方：公式JSON、YAML、PDF入力を整理

> 現行の公式model IDと動くJSONを起点に、YAML設定、response parser、PDFの安全な2段階経路、providerとの契約差を整理します。

- URL: https://blog.laozhang.ai/ja/posts/nano-banana-pro-api-guide
- Published: 2026-04-01
- Updated: 2026-07-20
- Author: AI Free API Team (https://blog.laozhang.ai/ja/about)
- Category: API ガイド
- Tags: Nano Banana Pro, Gemini 3 Pro Image, Gemini API, JSON, YAML, PDF, laozhang.ai

---
Nano Banana ProをGoogleへ直接リクエストする現在の正解は、モデル **Gemini 3 Pro Image**、model ID `gemini-3-pro-image`、endpoint `POST https://generativelanguage.googleapis.com/v1beta/interactions` の組み合わせです。新規実装では、Googleが最新モデル・機能向けに推奨する **Interactions API** を先に選びます。`generateContent` は現在も使えますが、互換・従来surfaceとして別のrequest/response contractのまま扱います。

まずは次の最小requestで、接続するcontractを固定できます。

```bash
curl -sS -X POST \
  "https://generativelanguage.googleapis.com/v1beta/interactions" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3-pro-image",
    "input": [
      {
        "type": "text",
        "text": "黒いメカニカルキーボードの商品画像。斜め30度の俯瞰、無彩色の背景、柔らかなリムライト。文字、ロゴ、透かしは入れない。"
      }
    ],
    "response_format": {
      "type": "image",
      "mime_type": "image/png",
      "aspect_ratio": "16:9",
      "image_size": "2K"
    }
  }'
```

このJSONはGoogle公式APIのtransportです。一方、いわゆる「JSON prompt」はチーム独自の制作briefであることが多く、Googleが品質向上を保証する公式prompt schemaではありません。YAMLもそのままAPIへ送る形式ではなく、型検査してJSONへ変換するためのアプリ設定です。

![Nano Banana Pro APIでYAMLをJSONへ変換し、PDFを別の文書処理経路に分け、最終画像を取得する流れ](https://blog.laozhang.ai/posts/ja/nano-banana-pro-api-guide/img/cover.webp)

本ページのfield、価格、制限は2026年7月20日に[Googleの画像生成ガイド](https://ai.google.dev/gemini-api/docs/image-generation?hl=ja)、[Gemini 3 Pro Image model card](https://ai.google.dev/gemini-api/docs/models/gemini-3-pro-image?hl=ja)などで再確認しました。今回はtask専用のcredentialと課金許可がないため、有料生成callは実施していません。サンプルはsource上のcontractとlocal syntaxを確認したもので、実生成品質のbenchmarkではありません。

## 実装前に固定する「完成形」

一つの画像生成jobを、次の4層に分けます。

1. **Semantic brief**：何を描き、何を維持し、何を禁止するか。アプリが所有する。
2. **Official JSON**：Google Interactions APIへ送るHTTP body。Googleが所有する。
3. **App YAML**：編集しやすい設定。アプリがparse・validateしてJSONへ変換する。
4. **Provider mapping**：gatewayを選ぶ場合の別contract。providerがendpoint、key、price、responseを所有する。

この順序を逆にして、検索で見つけたprovider JSONをGoogle endpointへ貼ると、model名が似ていても400/401/404やparser mismatchになります。

## Semantic prompt objectを自然文へ落とす

制作チームでは、promptを最初から1本の文字列にせず、次のような独自objectにすると検査しやすくなります。

```json
{
  "job": "product_hero",
  "subject": {
    "product": "黒いメカニカルキーボード",
    "must_preserve": ["筐体形状", "キー配列"]
  },
  "scene": {
    "camera": "斜め30度の俯瞰",
    "background": "無彩色のスタジオ背景",
    "lighting": "柔らかなリムライト"
  },
  "constraints": {
    "exact_text": [],
    "avoid": ["ロゴ", "余分なキー", "透かし"]
  }
}
```

これはofficial schemaではありません。アプリ側で例えば次の順に自然文へrenderします。

> 黒いメカニカルキーボードの商品画像。筐体形状とキー配列を維持する。斜め30度の俯瞰、無彩色のスタジオ背景、柔らかなリムライト。ロゴ、余分なキー、透かしは入れない。

最終文字列を`input[].text`へ入れ、画像設定を`response_format`へ置くと、意味とtransportを混同しません。Structured Outputsはresponse JSONを制約する機能であり、画像prompt用の公式JSON schemaが存在する証拠にはなりません。

## Official JSONとapp YAMLを同じjobで比較する

### Google Interactions APIへ送るJSON

```json
{
  "model": "gemini-3-pro-image",
  "input": [
    {
      "type": "text",
      "text": "黒いメカニカルキーボードの商品画像。筐体形状とキー配列を維持する。斜め30度の俯瞰、無彩色のスタジオ背景、柔らかなリムライト。ロゴ、余分なキー、透かしは入れない。"
    }
  ],
  "response_format": {
    "type": "image",
    "mime_type": "image/png",
    "aspect_ratio": "16:9",
    "image_size": "2K"
  }
}
```

### 人が編集するYAML

```yaml
route:
  owner: google
  contract: interactions
  endpoint: https://generativelanguage.googleapis.com/v1beta/interactions
  key_owner: google-ai-studio-project
request:
  model: gemini-3-pro-image
  prompt:
    subject: 黒いメカニカルキーボード
    must_preserve:
      - 筐体形状
      - キー配列
    camera: 斜め30度の俯瞰
    background: 無彩色のスタジオ背景
    lighting: 柔らかなリムライト
    avoid:
      - ロゴ
      - 余分なキー
      - 透かし
  output:
    mime_type: image/png
    aspect_ratio: "16:9"
    image_size: 2K
response:
  parser: interactions-final-image
```

YAMLを使う場合は、`aspect_ratio`の`16:9`を文字列として保持し、booleanやnumberが意図せずstring化していないか確認します。API keyはYAMLやrepositoryへ書かず、server-side secret storeからheaderへ注入します。最後にYAMLの独自fieldをそのまま送るのではなく、上のofficial JSONへ明示的にmapします。

## 6項目のmismatch validator

課金前のpreflightでは、endpointだけでなく6項目を一組で検査します。

| # | 検査field | Google directの期待値 | mismatch例 |
| ---: | --- | --- | --- |
| 1 | `endpoint` | Googleの`/v1beta/interactions` | provider URLとGoogle parserを混在 |
| 2 | `key_owner` | AI Studio / Google Cloud project | provider keyを`x-goog-api-key`へ投入 |
| 3 | `model` | `gemini-3-pro-image` | 古い`-preview`やprovider alias |
| 4 | `request_contract` | `input`を使うInteractions | `contents[].parts[]`を貼り付け |
| 5 | `output_contract` | `response_format`とsnake_case | `generationConfig.imageConfig`を混在 |
| 6 | `response_parser` | Interactionsのfinal output/steps | OpenAI imagesやgenerateContent parser |

```javascript
const PRO_RATIOS = new Set([
  "1:1", "2:3", "3:2", "3:4", "4:3",
  "4:5", "5:4", "9:16", "16:9", "21:9",
]);
const PRO_SIZES = new Set(["1K", "2K", "4K"]);

export function validateGooglePro(profile, body) {
  const errors = [];

  if (profile.endpoint !== "https://generativelanguage.googleapis.com/v1beta/interactions")
    errors.push("1 endpoint: Google Interactions endpointではありません");
  if (profile.key_owner !== "google-ai-studio-project")
    errors.push("2 key_owner: Google projectのkeyではありません");
  if (body.model !== "gemini-3-pro-image")
    errors.push("3 model: 現行の公式IDはgemini-3-pro-imageです");
  if (!Array.isArray(body.input) || !body.input.some(x => x.type === "text" && x.text))
    errors.push("4 request_contract: type=textのinputが必要です");
  if (body.response_format?.type !== "image" ||
      !PRO_RATIOS.has(body.response_format?.aspect_ratio) ||
      !PRO_SIZES.has(body.response_format?.image_size))
    errors.push("5 output_contract: type、ratio、uppercaseの1K/2K/4Kを確認してください");
  if (profile.response_parser !== "interactions-final-image")
    errors.push("6 response_parser: 別contract用parserです");

  return errors;
}
```

返り値が空になるまで送信しないのがstop ruleです。key、model、endpoint、payloadを同時に変更すると、どの修正が効いたか分からなくなります。

## responseからfinal imageだけを保存する

SDKの`output_image`は便利ですが、複雑なresponseではtextや複数のstepが混ざります。shortcutを先に確認し、なければ`model_output`のimageだけを集めて最後の1枚を採用します。thought/intermediate imageを成果物にしないためです。

```javascript
import { GoogleGenAI } from "@google/genai";
import * as fs from "node:fs";

const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });

const interaction = await ai.interactions.create({
  model: "gemini-3-pro-image",
  input: "3段階の決済フローを、日本語ラベル付きの見やすい図にする。",
  response_format: {
    type: "image",
    mime_type: "image/png",
    aspect_ratio: "16:9",
    image_size: "2K",
  },
});

function finalImage(result) {
  if (result.output_image?.data) return result.output_image;
  const candidates = [];
  for (const step of result.steps ?? []) {
    if (step.type !== "model_output") continue;
    for (const block of step.content ?? []) {
      if (block.type === "image" && block.data) candidates.push(block);
    }
  }
  return candidates.at(-1) ?? null;
}

const image = finalImage(interaction);
if (!image) throw new Error("final model outputに画像がありません");
fs.writeFileSync("nano-banana-pro.png", Buffer.from(image.data, "base64"));
```

HTTP 200でも画像がない場合は、raw responseをsecret除去後に保存し、`response_format.type`、policy/safetyのtext、`model_output`、parserのcontractを確認します。「ファイルがない」だけでupstream outageとは判断できません。

## 10種類のratioと1K〜4Kの境界

[Pro向けの現行official table](https://ai.google.dev/gemini-api/docs/image-generation?hl=ja)で確認できるsize tierは`1K`、`2K`、`4K`です。`K`は大文字で、小文字の`2k`はreject対象です。4Kは固定の4096×4096を意味せず、ratioごとのtierです。例えばofficial tableの`16:9`・4Kは5504×3072です。

Pro-specific tableの10 ratiosは次のとおりです。

| 正方形・縦長 | 横長 |
| --- | --- |
| `1:1`, `2:3`, `3:4`, `4:5`, `9:16` | `3:2`, `4:3`, `5:4`, `16:9`, `21:9` |

一般的な`ImageConfig` referenceには追加の極端なratioが見える場合がありますが、Pro-specific tableは14種類を保証していません。live routeで確認していない値をproduction allowlistへ入れないでください。

Reference imageは現行ガイドで合計最大14枚と説明され、Proのcategory guidanceはobject最大6、character最大5、style reference最大3です。同じページに「high fidelityは5枚」という別の境界もあります。14枚すべてが同じ精度で保持されると設計せず、重要度の高い入力を絞り、少数から増やすのが安全です。

## PDFを直接入れない：2段階のdocument route

`gemini-3-pro-image`のmodel cardに記載されたinputは**Text/Image**で、`document`ではありません。一方、[Geminiのドキュメント理解ガイド](https://ai.google.dev/gemini-api/docs/document-processing?hl=ja)はdocument-capable modelでPDFを扱う一般経路です。この二つを合わせても「Nano Banana ProへPDFを直接送れる」という結論にはなりません。

安全な実装は次の2段階です。

### Stage 1：PDFを理解して制作briefを確定する

1. 小さな一時PDFは`application/pdf`のinline data、大きい/再利用するPDFはFiles APIへ渡す。
2. Document-capable Gemini modelで、本文、表、必要ページ、正確な表記、図の要件をstructured dataへ抽出する。
3. 元PDFと照合し、数値・固有名詞・ページ番号を検証する。

General PDF pathの上限は50 MBまたは1000ページです。これはdocument workflowの上限であり、Pro image modelのdirect input limitではありません。HTML、Markdown、XMLなどのnon-PDFは通常textとして処理され、layoutやchart contextを失う可能性があります。

### Stage 2：検証済み情報だけを画像生成へ渡す

1. 検証済みtextからsemantic briefを組み立てる。
2. 必要なページや図だけをimageとしてrenderし、reference inputへ入れる。
3. `gemini-3-pro-image`で生成し、出力内の文字・数値を再検証する。

次の場合は処理を止めます。

- sensitive documentの保存期間、region、access policyが未承認;
- 全ページを1枚へ正確に再現するなど、image modelにdocument fidelityを要求している;
- pageが回転・不鮮明で、Stage 1のextractionを検証できない;
- MIMEを書き換えるだけでunsupported inputを通そうとしている;
- Files API resourceがprocessing中またはfailedのまま次へ進んでいる。

## keyを作れること、Free Tier、billing、quotaは別問題

2026年7月20日時点の[Google公式pricing](https://ai.google.dev/gemini-api/docs/pricing)では、Nano Banana Proのimage outputにFree Tierは表示されていません。

| Google公式lane | 1K/2K image output | 4K image output | 選択条件 |
| --- | ---: | ---: | --- |
| Standard | `$0.134` | `$0.24` | 通常のonline responseが必要 |
| Batch / Flex | `$0.067` | `$0.12` | batch/flexible processingを許容できる |

入力token、text/thinking output、grounding、retry、税などは別途コストになり得ます。BatchとFlexでimage price rowが同じでも、運用上の性質まで同じとは限りません。日本円換算は請求時の条件で変わるため、固定換算額は置きません。

[Gemini API key](https://ai.google.dev/gemini-api/docs/api-key)はAI Studioで管理され、Google Cloud projectへ紐づきます。key作成が無料でもPro outputが無料になるわけではありません。Paid useにはbillingが必要で、[billing docs](https://ai.google.dev/gemini-api/docs/billing)は一部accountで最低`$10`のprepaymentが必要になる場合を示しています。自身のbilling screenを確認してください。

[Rate limit](https://ai.google.dev/gemini-api/docs/rate-limits)はkey単位ではなくproject単位で、RPM、TPM、RPD、image-specific dimensionなどが関係します。同じprojectでkeyを増やしてもquotaは増えません。現在のlimitはAI Studio/project viewがownerであり、ブログに書かれた固定値はcapacity保証ではありません。

関連する運用手順は、[quotaの増加](https://blog.laozhang.ai/ja/posts/increase-nano-banana-pro-api-quota)、[rate limitの診断](https://blog.laozhang.ai/ja/posts/nano-banana-pro-rate-limit)、[Batch APIのコスト最適化](https://blog.laozhang.ai/ja/posts/nano-banana-pro-batch-api-cost-optimization)へ分けています。keyの作成とprojectへの紐づけは、直前のGoogle公式API keyドキュメントを参照してください。

## providerを選ぶなら、同じmodel名でも別contractとしてmapする

基準routeはGoogle directです。Gatewayは、決済方法、model switching、provider側logが要件に合う時だけ候補になります。model aliasが同じでも、key、endpoint、payload、price、failed-call rule、response parserはprovider所有です。

2026年7月20日に確認したlaozhang.aiの公開docsでは、provider aliasは`gemini-3-pro-image`、generation/editingは`$0.09/call`です。OpenAI-compatible chat routeはfixed `1:1/1K`、custom ratioと`2K/4K`はproviderの`generateContent`-compatible routeとして文書化されています。これはGoogle公式endpointや価格の証拠ではありません。

| App上の意味 | Google direct | laozhang.ai provider contract |
| --- | --- | --- |
| Key owner | AI Studio / Google project | Provider account |
| 新規実装の主route | Interactions API | Provider docsで指定されたroute |
| Model | `gemini-3-pro-image` | Provider alias `gemini-3-pro-image` |
| Custom ratio / 2K / 4K | `response_format` | Provider `generateContent`-compatible mapping |
| 1:1 / 1K | Official contract内で設定 | OpenAI-compatible chat laneはfixed |
| Price owner | Google pricing | Public docsの`$0.09/call`、最終的にはconsole |
| Parser | Interactions output/steps | 選択したprovider routeのresponse |

Provider docsには「14 ratios」やpixel rowについてGoogleのPro-specific tableとの未解決差があります。Googleの主張には上記10 ratiosを使い、provider callではlive console、model list、request logを確認します。Unlimited、failed-call refund、direct PDF、upstream parity、guaranteed concurrencyは、現行contractの証拠なしに約束できません。

## 既存のgenerateContentを保守する場合

`generateContent`は今もdocumented compatibility surfaceです。既存codeをすぐ捨てる必要はありませんが、Interactionsのfieldを混ぜないでください。

```json
{
  "contents": [
    {
      "parts": [
        {
          "text": "ロゴのない商品スタジオ画像を作成する。"
        }
      ]
    }
  ],
  "generationConfig": {
    "responseModalities": ["TEXT", "IMAGE"],
    "imageConfig": {
      "aspectRatio": "16:9",
      "imageSize": "2K"
    }
  }
}
```

Endpointは`models/gemini-3-pro-image:generateContent`を含み、requestは`contents[].parts[]`と`generationConfig`、responseはpartsを辿ります。`response_format`やInteractions用parserは使いません。Migrationでは同じprompt/ratio/sizeを固定し、endpoint、payload、parserを一つのcontract単位で切り替えます。

## 400、401、404、429、5xxを切り分ける

| Status / 症状 | 主なowner | 最初の確認 | 次の操作 |
| --- | --- | --- | --- |
| `400` malformed/invalid argument | JSON・field・type | JSON parse、casing、10-ratio allowlist、uppercase `K`、MIME | payloadだけ修正して同じrouteで再試行 |
| `401` | credential | header、key owner、restriction、project link | AI Studioでkeyを作成/移行し同じrequestを再試行 |
| `404` | endpoint/model/resource | `/v1beta/interactions`、current ID、Files URI/state | promptを変えずcontract/resourceを確認 |
| `429` | project quota/traffic | live RPM/TPM/RPD/IPM、concurrency、retry storm | backoff+jitter、concurrency削減、Batch/Flex、quota申請 |
| `500/502/503/504` | Google/provider/upstream | request ID、status、provider log、timeout | bounded retry。証拠なしにrouteを変更しない |
| `200`だが画像なし | output/parser/policy | `model_output`、output type、safety text、mixed content | parser/requestを修正し、network成功だけで完了扱いしない |

問い合わせ用の最小再現には、timestamp、contract owner、secretを除いたendpoint、model、sanitized payload、project/provider request ID、status、raw error、billing eventを残します。実API key、private image、顧客PDFはsupport logへ貼らないでください。

## 送信前チェック

- 6-field validatorが空配列を返す。
- JSON parseとYAML parse/type validationが通る。
- keyはserver-side secret storeから注入する。
- ratioはProの10-value allowlist、sizeは`1K`/`2K`/`4K`。
- endpointとresponse parserが同じcontractに属する。
- PDFは別のdocument stageを通り、抽出結果を検証済み。
- Googleの価格/quotaはGoogle、providerの価格/failed-call ruleはprovider console/logで確認。
- retry回数に上限があり、request IDとcost eventを記録する。

結論はシンプルです。まずcontract ownerを固定し、semantic briefをYAMLから検証済みJSONへ変換し、PDFだけはdocument処理へ分岐します。その後に初めて有料requestを送れば、Nano Banana Proの「JSON template」「YAML」「公式docs」「PDF problem」を一つの再現可能な実装として管理できます。
