> ## Documentation Index
> Fetch the complete documentation index at: https://docs.runbridge.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Generate images with Gemini

> Generate and edit Nano Banana images through RunBridge AI with the Gemini generateContent API, image options, and final inlineData output.

<Tip>
  For step-by-step examples, see [Use Gemini image models](/api/image/gemini/generate-image-guide).
</Tip>

Use `/v1beta/models/{model}:generateContent` to generate or edit Nano Banana images. Put the model ID in the URL and send the prompt or source image parts in `contents`.

## Choose a model

| Model | Reference example |
| - | - |
| `gemini-3.1-flash-image` | Nano Banana 2 text-to-image, editing, composition, and 4K image examples. |
| `gemini-3-pro-image` | Nano Banana Pro with a 2K output example. |
| `gemini-3.1-flash-lite-image` | Nano Banana 2 Lite; supports 1K output only. |

Use these stable IDs in requests. See [Google's Nano Banana guide](https://ai.google.dev/gemini-api/docs/image-generation) for model options and the [deprecation schedule](https://ai.google.dev/gemini-api/docs/deprecations) for model lifecycle dates.

<Note>
  Gemini image responses can include intermediate image parts where `thought` is `true`. These are not the final output. When saving generated images, skip `thought: true` parts and use the last image part where `inlineData` exists and `thought` is not `true`. Choose the saved file extension from its `mimeType`: `.jpg` for `image/jpeg`, `.png` for `image/png`, or `.webp` for `image/webp`.
</Note>


## OpenAPI

````yaml api/openapi/image/gemini/post-gemini-generates-image.openapi.json POST /v1beta/models/{model}:generateContent
openapi: 3.1.0
info:
  title: Gemini Image Generation API
  version: 1.0.0
servers:
  - url: https://api.runbridge.ai
security:
  - bearerAuth: []
paths:
  /v1beta/models/{model}:generateContent:
    post:
      summary: Gemini Image Generation
      operationId: gemini_generates_image
      parameters:
        - name: model
          in: path
          required: true
          description: >-
            Nano Banana image model ID. Use `gemini-3.1-flash-image` for the
            Flash examples, `gemini-3-pro-image` for Pro, or
            `gemini-3.1-flash-lite-image` for the Lite example.
          schema:
            type: string
            default: gemini-3.1-flash-image
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - contents
              properties:
                contents:
                  type: array
                  description: >-
                    Conversation turns. Each item has a `role` ("user" or
                    "model") and `parts` array containing text and/or image
                    data.
                  items:
                    type: object
                    properties:
                      role:
                        type: string
                        description: Role of the message sender.
                        enum:
                          - user
                          - model
                      parts:
                        type: array
                        description: >-
                          Content blocks — text prompts and/or inline image
                          data.
                        items:
                          type: object
                          properties:
                            text:
                              type: string
                              description: Text content (prompt or instruction).
                            inlineData:
                              type: object
                              description: >-
                                Inline image data for image-to-image or
                                multi-image input.
                              properties:
                                mimeType:
                                  type: string
                                  description: MIME type of the image.
                                  enum:
                                    - image/jpeg
                                    - image/png
                                    - image/webp
                                data:
                                  type: string
                                  description: >-
                                    Raw Base64-encoded image data. Do not
                                    include the `data:image/...;base64,` prefix.
                generationConfig:
                  type: object
                  description: >-
                    Controls generation behavior — output modalities, image
                    resolution, thinking, etc.
                  properties:
                    responseModalities:
                      type: array
                      description: >-
                        Output types to request. Use `["TEXT", "IMAGE"]` for
                        text and image parts, or `["IMAGE"]` for image-only
                        output.
                      items:
                        type: string
                        enum:
                          - TEXT
                          - IMAGE
                      default:
                        - TEXT
                        - IMAGE
                    imageConfig:
                      type: object
                      description: Image output configuration.
                      properties:
                        aspectRatio:
                          type: string
                          description: >-
                            All models: `1:1` `2:3` `3:2` `3:4` `4:3` `4:5`
                            `5:4` `9:16` `16:9` `21:9`. Gemini 3.1 Flash also
                            supports `1:4` `4:1` `1:8` `8:1`.
                          default: '1:1'
                        imageSize:
                          type: string
                          description: >-
                            Output resolution for the model selected in the URL.
                            The Flash example requests `4K`, the Pro example
                            requests `2K`, and the Lite example requests `1K`.
                            For `gemini-3.1-flash-lite-image`, use `1K` only.
                            Use uppercase K.
                          enum:
                            - 512px
                            - 1K
                            - 2K
                            - 4K
                          default: 1K
                    thinkingConfig:
                      type: object
                      description: >-
                        Controls the Thinking process (Gemini 3 models).
                        Thinking generates interim images before the final
                        output.
                      properties:
                        thinkingLevel:
                          type: string
                          description: >-
                            Thinking effort level. Only configurable for
                            `gemini-3.1-flash-image`; `gemini-3-pro-image`
                            always uses high thinking.
                          enum:
                            - minimal
                            - high
                          default: minimal
                        includeThoughts:
                          type: boolean
                          description: Whether to include thought parts in the response.
                          default: false
                tools:
                  type: array
                  description: >-
                    Optional Google Search grounding for
                    `gemini-3.1-flash-image` and `gemini-3-pro-image`. Pass
                    `[{"google_search": {}}]` to use real-time information in
                    generated images. The Lite model does not support search
                    grounding.
                  items:
                    type: object
                    properties:
                      google_search:
                        type: object
                        description: >-
                          Enables Google Search grounding for the Flash and Pro
                          models.
              default:
                contents:
                  - role: user
                    parts:
                      - text: >-
                          A Monarch butterfly anatomical sketch on textured
                          parchment, Da Vinci style
                generationConfig:
                  responseModalities:
                    - TEXT
                    - IMAGE
                  imageConfig:
                    aspectRatio: '1:1'
                    imageSize: 4K
            examples:
              text-to-image:
                summary: Text to Image
                value:
                  contents:
                    - role: user
                      parts:
                        - text: >-
                            A Monarch butterfly anatomical sketch on textured
                            parchment, Da Vinci style
                  generationConfig:
                    responseModalities:
                      - TEXT
                      - IMAGE
                    imageConfig:
                      aspectRatio: '1:1'
                      imageSize: 4K
              image-to-image:
                summary: Image to Image
                value:
                  contents:
                    - role: user
                      parts:
                        - text: Transform this into a watercolor painting
                        - inlineData:
                            mimeType: image/jpeg
                            data: <base64-encoded-image>
                  generationConfig:
                    responseModalities:
                      - TEXT
                      - IMAGE
              multi-image-composition:
                summary: Multi-Image Composition
                value:
                  contents:
                    - role: user
                      parts:
                        - text: Blend these images into one scene
                        - inlineData:
                            mimeType: image/jpeg
                            data: <base64-image-1>
                        - inlineData:
                            mimeType: image/jpeg
                            data: <base64-image-2>
                  generationConfig:
                    responseModalities:
                      - TEXT
                      - IMAGE
              force-image-only:
                summary: Force Image Output
                value:
                  contents:
                    - role: user
                      parts:
                        - text: A photo-realistic sunset over the ocean
                  generationConfig:
                    responseModalities:
                      - IMAGE
                    imageConfig:
                      aspectRatio: '16:9'
                      imageSize: 2K
              with-thinking:
                summary: With Thinking (3.1 Flash)
                value:
                  contents:
                    - role: user
                      parts:
                        - text: >-
                            A futuristic city inside a glass bottle floating in
                            space
                  generationConfig:
                    responseModalities:
                      - IMAGE
                    thinkingConfig:
                      thinkingLevel: high
                      includeThoughts: true
              with-search-grounding:
                summary: With Google Search Grounding
                value:
                  contents:
                    - role: user
                      parts:
                        - text: >-
                            Visualize the current weather forecast for San
                            Francisco as a chart
                  generationConfig:
                    responseModalities:
                      - TEXT
                      - IMAGE
                  tools:
                    - google_search: {}
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: object
                properties:
                  candidates:
                    type: array
                    items:
                      type: object
                      properties:
                        content:
                          type: object
                          properties:
                            role:
                              type: string
                              description: Always `model` for responses.
                            parts:
                              type: array
                              description: >-
                                Response parts — may contain text, images,
                                intermediate thought images, or a mix of these.
                                Skip image parts where `thought` is `true` when
                                saving the final output.
                              items:
                                type: object
                                properties:
                                  text:
                                    type: string
                                    description: Text content from the model.
                                  inlineData:
                                    type: object
                                    description: Generated image data.
                                    properties:
                                      mimeType:
                                        type: string
                                        description: >-
                                          MIME type of the returned image data,
                                          such as `image/jpeg`, `image/png`, or
                                          `image/webp`. Use it to choose the
                                          output file extension.
                                        example: image/jpeg
                                      data:
                                        type: string
                                        description: Base64-encoded image data.
                                  thought:
                                    type: boolean
                                    example: false
                                    description: >-
                                      Whether this part is an intermediate
                                      thought part rather than final user-facing
                                      output. Skip generated image parts where
                                      this value is `true`.
                                  thoughtSignature:
                                    type: string
                                    description: >-
                                      Provider signature metadata for
                                      thought-related response parts. Do not use
                                      this as the primary final-image selector;
                                      use `thought !== true` and save the last
                                      remaining image part.
                        finishReason:
                          type: string
                          description: Reason generation stopped.
                          enum:
                            - STOP
                            - MAX_TOKENS
                            - SAFETY
                            - RECITATION
                        index:
                          type: integer
                        safetyRatings:
                          type: array
                          items:
                            type: object
                            properties:
                              category:
                                type: string
                              probability:
                                type: string
                  usageMetadata:
                    type: object
                    properties:
                      promptTokenCount:
                        type: integer
                      candidatesTokenCount:
                        type: integer
                      totalTokenCount:
                        type: integer
                      thoughtsTokenCount:
                        type: integer
                        description: >-
                          Token count for thinking process (Gemini 3 models
                          only).
      x-codeSamples:
        - lang: Python
          label: Default
          source: |
            import os
            from pathlib import Path
            from google import genai
            from google.genai import types

            client = genai.Client(
                http_options={"api_version": "v1beta", "base_url": "https://api.runbridge.ai"},
                api_key=os.environ["RUNBRIDGE_API_KEY"],
            )

            response = client.models.generate_content(
                model="gemini-3.1-flash-image",
                contents="A Monarch butterfly anatomical sketch on textured parchment, Da Vinci style",
                config=types.GenerateContentConfig(
                    response_modalities=["TEXT", "IMAGE"],
                    image_config=types.ImageConfig(aspect_ratio="1:1", image_size="4K"),
                ),
            )

            final_image = None
            for part in response.parts:
                if getattr(part, "thought", False):
                    continue
                if part.text:
                    print(part.text)
                elif part.inline_data is not None:
                    final_image = part.inline_data

            if final_image:
                extension = {
                    "image/jpeg": "jpg",
                    "image/png": "png",
                    "image/webp": "webp",
                }.get(final_image.mime_type)
                if not extension:
                    raise ValueError(f"Unsupported image MIME type: {final_image.mime_type}")
                filename = f"output.{extension}"
                Path(filename).write_bytes(final_image.data)
        - lang: JavaScript
          label: Default
          source: |
            import { GoogleGenAI } from "@google/genai";
            import * as fs from "fs";

            const ai = new GoogleGenAI({
              apiKey: process.env.RUNBRIDGE_API_KEY,
              httpOptions: { apiVersion: "v1beta", baseUrl: "https://api.runbridge.ai" },
            });

            const response = await ai.models.generateContent({
              model: "gemini-3.1-flash-image",
              contents: "A Monarch butterfly anatomical sketch on textured parchment, Da Vinci style",
              config: {
                responseModalities: ["TEXT", "IMAGE"],
                imageConfig: { aspectRatio: "1:1", imageSize: "4K" },
              },
            });

            let finalImagePart;
            for (const part of response.candidates[0].content.parts) {
              if (part.thought === true) {
                continue;
              }
              if (part.text) {
                console.log(part.text);
              }
              if (part.inlineData) {
                finalImagePart = part;
              }
            }

            if (finalImagePart) {
              const mimeType = finalImagePart.inlineData.mimeType;
              const extension = {
                "image/jpeg": "jpg",
                "image/png": "png",
                "image/webp": "webp",
              }[mimeType];
              if (!extension) {
                throw new Error(`Unsupported image MIME type: ${mimeType}`);
              }
              const filename = `output.${extension}`;
              fs.writeFileSync(filename, Buffer.from(finalImagePart.inlineData.data, "base64"));
            }
        - lang: Shell
          label: Default
          source: |
            curl -s -X POST \
              "https://api.runbridge.ai/v1beta/models/gemini-3.1-flash-image:generateContent" \
              -H "x-goog-api-key: $RUNBRIDGE_API_KEY" \
              -H "Content-Type: application/json" \
              -d '{
                "contents": [{"parts": [{"text": "A Monarch butterfly anatomical sketch on textured parchment, Da Vinci style"}]}],
                "generationConfig": {
                  "responseModalities": ["TEXT", "IMAGE"],
                  "imageConfig": {"aspectRatio": "1:1", "imageSize": "4K"}
                }
              }'
        - lang: Python
          label: Nano Banana 2 Lite (1K)
          source: |
            import os
            from pathlib import Path
            from google import genai
            from google.genai import types

            client = genai.Client(
                http_options={"api_version": "v1beta", "base_url": "https://api.runbridge.ai"},
                api_key=os.environ["RUNBRIDGE_API_KEY"],
            )

            response = client.models.generate_content(
                model="gemini-3.1-flash-lite-image",
                contents="A Monarch butterfly anatomical sketch on textured parchment",
                config=types.GenerateContentConfig(
                    response_modalities=["TEXT", "IMAGE"],
                    image_config=types.ImageConfig(aspect_ratio="1:1", image_size="1K"),
                ),
            )

            final_image = None
            for part in response.parts:
                if getattr(part, "thought", False):
                    continue
                if part.text:
                    print(part.text)
                elif part.inline_data is not None:
                    final_image = part.inline_data

            if final_image:
                extension = {
                    "image/jpeg": "jpg",
                    "image/png": "png",
                    "image/webp": "webp",
                }.get(final_image.mime_type)
                if not extension:
                    raise ValueError(f"Unsupported image MIME type: {final_image.mime_type}")
                filename = f"output.{extension}"
                Path(filename).write_bytes(final_image.data)
        - lang: Python
          label: Image to Image
          source: |
            import os
            from pathlib import Path
            from google import genai
            from google.genai import types
            from PIL import Image

            client = genai.Client(
                http_options={"api_version": "v1beta", "base_url": "https://api.runbridge.ai"},
                api_key=os.environ["RUNBRIDGE_API_KEY"],
            )

            source_image = Image.open("source.jpg")

            response = client.models.generate_content(
                model="gemini-3.1-flash-image",
                contents=["Transform this into a watercolor painting", source_image],
                config=types.GenerateContentConfig(
                    response_modalities=["TEXT", "IMAGE"],
                ),
            )

            final_image = None
            for part in response.parts:
                if getattr(part, "thought", False):
                    continue
                if part.inline_data is not None:
                    final_image = part.inline_data

            if final_image:
                extension = {
                    "image/jpeg": "jpg",
                    "image/png": "png",
                    "image/webp": "webp",
                }.get(final_image.mime_type)
                if not extension:
                    raise ValueError(f"Unsupported image MIME type: {final_image.mime_type}")
                filename = f"output.{extension}"
                Path(filename).write_bytes(final_image.data)
        - lang: Python
          label: Multi-turn Chat
          source: >
            import os

            from pathlib import Path

            from google import genai

            from google.genai import types


            client = genai.Client(
                http_options={"api_version": "v1beta", "base_url": "https://api.runbridge.ai"},
                api_key=os.environ["RUNBRIDGE_API_KEY"],
            )


            chat = client.chats.create(
                model="gemini-3.1-flash-image",
                config=types.GenerateContentConfig(
                    response_modalities=["TEXT", "IMAGE"],
                ),
            )


            def save_final_image(response, stem):
                final_image = None
                for part in response.parts:
                    if getattr(part, "thought", False):
                        continue
                    if part.inline_data is not None:
                        final_image = part.inline_data
                if final_image:
                    extension = {
                        "image/jpeg": "jpg",
                        "image/png": "png",
                        "image/webp": "webp",
                    }.get(final_image.mime_type)
                    if not extension:
                        raise ValueError(f"Unsupported image MIME type: {final_image.mime_type}")
                    filename = f"{stem}.{extension}"
                    Path(filename).write_bytes(final_image.data)

            # First turn: generate

            response = chat.send_message("Create an infographic explaining
            photosynthesis")

            save_final_image(response, "v1")


            # Second turn: refine

            response = chat.send_message("Translate this to Spanish, keep other
            elements unchanged")

            save_final_image(response, "v2")
        - lang: Python
          label: With Thinking
          source: |
            import os
            from pathlib import Path
            from google import genai
            from google.genai import types

            client = genai.Client(
                http_options={"api_version": "v1beta", "base_url": "https://api.runbridge.ai"},
                api_key=os.environ["RUNBRIDGE_API_KEY"],
            )

            response = client.models.generate_content(
                model="gemini-3.1-flash-image",
                contents="A futuristic city inside a glass bottle floating in space",
                config=types.GenerateContentConfig(
                    response_modalities=["IMAGE"],
                    thinking_config=types.ThinkingConfig(
                        thinking_level="HIGH",
                        include_thoughts=True,
                    ),
                ),
            )

            final_image = None
            for part in response.parts:
                if getattr(part, "thought", False):
                    continue
                if part.inline_data is not None:
                    final_image = part.inline_data

            if final_image:
                extension = {
                    "image/jpeg": "jpg",
                    "image/png": "png",
                    "image/webp": "webp",
                }.get(final_image.mime_type)
                if not extension:
                    raise ValueError(f"Unsupported image MIME type: {final_image.mime_type}")
                filename = f"output.{extension}"
                Path(filename).write_bytes(final_image.data)
        - lang: Python
          label: With Search Grounding
          source: |
            import os
            from pathlib import Path
            from google import genai
            from google.genai import types

            client = genai.Client(
                http_options={"api_version": "v1beta", "base_url": "https://api.runbridge.ai"},
                api_key=os.environ["RUNBRIDGE_API_KEY"],
            )

            response = client.models.generate_content(
                model="gemini-3.1-flash-image",
                contents="Visualize the current weather in San Francisco as a chart",
                config=types.GenerateContentConfig(
                    response_modalities=["TEXT", "IMAGE"],
                    tools=[types.Tool(google_search=types.GoogleSearch())],
                ),
            )

            final_image = None
            for part in response.parts:
                if getattr(part, "thought", False):
                    continue
                if part.inline_data is not None:
                    final_image = part.inline_data

            if final_image:
                extension = {
                    "image/jpeg": "jpg",
                    "image/png": "png",
                    "image/webp": "webp",
                }.get(final_image.mime_type)
                if not extension:
                    raise ValueError(f"Unsupported image MIME type: {final_image.mime_type}")
                filename = f"weather.{extension}"
                Path(filename).write_bytes(final_image.data)
        - lang: Python
          label: Force Image Only
          source: |
            import os
            from pathlib import Path
            from google import genai
            from google.genai import types

            client = genai.Client(
                http_options={"api_version": "v1beta", "base_url": "https://api.runbridge.ai"},
                api_key=os.environ["RUNBRIDGE_API_KEY"],
            )

            response = client.models.generate_content(
                model="gemini-3-pro-image",
                contents="A photo-realistic sunset over the ocean",
                config=types.GenerateContentConfig(
                    response_modalities=["IMAGE"],
                    image_config=types.ImageConfig(aspect_ratio="16:9", image_size="2K"),
                ),
            )

            final_image = None
            for part in response.parts:
                if getattr(part, "thought", False):
                    continue
                if part.inline_data is not None:
                    final_image = part.inline_data

            if final_image:
                extension = {
                    "image/jpeg": "jpg",
                    "image/png": "png",
                    "image/webp": "webp",
                }.get(final_image.mime_type)
                if not extension:
                    raise ValueError(f"Unsupported image MIME type: {final_image.mime_type}")
                filename = f"sunset.{extension}"
                Path(filename).write_bytes(final_image.data)
        - lang: JavaScript
          label: Nano Banana 2 Lite (1K)
          source: |
            import { GoogleGenAI } from "@google/genai";
            import * as fs from "fs";

            const ai = new GoogleGenAI({
              apiKey: process.env.RUNBRIDGE_API_KEY,
              httpOptions: { apiVersion: "v1beta", baseUrl: "https://api.runbridge.ai" },
            });

            const response = await ai.models.generateContent({
              model: "gemini-3.1-flash-lite-image",
              contents: "A Monarch butterfly anatomical sketch on textured parchment",
              config: {
                responseModalities: ["TEXT", "IMAGE"],
                imageConfig: { aspectRatio: "1:1", imageSize: "1K" },
              },
            });

            let finalImagePart;
            for (const part of response.candidates[0].content.parts) {
              if (part.thought === true) {
                continue;
              }
              if (part.text) {
                console.log(part.text);
              }
              if (part.inlineData) {
                finalImagePart = part;
              }
            }

            if (finalImagePart) {
              const mimeType = finalImagePart.inlineData.mimeType;
              const extension = {
                "image/jpeg": "jpg",
                "image/png": "png",
                "image/webp": "webp",
              }[mimeType];
              if (!extension) {
                throw new Error(`Unsupported image MIME type: ${mimeType}`);
              }
              const filename = `output.${extension}`;
              fs.writeFileSync(filename, Buffer.from(finalImagePart.inlineData.data, "base64"));
            }
        - lang: JavaScript
          label: Image to Image
          source: |
            import { GoogleGenAI } from "@google/genai";
            import * as fs from "fs";

            const ai = new GoogleGenAI({
              apiKey: process.env.RUNBRIDGE_API_KEY,
              httpOptions: { apiVersion: "v1beta", baseUrl: "https://api.runbridge.ai" },
            });

            const imageData = fs.readFileSync("source.jpg").toString("base64");

            const response = await ai.models.generateContent({
              model: "gemini-3.1-flash-image",
              contents: [
                { text: "Transform this into a watercolor painting" },
                { inlineData: { mimeType: "image/jpeg", data: imageData } },
              ],
              config: { responseModalities: ["TEXT", "IMAGE"] },
            });

            const imageParts = response.candidates[0].content.parts.filter(
              (part) => part.inlineData && part.thought !== true,
            );
            const finalImagePart = imageParts.at(-1);

            if (finalImagePart) {
              const mimeType = finalImagePart.inlineData.mimeType;
              const extension = {
                "image/jpeg": "jpg",
                "image/png": "png",
                "image/webp": "webp",
              }[mimeType];
              if (!extension) {
                throw new Error(`Unsupported image MIME type: ${mimeType}`);
              }
              const filename = `output.${extension}`;
              fs.writeFileSync(filename, Buffer.from(finalImagePart.inlineData.data, "base64"));
            }
        - lang: JavaScript
          label: Multi-turn Chat
          source: >
            import { GoogleGenAI } from "@google/genai";

            import * as fs from "fs";


            const ai = new GoogleGenAI({
              apiKey: process.env.RUNBRIDGE_API_KEY,
              httpOptions: { apiVersion: "v1beta", baseUrl: "https://api.runbridge.ai" },
            });


            const chat = ai.chats.create({
              model: "gemini-3.1-flash-image",
              config: { responseModalities: ["TEXT", "IMAGE"] },
            });


            function saveFinalImage(response, stem) {
              const imageParts = response.candidates[0].content.parts.filter(
                (part) => part.inlineData && part.thought !== true,
              );
              const finalImagePart = imageParts.at(-1);
              if (finalImagePart) {
                const mimeType = finalImagePart.inlineData.mimeType;
                const extension = {
                  "image/jpeg": "jpg",
                  "image/png": "png",
                  "image/webp": "webp",
                }[mimeType];
                if (!extension) {
                  throw new Error(`Unsupported image MIME type: ${mimeType}`);
                }
                const filename = `${stem}.${extension}`;
                fs.writeFileSync(filename, Buffer.from(finalImagePart.inlineData.data, "base64"));
              }
            }


            const r1 = await chat.sendMessage({ message: "Create an infographic
            explaining photosynthesis" });

            saveFinalImage(r1, "v1");


            const r2 = await chat.sendMessage({ message: "Translate this to
            Spanish, keep other elements unchanged" });

            saveFinalImage(r2, "v2");
        - lang: JavaScript
          label: With Search Grounding
          source: |
            import { GoogleGenAI } from "@google/genai";
            import fs from "node:fs";

            const ai = new GoogleGenAI({
                apiKey: process.env.RUNBRIDGE_API_KEY,
                httpOptions: { apiVersion: "v1beta", baseUrl: "https://api.runbridge.ai" },
            });

            const response = await ai.models.generateContent({
                model: "gemini-3.1-flash-image",
                contents: "Visualize the current weather in San Francisco as a chart",
                config: {
                    responseModalities: ["TEXT", "IMAGE"],
                    tools: [{ googleSearch: {} }],
                },
            });

            const imageParts = response.candidates[0].content.parts.filter(
                (part) => part.inlineData && part.thought !== true,
            );
            const finalImagePart = imageParts.at(-1);

            if (finalImagePart) {
                const mimeType = finalImagePart.inlineData.mimeType;
                const extension = {
                  "image/jpeg": "jpg",
                  "image/png": "png",
                  "image/webp": "webp",
                }[mimeType];
                if (!extension) {
                  throw new Error(`Unsupported image MIME type: ${mimeType}`);
                }
                const filename = `weather.${extension}`;
                fs.writeFileSync(filename, Buffer.from(finalImagePart.inlineData.data, "base64"));
            }
        - lang: JavaScript
          label: With Thinking
          source: |
            import { GoogleGenAI } from "@google/genai";
            import fs from "node:fs";

            const ai = new GoogleGenAI({
                apiKey: process.env.RUNBRIDGE_API_KEY,
                httpOptions: { apiVersion: "v1beta", baseUrl: "https://api.runbridge.ai" },
            });

            const response = await ai.models.generateContent({
                model: "gemini-3.1-flash-image",
                contents: "A futuristic city inside a glass bottle floating in space",
                config: {
                    responseModalities: ["IMAGE"],
                    thinkingConfig: { thinkingLevel: "HIGH", includeThoughts: true },
                },
            });

            const imageParts = response.candidates[0].content.parts.filter(
                (part) => part.inlineData && part.thought !== true,
            );
            const finalImagePart = imageParts.at(-1);

            if (finalImagePart) {
                const mimeType = finalImagePart.inlineData.mimeType;
                const extension = {
                  "image/jpeg": "jpg",
                  "image/png": "png",
                  "image/webp": "webp",
                }[mimeType];
                if (!extension) {
                  throw new Error(`Unsupported image MIME type: ${mimeType}`);
                }
                const filename = `city.${extension}`;
                fs.writeFileSync(filename, Buffer.from(finalImagePart.inlineData.data, "base64"));
            }
        - lang: JavaScript
          label: Force Image Only
          source: |
            import { GoogleGenAI } from "@google/genai";
            import fs from "node:fs";

            const ai = new GoogleGenAI({
                apiKey: process.env.RUNBRIDGE_API_KEY,
                httpOptions: { apiVersion: "v1beta", baseUrl: "https://api.runbridge.ai" },
            });

            const response = await ai.models.generateContent({
                model: "gemini-3-pro-image",
                contents: "A photo-realistic sunset over the ocean",
                config: {
                    responseModalities: ["IMAGE"],
                    imageConfig: { aspectRatio: "16:9", imageSize: "2K" },
                },
            });

            const imageParts = response.candidates[0].content.parts.filter(
                (part) => part.inlineData && part.thought !== true,
            );
            const finalImagePart = imageParts.at(-1);

            if (finalImagePart) {
                const mimeType = finalImagePart.inlineData.mimeType;
                const extension = {
                  "image/jpeg": "jpg",
                  "image/png": "png",
                  "image/webp": "webp",
                }[mimeType];
                if (!extension) {
                  throw new Error(`Unsupported image MIME type: ${mimeType}`);
                }
                const filename = `sunset.${extension}`;
                fs.writeFileSync(filename, Buffer.from(finalImagePart.inlineData.data, "base64"));
            }
        - lang: Shell
          label: Nano Banana 2 Lite (1K)
          source: |
            curl -s -X POST \
              "https://api.runbridge.ai/v1beta/models/gemini-3.1-flash-lite-image:generateContent" \
              -H "x-goog-api-key: $RUNBRIDGE_API_KEY" \
              -H "Content-Type: application/json" \
              -d '{
                "contents": [{"parts": [{"text": "A Monarch butterfly anatomical sketch on textured parchment"}]}],
                "generationConfig": {
                  "responseModalities": ["TEXT", "IMAGE"],
                  "imageConfig": {"aspectRatio": "1:1", "imageSize": "1K"}
                }
              }'
        - lang: Shell
          label: Force Image Only
          source: |
            curl -s -X POST \
              "https://api.runbridge.ai/v1beta/models/gemini-3-pro-image:generateContent" \
              -H "x-goog-api-key: $RUNBRIDGE_API_KEY" \
              -H "Content-Type: application/json" \
              -d '{
                "contents": [{"parts": [{"text": "A photo-realistic sunset over the ocean"}]}],
                "generationConfig": {
                  "responseModalities": ["IMAGE"],
                  "imageConfig": {"aspectRatio": "16:9", "imageSize": "2K"}
                }
              }'
        - lang: Shell
          label: With Search Grounding
          source: |
            curl -s -X POST \
              "https://api.runbridge.ai/v1beta/models/gemini-3.1-flash-image:generateContent" \
              -H "x-goog-api-key: $RUNBRIDGE_API_KEY" \
              -H "Content-Type: application/json" \
              -d '{
                "contents": [{"parts": [{"text": "Visualize the current weather in San Francisco as a chart"}]}],
                "generationConfig": {"responseModalities": ["TEXT", "IMAGE"]},
                "tools": [{"google_search": {}}]
              }'
        - lang: Shell
          label: Image to Image
          source: |
            python3 - <<'PYTHON'
            import base64
            import json
            from pathlib import Path

            parts = [{"text": "Transform this into a watercolor painting"}]
            for filename in ('source.jpg',):
                image_data = base64.b64encode(Path(filename).read_bytes()).decode("ascii")
                parts.append({
                    "inlineData": {"mimeType": "image/jpeg", "data": image_data}
                })

            request = {
                "contents": [{"role": "user", "parts": parts}],
                "generationConfig": {"responseModalities": ["TEXT", "IMAGE"]},
            }
            Path("nano-banana-request.json").write_text(json.dumps(request))
            PYTHON

            curl -s -X POST \
              "https://api.runbridge.ai/v1beta/models/gemini-3.1-flash-image:generateContent" \
              -H "x-goog-api-key: $RUNBRIDGE_API_KEY" \
              -H "Content-Type: application/json" \
              --data-binary @nano-banana-request.json
        - lang: Shell
          label: Multi-turn Chat
          source: |
            curl -s -X POST \
              "https://api.runbridge.ai/v1beta/models/gemini-3.1-flash-image:generateContent" \
              -H "x-goog-api-key: $RUNBRIDGE_API_KEY" \
              -H "Content-Type: application/json" \
              -d '{
                "contents": [
                  {"role": "user", "parts": [{"text": "Create an infographic explaining photosynthesis"}]},
                  {"role": "model", "parts": [{"text": "Here is the infographic."}]},
                  {"role": "user", "parts": [{"text": "Translate this to Spanish, keep other elements unchanged"}]}
                ],
                "generationConfig": {"responseModalities": ["TEXT", "IMAGE"]}
              }'
        - lang: Shell
          label: With Thinking
          source: |
            curl -s -X POST \
              "https://api.runbridge.ai/v1beta/models/gemini-3.1-flash-image:generateContent" \
              -H "x-goog-api-key: $RUNBRIDGE_API_KEY" \
              -H "Content-Type: application/json" \
              -d '{
                "contents": [{"parts": [{"text": "A futuristic city inside a glass bottle floating in space"}]}],
                "generationConfig": {
                  "responseModalities": ["IMAGE"],
                  "thinkingConfig": {"thinkingLevel": "HIGH", "includeThoughts": true}
                }
              }'
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: Use your RunBridge AI API key.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.