> ## Documentation Index
> Fetch the complete documentation index at: https://dripart-chore-mintlify-theme-mint.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Comfy Router で Nano Banana Pro を使う

> Comfy Router 経由の HTTP で Nano Banana Pro（Gemini 3 Pro Image）を使って画像を生成するための Python、TypeScript、cURL スニペット、およびリクエストフィールドと結果の形状

Nano Banana Pro の API リファレンスです。Nano Banana Pro (Gemini 3 Pro Image) は、Google の Nano Banana 画像生成ファミリーの Pro ティアであり、複雑なシーンや読み取りやすいテキストを対象としています。

## クイックスタート

[お使いの Comfy ワークスペース](https://platform.comfy.org/profile/api-keys?onboarding=router)でキーを作成し、`COMFY_API_KEY` としてエクスポートします。Python、TypeScript、Swift のスニペットは Comfy SDK（`pip install comfy-sdk`、`npm install @comfyorg/sdk`、および [`ComfySwiftSDK`](https://github.com/Comfy-Org/comfy-swift-sdk) Swift パッケージ）を使用しています。cURL のスニペットは、同じ呼び出しを生の HTTP で行うものです。

**モデル ID:** `vertexai/gemini-3-pro-image`

**エンドポイント:** `POST https://api.comfy.org/v2/models/vertexai/gemini-3-pro-image`

<Tabs>
  <Tab title="結果を待つ">
    <CodeGroup>
      ```python Python theme={null}
      from comfy_sdk import Comfy

      # 環境から COMFY_API_KEY を読み取ります。
      # SDK は冪等性キーを自動的に生成し、自動リトライのために再利用します。
      with Comfy() as client:
          result = client.models.run(
              "vertexai/gemini-3-pro-image",
              {
                  "contents": [
                      {
                          "role": "user",
                          "parts": [
                              {
                                  "text": "a single red maple leaf on a plain white background, studio lighting",
                              },
                          ],
                      },
                  ],
                  "generationConfig": {
                      "responseModalities": ["IMAGE"],
                      "imageConfig": {
                          "aspectRatio": "1:1",
                      },
                  },
              },
          )

      print("image (base64):", result["candidates"][0]["content"]["parts"][0]["inlineData"]["data"])
      ```

      ```typescript TypeScript theme={null}
      import { comfy } from "@comfyorg/sdk";

      // 環境から COMFY_API_KEY を読み取ります。
      // SDK は冪等性キーを自動的に生成し、自動リトライのために再利用します。
      type Result = { candidates: { content: { parts: { inlineData: { data: string } }[] } }[] };
      const result = await comfy.models.run<Result>("vertexai/gemini-3-pro-image", {
        contents: [
          {
            role: "user",
            parts: [
              {
                text: "a single red maple leaf on a plain white background, studio lighting",
              },
            ],
          },
        ],
        generationConfig: {
          responseModalities: ["IMAGE"],
          imageConfig: {
            aspectRatio: "1:1",
          },
        },
      });
      if (result.kind !== "json") throw new Error("expected a JSON result");

      console.log("image (base64):", result.data.candidates[0].content.parts[0].inlineData.data);
      ```

      ```swift Swift theme={null}
      import Foundation
      import ComfySwiftSDK

      // 環境から COMFY_API_KEY を読み取ります。
      // SDK は呼び出しごとに冪等性キーを発行し、自動リトライのために再利用します。
      let client = ComfyCloudClient(apiKey: ProcessInfo.processInfo.environment["COMFY_API_KEY"]!)
      let result = try await client.models.run(
          "vertexai/gemini-3-pro-image",
          input: [
              "contents": [
                  [
                      "role": "user",
                      "parts": [
                          [
                              "text": "a single red maple leaf on a plain white background, studio lighting",
                          ],
                      ],
                  ],
              ],
              "generationConfig": [
                  "responseModalities": ["IMAGE"],
                  "imageConfig": [
                      "aspectRatio": "1:1",
                  ],
              ],
          ]
      )

      print("image (base64):", result.output["candidates"][0]["content"]["parts"][0]["inlineData"]["data"].stringValue ?? "")
      ```

      ```bash cURL theme={null}
      curl https://api.comfy.org/v2/models/vertexai/gemini-3-pro-image \
        -H "X-API-Key: $COMFY_API_KEY" \
        -H "Idempotency-Key: $(uuidgen)" \
        -H "Content-Type: application/json" \
        -d "{\"contents\": [{\"role\":\"user\",\"parts\":[{\"text\":\"a single red maple leaf on a plain white background, studio lighting\"}]}], \"generationConfig\": {\"responseModalities\":[\"IMAGE\"],\"imageConfig\":{\"aspectRatio\":\"1:1\"}}}"
      ```
    </CodeGroup>
  </Tab>

  <Tab title="キューに登録して後で収集">
    同じボディを `POST https://api.comfy.org/v2/models/vertexai/gemini-3-pro-image/requests` に送信します。Router は実行が受け付けられるとすぐに `request_id` とともに `201` を返し、結果は準備ができ次第、このプロセスからでも別のプロセスからでも収集できます。[キュー配信](/ja/development/comfy-router/queue)では、ステータス、キャンセル、収集について説明しています。

    <CodeGroup>
      ```python Python theme={null}
      from comfy_sdk import Comfy

      # 環境から COMFY_API_KEY を読み取ります。
      # 各 submit() 呼び出しは独自の Idempotency-Key を生成し、自動リトライのために再利用します。
      with Comfy() as client:
          handle = client.models.submit(
              "vertexai/gemini-3-pro-image",
              {
                  "contents": [
                      {
                          "role": "user",
                          "parts": [
                              {
                                  "text": "a single red maple leaf on a plain white background, studio lighting",
                              },
                          ],
                      },
                  ],
                  "generationConfig": {
                      "responseModalities": ["IMAGE"],
                      "imageConfig": {
                          "aspectRatio": "1:1",
                      },
                  },
              },
          )
          print("request_id:", handle.request_id)  # モデル ID とともに、別のプロセスが必要とするものすべて

          # リクエストが完了するまでポーリングし、サーバーが指定する Retry-After の分だけ待機します。
          for update in handle.iter_events():
              print(update.status, update.queue_position)

          # プロバイダー自身のペイロードで、models.run() が返すのと同じ値です。
          # 失敗またはキャンセルされたリクエストは、ここで型付きの Router エラーを発生させます。
          result = handle.get()

      print("image (base64):", result["candidates"][0]["content"]["parts"][0]["inlineData"]["data"])
      ```

      ```typescript TypeScript theme={null}
      import { comfy } from "@comfyorg/sdk";

      // 環境から COMFY_API_KEY を読み取ります。
      // 各 submit() 呼び出しは独自の Idempotency-Key を生成し、自動リトライのために再利用します。
      type Result = { candidates: { content: { parts: { inlineData: { data: string } }[] } }[] };
      const handle = await comfy.models.submit<Result>("vertexai/gemini-3-pro-image", {
        contents: [
          {
            role: "user",
            parts: [
              {
                text: "a single red maple leaf on a plain white background, studio lighting",
              },
            ],
          },
        ],
        generationConfig: {
          responseModalities: ["IMAGE"],
          imageConfig: {
            aspectRatio: "1:1",
          },
        },
      });
      console.log("requestId:", handle.requestId); // モデル ID とともに、別のプロセスが必要とするものすべて

      // リクエストが完了するまでポーリングし、サーバーが指定する Retry-After の分だけ待機します。
      for await (const update of handle.events()) {
        console.log(update.status, update.queuePosition);
      }

      // models.run() が返すのと同じ結果です。失敗またはキャンセルされたリクエストはここで拒否されます。
      const result = await handle.get();
      if (result.kind !== "json") throw new Error("expected a JSON result");

      console.log("image (base64):", result.data.candidates[0].content.parts[0].inlineData.data);
      ```

      ```swift Swift theme={null}
      import Foundation
      import ComfySwiftSDK

      // 環境から COMFY_API_KEY を読み取ります。
      // 各 submit() 呼び出しは独自の Idempotency-Key を生成し、自動リトライのために再利用します。
      let client = ComfyCloudClient(apiKey: ProcessInfo.processInfo.environment["COMFY_API_KEY"]!)
      let handle = try await client.models.submit(
          "vertexai/gemini-3-pro-image",
          input: [
              "contents": [
                  [
                      "role": "user",
                      "parts": [
                          [
                              "text": "a single red maple leaf on a plain white background, studio lighting",
                          ],
                      ],
                  ],
              ],
              "generationConfig": [
                  "responseModalities": ["IMAGE"],
                  "imageConfig": [
                      "aspectRatio": "1:1",
                  ],
              ],
          ]
      )
      print("requestId:", handle.requestId)  // モデル ID とともに、別のプロセスが必要とするものすべて

      // リクエストが完了するまでポーリングし、サーバーが指定する Retry-After の分だけ待機します。
      for try await update in handle.events() {
          print(update.state.rawValue, update.queuePosition.map(String.init) ?? "unknown")
      }

      // プロバイダー自身のペイロードで、models.run() が返すのと同じ値です。
      // 失敗またはキャンセルされたリクエストは、ここで型付きの Router エラーをスローします。
      let result = try await handle.result()

      print("image (base64):", result.output["candidates"][0]["content"]["parts"][0]["inlineData"]["data"].stringValue ?? "")
      ```

      ```bash cURL theme={null}
      # 1. 送信。Router は request_id、status_url、response_url、cancel_url とともに 201 を返します。
      curl https://api.comfy.org/v2/models/vertexai/gemini-3-pro-image/requests \
        -H "X-API-Key: $COMFY_API_KEY" \
        -H "Idempotency-Key: $(uuidgen)" \
        -H "Content-Type: application/json" \
        -d "{\"contents\": [{\"role\":\"user\",\"parts\":[{\"text\":\"a single red maple leaf on a plain white background, studio lighting\"}]}], \"generationConfig\": {\"responseModalities\":[\"IMAGE\"],\"imageConfig\":{\"aspectRatio\":\"1:1\"}}}"

      # 2. ステータスが COMPLETED になるまでポーリングし、各レスポンスが指定する Retry-After 秒だけ待機します。
      REQUEST_ID="<request_id from the 201 body>"
      curl -i https://api.comfy.org/v2/models/vertexai/gemini-3-pro-image/requests/$REQUEST_ID/status \
        -H "X-API-Key: $COMFY_API_KEY"

      # 3. 収集。モデルのネイティブ出力とともに 200、まだ実行中はステータスボディとともに 202。
      curl https://api.comfy.org/v2/models/vertexai/gemini-3-pro-image/requests/$REQUEST_ID \
        -H "X-API-Key: $COMFY_API_KEY"
      ```
    </CodeGroup>
  </Tab>
</Tabs>

## 提供プロバイダー

このモデルは、リクエストで別のプロバイダーを指定しない限り、Comfy Router が直接提供します。以下のプロバイダーも、同じエンドポイントと同じモデル ID でこのモデルを提供しており、`model_provider` クエリパラメータで選択します。

* **Comfy**（デフォルト）: `POST https://api.comfy.org/v2/models/vertexai/gemini-3-pro-image`
* **fal**、`fal/fal-nano-banana-pro` として: `POST https://api.comfy.org/v2/models/vertexai/gemini-3-pro-image?model_provider=fal`
* **Runware**、`runware/runware-nano-banana-pro` として: `POST https://api.comfy.org/v2/models/vertexai/gemini-3-pro-image?model_provider=runware`
* **WaveSpeed**、`wavespeed/wavespeed-nano-banana-pro` として: `POST https://api.comfy.org/v2/models/vertexai/gemini-3-pro-image?model_provider=wavespeed`

`strict_mode` のデフォルトは false であるため、Router はこのページで説明されているネイティブのリクエストボディをプロバイダー独自のスキーマに変換し、レスポンスを元に戻す変換を行います。API リファレンスの [`model_provider`、`strict_mode`、`fallback_provider`](/ja/development/comfy-router/reference#post-v2modelsprovidermodel) と、この方法でルーティングされるすべてのモデルについては[提供プロバイダー](/ja/development/comfy-router/providers)を参照してください。

## スキーマ

### 入力

<ParamField body="contents" type="object[]" required>
  モデルとの現在の会話のコンテンツ。単一ターンのクエリでは単一のインスタンスとなります。マルチターンのクエリでは、会話履歴と最新のリクエストを含む繰り返しフィールドとなります。
</ParamField>

<ParamField body="contents[].parts" type="object[]" required />

<ParamField body="contents[].parts[].fileData" type="object">
  URI ベースのデータ。
</ParamField>

<ParamField body="contents[].parts[].fileData.fileUri" type="string">
  URI
</ParamField>

<ParamField body="contents[].parts[].fileData.mimeType" type="string">
  data フィールドまたは fileUri フィールドで指定されたファイルのメディアタイプ。指定できる値は以下のとおりです。gemini-2.0-flash-lite および gemini-2.0-flash では、オーディオファイルの最大長は 8.4 時間、ビデオファイル（音声なし）の最大長は 1 時間です。詳細については、Gemini のオーディオとビデオの要件を参照してください。テキストファイルは UTF-8 でエンコードされている必要があります。テキストファイルの内容はトークン上限にカウントされます。画像の解像度に制限はありません。

  指定可能な値: `application/pdf`、`audio/mpeg`、`audio/mp3`、`audio/wav`、`image/png`、`image/jpeg`、`image/webp`、`text/plain`、`video/mov`、`video/mpeg`、`video/mp4`、`video/mpg`、`video/avi`、`video/wmv`、`video/mpegps`、`video/flv`、`image/heic`、`image/heif`、`audio/flac`、`video/webm`
</ParamField>

<ParamField body="contents[].parts[].inlineData" type="object">
  生のバイト形式のインラインデータ。gemini-2.0-flash-lite および gemini-2.0-flash では、inlineData を使用して最大 3000 枚の画像を指定できます。
</ParamField>

<ParamField body="contents[].parts[].inlineData.data" type="string (byte)">
  プロンプトにインラインで含める画像、PDF、またはビデオの base64 エンコーディング。メディアをインラインで含める場合は、データのメディアタイプ（mimeType）も指定する必要があります。サイズ制限: 20MB

  形式: `byte`
</ParamField>

<ParamField body="contents[].parts[].inlineData.mimeType" type="string">
  data フィールドまたは fileUri フィールドで指定されたファイルのメディアタイプ。指定できる値は以下のとおりです。gemini-2.0-flash-lite および gemini-2.0-flash では、オーディオファイルの最大長は 8.4 時間、ビデオファイル（音声なし）の最大長は 1 時間です。詳細については、Gemini のオーディオとビデオの要件を参照してください。テキストファイルは UTF-8 でエンコードされている必要があります。テキストファイルの内容はトークン上限にカウントされます。画像の解像度に制限はありません。

  指定可能な値: `application/pdf`、`audio/mpeg`、`audio/mp3`、`audio/wav`、`image/png`、`image/jpeg`、`image/webp`、`text/plain`、`video/mov`、`video/mpeg`、`video/mp4`、`video/mpg`、`video/avi`、`video/wmv`、`video/mpegps`、`video/flv`、`image/heic`、`image/heif`、`audio/flac`、`video/webm`
</ParamField>

<ParamField body="contents[].parts[].mediaProcessing" type="string">
  モデルがこのパートのビデオを読み取る方法。固定レートのフレームサンプリングではなく、モデルに検査するセグメントを判断させるには "AGENTIC" を設定します。デフォルトの固定レートサンプリングを使用する場合は省略します。gemini-3.7-flash 以降の Flash モデルでサポートされています。
</ParamField>

<ParamField body="contents[].parts[].text" type="string">
  テキストプロンプトまたはコードスニペット。
</ParamField>

<ParamField body="contents[].parts[].thought" type="boolean">
  このパートがモデルからの思考/推論ステップであることを示します。
</ParamField>

<ParamField body="contents[].role" type="string">
  指定可能な値: `user`、`model`
</ParamField>

<ParamField body="generationConfig" type="object">
  生成のためのサンプリング、長さ、出力の設定。すべてのフィールドはオプションです。以下で `default` を宣言しているフィールドは省略時にそれが適用され、それ以外はモデル自身の動作に従います。
</ParamField>

<ParamField body="generationConfig.imageConfig" type="object">
  画像生成の設定
</ParamField>

<ParamField body="generationConfig.imageConfig.aspectRatio" type="string">
  生成される画像のアスペクト比
</ParamField>

<ParamField body="generationConfig.imageConfig.imageOutputOptions" type="object">
  オプション。生成される画像の画像出力形式。
</ParamField>

<ParamField body="generationConfig.imageConfig.imageOutputOptions.compressionQuality" type="integer">
  オプション。出力画像の圧縮品質。
</ParamField>

<ParamField body="generationConfig.imageConfig.imageOutputOptions.mimeType" type="string">
  オプション。出力を保存する画像形式。
</ParamField>

<ParamField body="generationConfig.imageConfig.imageSize" type="string">
  オプション。生成される画像のサイズを指定します。サポートされる値は 1K、2K、4K です。指定しない場合、モデルはデフォルト値の 1K を使用します。
</ParamField>

<ParamField body="generationConfig.maxOutputTokens" type="integer">
  レスポンスで生成できるトークンの最大数。トークンはおよそ 4 文字に相当します。100 トークンはおおよそ 60～80 語に相当します。

  範囲: `16` ～ `65536`
</ParamField>

<ParamField body="generationConfig.responseModalities" type="`TEXT`, `IMAGE`[]" />

<ParamField body="generationConfig.seed" type="integer">
  seed を特定の値に固定すると、モデルは繰り返しのリクエストに対して同じレスポンスを返すよう最善を尽くします。決定論的な出力は保証されません。また、モデルや temperature などのパラメータ設定を変更すると、同じ seed 値を使用してもレスポンスが変化する可能性があります。デフォルトではランダムな seed 値が使用されます。以下のモデルで利用できます: gemini-2.5-flash、gemini-2.5-pro、gemini-2.5-flash-preview-04-1、gemini-2.5-pro-preview-05-0、gemini-2.0-flash-lite-00、gemini-2.0-flash-001
</ParamField>

<ParamField body="generationConfig.stopSequences" type="string[]" />

<ParamField body="generationConfig.temperature" type="number" default="1">
  temperature はレスポンス生成中のサンプリングに使用され、これは topP と topK が適用されるときに実行されます。temperature はトークン選択におけるランダム性の度合いを制御します。低い temperature は、より限定された、あるいは創造性の低いレスポンスが求められるプロンプトに適しており、高い temperature はより多様または創造的な結果につながる可能性があります。temperature が 0 の場合、最も確率の高いトークンが常に選択されることを意味します。この場合、特定のプロンプトに対するレスポンスはほぼ決定的ですが、わずかなばらつきが生じる可能性はあります。モデルが返すレスポンスが一般的すぎる、短すぎる、またはモデルがフォールバックレスポンスを返す場合は、temperature を上げてみてください

  範囲: `0` から `2`

  形式: `float`
</ParamField>

<ParamField body="generationConfig.thinkingConfig" type="object">
  省略可能。thinking 機能の設定です。thinking とは、モデルが複雑なタスクを小さなステップに分解し、より高品質なレスポンスを生成するプロセスです。
</ParamField>

<ParamField body="generationConfig.thinkingConfig.includeThoughts" type="boolean">
  省略可能。true の場合、モデルは自身の思考をレスポンスに含めます。
</ParamField>

<ParamField body="generationConfig.thinkingConfig.thinkingBudget" type="integer">
  省略可能。モデルの thinking プロセスのトークン予算。モデルはこの予算内に収まるよう最善を尽くします。
</ParamField>

<ParamField body="generationConfig.thinkingConfig.thinkingLevel" type="string">
  省略可能。モデルの thinking レベル。

  指定可能な値: `THINKING_LEVEL_UNSPECIFIED`、`LOW`、`MEDIUM`、`HIGH`、`MINIMAL`
</ParamField>

<ParamField body="generationConfig.topK" type="integer" default="40">
  Top-K は、モデルが出力のためにトークンを選択する方法を変更します。Top-K が 1 の場合、次に選択されるトークンはモデルの語彙内のすべてのトークンの中で最も確率が高いものになります。Top-K が 3 の場合、次のトークンは最も確率の高い 3 つのトークンの中から temperature を用いて選択されます。

  範囲: `1` から `…`
</ParamField>

<ParamField body="generationConfig.topP" type="number" default="0.95">
  指定した場合、nucleus サンプリングが使用されます。
  Top-P は、モデルが出力のためにトークンを選択する方法を変更します。トークンは、それらの確率の合計が top-P の値に等しくなるまで、最も確率の高いもの（top-K を参照）から低いものへと選択されます。たとえば、トークン A、B、C の確率がそれぞれ 0.3、0.2、0.1 で、top-P の値が 0.5 の場合、モデルは temperature を用いて A または B のいずれかを次のトークンとして選択し、C は候補から除外されます。
  ランダム性の低いレスポンスには低い値を、ランダム性の高いレスポンスには高い値を指定します。

  範囲: `0` から `1`

  形式: `float`
</ParamField>

<ParamField body="safetySettings" type="object[]">
  安全でないコンテンツをブロックするためのリクエストごとの設定。GenerateContentResponse.candidates に適用されます。
</ParamField>

<ParamField body="safetySettings[].category" type="string" required>
  指定可能な値: `HARM_CATEGORY_SEXUALLY_EXPLICIT`、`HARM_CATEGORY_HATE_SPEECH`、`HARM_CATEGORY_HARASSMENT`、`HARM_CATEGORY_DANGEROUS_CONTENT`
</ParamField>

<ParamField body="safetySettings[].threshold" type="string" required>
  指定可能な値: `OFF`、`BLOCK_NONE`、`BLOCK_LOW_AND_ABOVE`、`BLOCK_MEDIUM_AND_ABOVE`、`BLOCK_ONLY_HIGH`
</ParamField>

<ParamField body="systemInstruction" type="object">
  モデルをより良いパフォーマンスへ導くための指示。たとえば、「できるだけ簡潔に回答してください」や「回答に専門用語を使わないでください」などです。テキスト文字列はトークン上限にカウントされます。systemInstruction の role フィールドは無視され、モデルのパフォーマンスには影響しません。注: parts にはテキストのみを使用し、各 part の content は別々の段落にしてください。
</ParamField>

<ParamField body="systemInstruction.parts" type="object[]" required>
  1 つのメッセージを構成する順序付けられた part のリスト。part ごとに異なる IANA MIME タイプを持つ場合があります。最大トークン数や画像数などの入力の制限については、Google のモデルページにあるモデル仕様を参照してください。
</ParamField>

<ParamField body="systemInstruction.parts[].text" type="string">
  テキストプロンプトまたはコードスニペット。
</ParamField>

<ParamField body="systemInstruction.role" type="string">
  メッセージを作成するエンティティの識別情報。次の値がサポートされています: user: メッセージが実在の人物によって送信されたことを示します。通常はユーザーが生成したメッセージです。model: メッセージがモデルによって生成されたことを示します。model の値は、マルチターン会話中にモデルからのメッセージを会話に挿入するために使用されます。マルチターンでない会話では、このフィールドは空のままにするか、未設定にできます。

  指定可能な値: `user`、`model`
</ParamField>

<ParamField body="tools" type="object[]">
  システムがモデルの知識と範囲外のアクションを実行するために、外部システムと連携できるようにするコード。Function calling を参照してください。
</ParamField>

<ParamField body="tools[].functionDeclarations" type="object[]" />

<ParamField body="tools[].functionDeclarations[].description" type="string" />

<ParamField body="tools[].functionDeclarations[].name" type="string" required />

<ParamField body="tools[].functionDeclarations[].parameters" type="object">
  関数パラメータの JSON スキーマ
</ParamField>

<ParamField body="uploadImagesToStorage" type="boolean">
  true の場合、生成済みの画像はクラウドストレージにアップロードされ、インラインの base64 データではなく署名付き URL として返されます。URL は 24 時間後に失効します。
</ParamField>

<ParamField body="videoMetadata" type="object">
  ビデオ入力の場合、ビデオの開始オフセットと終了オフセットを Duration 形式で指定します。たとえば、1:00 から始まる 10 秒のクリップを指定するには、"startOffset": \{ "seconds": 60 } と "endOffset": \{ "seconds": 70 } を設定します。メタデータは、ビデオデータが inlineData または fileData で提供されている場合にのみ指定してください。
</ParamField>

<ParamField body="videoMetadata.endOffset" type="object">
  ビデオタイムライン上の位置に対する再生時間のオフセットを表します。
</ParamField>

<ParamField body="videoMetadata.endOffset.nanos" type="integer">
  ナノ秒解像度での秒の小数部（符号付き）。小数部を持つ負の秒の値であっても、nanos の値は非負でなければなりません。

  範囲: `0` から `999999999`
</ParamField>

<ParamField body="videoMetadata.endOffset.seconds" type="integer">
  期間の秒数（符号付き）。-315,576,000,000 から +315,576,000,000 まで（両端を含む）でなければなりません。

  範囲: `-315576000000` から `315576000000`
</ParamField>

<ParamField body="videoMetadata.startOffset" type="object">
  ビデオタイムライン上の位置に対する再生時間のオフセットを表します。
</ParamField>

<ParamField body="videoMetadata.startOffset.nanos" type="integer">
  ナノ秒解像度での秒の小数部（符号付き）。小数部を持つ負の秒の値であっても、nanos の値は非負でなければなりません。

  範囲: `0` から `999999999`
</ParamField>

<ParamField body="videoMetadata.startOffset.seconds" type="integer">
  期間の秒数（符号付き）。-315,576,000,000 から +315,576,000,000 まで（両端を含む）でなければなりません。

  範囲: `-315576000000` から `315576000000`
</ParamField>

Router が `GET /v2/models/vertexai/gemini-3-pro-image/openapi.json` で提供するスキーマから生成されています。これは、リクエストがプロバイダーに到達する前に呼び出しを検証する対象となるドキュメントと同じものです。

### 出力

<ResponseField name="candidates" type="object[]" />

<ResponseField name="candidates[].citationMetadata" type="object" />

<ResponseField name="candidates[].citationMetadata.citations" type="object[]" />

<ResponseField name="candidates[].citationMetadata.citations[].authors" type="string[]" />

<ResponseField name="candidates[].citationMetadata.citations[].endIndex" type="integer" />

<ResponseField name="candidates[].citationMetadata.citations[].license" type="string" />

<ResponseField name="candidates[].citationMetadata.citations[].publicationDate" type="string (date)">
  フォーマット: `date`
</ResponseField>

<ResponseField name="candidates[].citationMetadata.citations[].startIndex" type="integer" />

<ResponseField name="candidates[].citationMetadata.citations[].title" type="string" />

<ResponseField name="candidates[].citationMetadata.citations[].uri" type="string" />

<ResponseField name="candidates[].content" type="object">
  モデルとの現在の会話のコンテンツです。単一ターンのクエリでは、これは単一のインスタンスです。マルチターンのクエリでは、これは会話履歴と最新のリクエストを含む繰り返しフィールドです。
</ResponseField>

<ResponseField name="candidates[].content.parts" type="object[]" required />

<ResponseField name="candidates[].content.parts[].fileData" type="object">
  URI ベースのデータ。
</ResponseField>

<ResponseField name="candidates[].content.parts[].fileData.fileUri" type="string">
  URI
</ResponseField>

<ResponseField name="candidates[].content.parts[].fileData.mimeType" type="string">
  data フィールドまたは fileUri フィールドで指定されたファイルのメディアタイプです。許容される値は以下のとおりです。gemini-2.0-flash-lite および gemini-2.0-flash では、オーディオファイルの最大長は 8.4 時間、ビデオファイル（音声なし）の最大長は 1 時間です。詳細については、Gemini のオーディオとビデオの要件を参照してください。テキストファイルは UTF-8 でエンコードする必要があります。テキストファイルのコンテンツはトークン制限にカウントされます。画像の解像度に制限はありません。

  指定可能な値: `application/pdf`、`audio/mpeg`、`audio/mp3`、`audio/wav`、`image/png`、`image/jpeg`、`image/webp`、`text/plain`、`video/mov`、`video/mpeg`、`video/mp4`、`video/mpg`、`video/avi`、`video/wmv`、`video/mpegps`、`video/flv`、`image/heic`、`image/heif`、`audio/flac`、`video/webm`
</ResponseField>

<ResponseField name="candidates[].content.parts[].inlineData" type="object">
  生バイトのインラインデータです。gemini-2.0-flash-lite および gemini-2.0-flash では、inlineData を使用して最大 3000 枚の画像を指定できます。
</ResponseField>

<ResponseField name="candidates[].content.parts[].inlineData.data" type="string (byte)">
  プロンプトにインラインで含める画像、PDF、またはビデオの base64 エンコードです。メディアをインラインで含める場合は、データのメディアタイプ（mimeType）も指定する必要があります。サイズ制限: 20MB

  フォーマット: `byte`
</ResponseField>

<ResponseField name="candidates[].content.parts[].inlineData.mimeType" type="string">
  data フィールドまたは fileUri フィールドで指定されたファイルのメディアタイプです。許容される値は以下のとおりです。gemini-2.0-flash-lite および gemini-2.0-flash では、オーディオファイルの最大長は 8.4 時間、ビデオファイル（音声なし）の最大長は 1 時間です。詳細については、Gemini のオーディオとビデオの要件を参照してください。テキストファイルは UTF-8 でエンコードする必要があります。テキストファイルのコンテンツはトークン制限にカウントされます。画像の解像度に制限はありません。

  指定可能な値: `application/pdf`、`audio/mpeg`、`audio/mp3`、`audio/wav`、`image/png`、`image/jpeg`、`image/webp`、`text/plain`、`video/mov`、`video/mpeg`、`video/mp4`、`video/mpg`、`video/avi`、`video/wmv`、`video/mpegps`、`video/flv`、`image/heic`、`image/heif`、`audio/flac`、`video/webm`
</ResponseField>

<ResponseField name="candidates[].content.parts[].mediaProcessing" type="string">
  モデルがこのパートのビデオをどのように読み取るかです。固定レートのフレームサンプリングではなく、検査するセグメントをモデルに決定させるには "AGENTIC" を設定します。デフォルトの固定レートサンプリングを使用する場合は省略します。gemini-3.7-flash 以降の Flash モデルでサポートされています。
</ResponseField>

<ResponseField name="candidates[].content.parts[].text" type="string">
  テキストプロンプトまたはコードスニペット。
</ResponseField>

<ResponseField name="candidates[].content.parts[].thought" type="boolean">
  このパートがモデルからの思考/推論ステップであることを示します。
</ResponseField>

<ResponseField name="candidates[].content.role" type="string">
  指定可能な値: `user`、`model`
</ResponseField>

<ResponseField name="candidates[].finishReason" type="string" />

<ResponseField name="candidates[].safetyRatings" type="object[]" />

<ResponseField name="candidates[].safetyRatings[].category" type="string">
  指定可能な値: `HARM_CATEGORY_SEXUALLY_EXPLICIT`、`HARM_CATEGORY_HATE_SPEECH`、`HARM_CATEGORY_HARASSMENT`、`HARM_CATEGORY_DANGEROUS_CONTENT`
</ResponseField>

<ResponseField name="candidates[].safetyRatings[].probability" type="string">
  コンテンツが指定された安全性カテゴリに違反する確率

  指定可能な値: `NEGLIGIBLE`、`LOW`、`MEDIUM`、`HIGH`、`UNKNOWN`
</ResponseField>

<ResponseField name="createTime" type="string">
  レスポンスが作成されたタイムスタンプ。
</ResponseField>

<ResponseField name="modelVersion" type="string">
  レスポンスの生成に使用されたモデルのバージョン。
</ResponseField>

<ResponseField name="promptFeedback" type="object" />

<ResponseField name="promptFeedback.blockReason" type="string" />

<ResponseField name="promptFeedback.blockReasonMessage" type="string" />

<ResponseField name="promptFeedback.safetyRatings" type="object[]" />

<ResponseField name="promptFeedback.safetyRatings[].category" type="string">
  指定可能な値:  `HARM_CATEGORY_SEXUALLY_EXPLICIT`, `HARM_CATEGORY_HATE_SPEECH`, `HARM_CATEGORY_HARASSMENT`, `HARM_CATEGORY_DANGEROUS_CONTENT`
</ResponseField>

<ResponseField name="promptFeedback.safetyRatings[].probability" type="string">
  コンテンツが指定された安全性カテゴリに違反する確率

  指定可能な値: `NEGLIGIBLE`, `LOW`, `MEDIUM`, `HIGH`, `UNKNOWN`
</ResponseField>

<ResponseField name="responseId" type="string">
  レスポンスの一意の識別子。
</ResponseField>

<ResponseField name="usageMetadata" type="object" />

<ResponseField name="usageMetadata.cachedContentTokenCount" type="integer">
  出力専用。入力内のキャッシュされた部分 (キャッシュされたコンテンツ) のトークン数。
</ResponseField>

<ResponseField name="usageMetadata.candidatesTokenCount" type="integer">
  レスポンス内のトークン数。
</ResponseField>

<ResponseField name="usageMetadata.candidatesTokensDetails" type="object[]">
  モダリティ別の候補トークンの内訳。
</ResponseField>

<ResponseField name="usageMetadata.candidatesTokensDetails[].modality" type="string">
  入力または出力コンテンツのモダリティの種類。

  指定可能な値: `MODALITY_UNSPECIFIED`, `TEXT`, `IMAGE`, `VIDEO`, `AUDIO`, `DOCUMENT`
</ResponseField>

<ResponseField name="usageMetadata.candidatesTokensDetails[].tokenCount" type="integer">
  指定されたモダリティのトークン数。
</ResponseField>

<ResponseField name="usageMetadata.promptTokenCount" type="integer">
  リクエスト内のトークン数。cachedContent が設定されている場合でも、これは有効なプロンプトの合計サイズであり、キャッシュされたコンテンツ内のトークン数も含まれます。
</ResponseField>

<ResponseField name="usageMetadata.promptTokensDetails" type="object[]">
  モダリティ別のプロンプトトークンの内訳。
</ResponseField>

<ResponseField name="usageMetadata.promptTokensDetails[].modality" type="string">
  入力または出力コンテンツのモダリティの種類。

  指定可能な値: `MODALITY_UNSPECIFIED`, `TEXT`, `IMAGE`, `VIDEO`, `AUDIO`, `DOCUMENT`
</ResponseField>

<ResponseField name="usageMetadata.promptTokensDetails[].tokenCount" type="integer">
  指定されたモダリティのトークン数。
</ResponseField>

<ResponseField name="usageMetadata.thoughtsTokenCount" type="integer">
  thoughts 出力に含まれるトークン数。
</ResponseField>

<ResponseField name="usageMetadata.toolUsePromptTokenCount" type="integer">
  ツール使用プロンプトに含まれるトークン数。
</ResponseField>

<ResponseField name="usageMetadata.toolUsePromptTokensDetails" type="object[]">
  モダリティ別のツール使用プロンプトトークンの内訳。
</ResponseField>

<ResponseField name="usageMetadata.toolUsePromptTokensDetails[].modality" type="string">
  入力または出力コンテンツのモダリティの種類。

  指定可能な値: `MODALITY_UNSPECIFIED`, `TEXT`, `IMAGE`, `VIDEO`, `AUDIO`, `DOCUMENT`
</ResponseField>

<ResponseField name="usageMetadata.toolUsePromptTokensDetails[].tokenCount" type="integer">
  指定されたモダリティのトークン数。
</ResponseField>

<ResponseField name="usageMetadata.totalTokenCount" type="integer">
  トークンの合計数 (プロンプト + 候補)。
</ResponseField>

<ResponseField name="usageMetadata.trafficType" type="string">
  リクエストに使用されたトラフィックタイプ (例: PROVISIONED\_THROUGHPUT)。
</ResponseField>

## 例

### 入力

```json theme={null}
{
  "contents": [
    {
      "role": "user",
      "parts": [
        {
          "text": "a single red maple leaf on a plain white background, studio lighting"
        }
      ]
    }
  ],
  "generationConfig": {
    "responseModalities": [
      "IMAGE"
    ],
    "imageConfig": {
      "aspectRatio": "1:1"
    }
  }
}
```

### 出力

```json theme={null}
{
  "candidates": [
    {
      "content": {
        "role": "model",
        "parts": [
          {
            "inlineData": {
              "mimeType": "image/png",
              "data": "PGJhc2U2ND4="
            }
          }
        ]
      },
      "finishReason": "STOP"
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 12,
    "candidatesTokenCount": 1290
  }
}
```

### parts の読み取り

デフォルトでは、生成された画像の part には、base64 バイト列が `inlineData.data` に、メディアタイプが `inlineData.mimeType` に含まれます。バイト列をデコードしてファイルに保存してください。`uploadImagesToStorage: true` の場合、アップロードされた画像は代わりに、署名付き URL に `fileData.fileUri` を、メディアタイプに `fileData.mimeType` を使用します。これらの画像は、URL が失効する前にダウンロードしてください。URL は作成から 24 時間後に失効します。

**`fileData` は、それを要求していないレスポンスにも現れることがあります。** この 2 つの形はレスポンス単位ではなく part 単位です。`uploadImagesToStorage: true` が設定されている場合、アップロードに失敗した画像は `inlineData` のまま残るため、1 つのレスポンスに両方が混在することがあります。要求した内容ではなく、どのキーが存在するかで分岐してください。逆のケースは起こりません。フィールドが未設定または false の場合、生成されたすべての画像は `inlineData` として返り、`fileData` の画像 part は生成されません。テキストの part も現れることがあり、画像が最初の part であるとも限らないため、インデックスではなく必要なフィールドで part を選択してください。上記のクイックスタートのサンプルにある `candidates[0].content.parts[0].inlineData.data` というパスは、このページのサンプルレスポンスにある唯一の inline part を読み取るものです。実際のレスポンスに対しては、位置 0 をインデックス指定するのではなく、`parts` を走査して目的のキーを探してください。

**`thoughtSignature` も part のフィールドで、しかもサイズが大きくなります。** part は `thoughtSignature` を持つことがあります。これはモデルの推論を表す不透明な base64 署名で、後続のリクエストでその思考を再生できるようにするために存在します。上記の生成スキーマには含まれていません。このスキーマは Router が公開しているリクエスト/レスポンスのドキュメントに従ったものです。実際のレスポンスで計測すると、part あたりおよそ 1〜2 MB で、画像本体と同程度です。そのため、レスポンスをログに記録したり、サーバーレス関数を介して転送したり、保存したりする場合は、その分の容量を見込むか、明示的に破棄することを検討してください。

### `imageSize` は幅ではなくクラス

`generationConfig.imageConfig.imageSize` は `1K`、`2K`、`4K` のいずれかを取り、段階が上がるごとに幅を設定するのではなく両辺が 2 倍になります。16:9 のリクエストを計測すると、`1K` では 1376x768 で約 1.35 MB、`2K` では 2752x1536 で約 5.6 MB でした。同じアスペクト比で、ピクセル数は 4 倍、バイト数もおよそ 4 倍です。したがって `2K` は幅 2048 ピクセルの画像を意味するものではありません。`2K` を幅であるかのように扱ってアップロード経路、レスポンスボディの上限、ストレージバケットのサイズを見積もると、約 4 倍の不足が生じます。

### 参照チェーン

生成済みの画像をそのまま入力し直すと、同じ被写体を別のカメラアングルで捉えた画像が得られます。そのため、1 つのシーンの一連のショットは、すべてを一度に記述しなければならない 1 つのプロンプトではなく、呼び出しのチェーンになります。アーキテクチャ、素材、ライティングはチェーンを通じて維持されることがよくありますが、モデルがそれを保証するわけではありません。連続性は、信頼できる性質ではなく、確認すべき可能性の高い結果として扱ってください。

画像は、前のレスポンスで使われた形のまま送り返してください。`inlineData` の part の場合は、`inlineData.data` から base64 バイト列を取り出し、それをそのまま `inlineData` として送信します（以下を参照）。`uploadImagesToStorage: true` で `fileData` として返ってきた part の場合は、署名付き URL がまだ有効なうちに、その `fileData.fileUri` と `fileData.mimeType` を `fileData` part として送信してください。バイト列を `inlineData` として再アップロードする方法も機能し、失効しません。そのうえで、希望する変更を指示します。

```json theme={null}
{
  "contents": [
    {
      "role": "user",
      "parts": [
        {
          "inlineData": {
            "mimeType": "image/png",
            "data": "<the base64 from candidates[0].content.parts[].inlineData.data of the previous response>"
          }
        },
        { "text": "the same room, viewed from the opposite corner at eye level" }
      ]
    }
  ],
  "generationConfig": {
    "responseModalities": ["IMAGE"],
    "imageConfig": { "aspectRatio": "16:9" }
  }
}
```

各呼び出しは独立しているため、会話履歴に頼るのではなく、基にしたい画像を渡してください。チェーンする際はリクエストボディのサイズに注意してください。インライン画像は Router の[リクエストボディの上限](/ja/development/comfy-router/limitations#リクエストボディの上限)にカウントされ、`2K` の画像は `1K` のおよそ 4 倍のバイト数になります。

## 出荷前の確認

SDK は `Idempotency-Key` を生成し、自動リトライで再利用します。手動リトライでは元のキーを再利用してください。Router は最大 10 分間接続を保持できます。

リクエストが失敗すると、Router は理由を説明する `X-Comfy-Error-Type` レスポンスヘッダーを送信します。`422` は、プロバイダーを呼び出す前に Router が入力を拒否したことを意味し、`413` はリクエスト本文が Router の受け入れ可能なサイズを超えていたことを意味します。生成されたアセットは [結果 URL の有効期限](/ja/development/comfy-router/reference#結果アセット) があるため、早めにダウンロードしてください。

上記のフィールド説明に記載されているサイズ制限は、プロバイダーの仕様から引用した、そのフィールドに対するプロバイダー自身の上限です。Router はリクエスト本文全体に対して別の上限を適用し、base64 エンコードされたメディアもこれにカウントされます。[リクエスト本文のサイズ](/ja/development/comfy-router/limitations) を参照してください。

このページは、Comfy Router 経由で呼び出す 1 つのパートナーモデルについて説明しています。同じ `comfy-sdk` / `@comfyorg/sdk` パッケージには、Comfy Cloud 上で ComfyUI のワークフローグラフ全体を実行するための 2 つ目のクライアントも含まれています: `Comfy(api_key=...)` / `new Comfy({ apiKey })`、および `client.workflows`、`client.assets`、`client.jobs`。[Comfy SDKs](/ja/development/api-development/sdks) を参照してください。

<CardGroup cols={3}>
  <Card title="ヘッダー" icon="list" href="/ja/development/comfy-router/headers">
    認証、冪等性、リクエスト ID、エラー分類、リトライ間隔、支出上限。
  </Card>

  <Card title="Router API の利用" icon="code" href="/ja/development/comfy-router/api">
    モデルの検出、バリデーションエラー、リトライ、課金。
  </Card>

  <Card title="制限事項" icon="triangle-exclamation" href="/ja/development/comfy-router/limitations">
    Router が現在対応していないことと、代替手段。
  </Card>
</CardGroup>
