# Gemini API Source: https://aistudio.google.com/docs Description: Build apps and agents with Gemini, Nano Banana, Gemini Omni, and Lyria using the Gemini API documentation and reference. {% two-column-layout %} {% left-column %} # Welcome to Gemini API {% class="h0" %} Go from a quick prompt to production apps and agents with the Gemini API. Tackle complex coding and multimodal reasoning with Gemini, or hand multi-step work to a managed agent. Stream voice and video with the Live API, or generate images with Nano Banana, video with Gemini Omni, and music with Lyria. {% button href="/docs/get-started" variant="ais" size="large" %}Get Started{% /button %} {% button href="https://aistudio.google.com/apikey" variant="primary" size="large" %}Create API Key{% /button %} {% /left-column %} {% right-column %} {% tabs %} {% tab label="Agents" %} ```bash # Connect the Gemini Docs MCP server npx add-mcp "https://gemini-api-docs-mcp.dev" # Install Gemini API agent skills npx skills add google-gemini/gemini-skills --skill gemini-api-dev # Or install the Antigravity plugin (MCP + skills) agy plugin install https://github.com/google-gemini/gemini-skills # Install the experimental Gemini API CLI on macOS and Linux curl -fsSL https://raw.githubusercontent.com/google-gemini/gemini-api-cli/main/scripts/install.sh | bash ``` {% /tab %} {% tab label="Python" filename="main.py" %} ```python from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-4-argon", input="Explain how AI works in a few words" ) print(interaction.output_text) ``` {% /tab %} {% tab label="JavaScript" filename="index.js" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: "gemini-4-argon", input: "Explain how AI works in a few words", }); console.log(interaction.output_text); ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -d '{ "model": "gemini-4-argon", "input": "Explain how AI works in a few words" }' ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-4-argon")) .input(InteractionsInput.of("Explain how AI works in a few words")) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); System.out.println(interaction.outputText().orElse("")); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-4-argon"), Input: interactions.NewInteractionsInput("Explain how AI works in a few words"), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputText != nil { fmt.Println(*res.Interaction.OutputText) } } ``` {% /tab %} {% /tabs %} {% /right-column %} {% /two-column-layout %} ## Meet the models {% class="hide-from-toc" id="meet-the-models" %} {% card-grid columns="3" %} {% card title="Gemini 4 Argon" description="Our flagship reasoning model with a shared 1M context window and long decodes up to 1M tokens." variant="model-card" %} {% section class="model-specs" %} * *Model code* **gemini-4-argon** * *Context* **1M tokens** * *Max output* **65K / 1M tokens** * *Modalities* **Text, Image, Audio, Video, PDF** {% /section %} {% section class="card-actions" %} {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-4-argon" variant="primary" tooltip="Try Gemini 4 Argon in AI Studio" %}Try in AI Studio{% /button %} {% button href="/docs/models/gemini-4-argon" variant="icon-primary" icon="arrow_forward" tooltip="View Gemini 4 Argon model details" %}{% /button %} {% /section %} {% /card %} {% card title="Gemini 3.8 Flash" description="Our most intelligent Flash model, engineered for long-horizon software engineering, autonomous agents, and complex enterprise workflows." variant="model-card" %} {% section class="model-specs" %} * *Model code* **gemini-3.8-flash** * *Context* **1M tokens** * *Max output* **65K tokens** * *Modalities* **Text, Image, Audio, Video, PDF** {% /section %} {% section class="card-actions" %} {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-3.8-flash" variant="primary" tooltip="Try Gemini 3.8 Flash in AI Studio" %}Try in AI Studio{% /button %} {% button href="/docs/models/gemini-3.8-flash" variant="icon-primary" icon="arrow_forward" tooltip="View Gemini 3.8 Flash model details" %}{% /button %} {% /section %} {% /card %} {% card title="Gemini 3.8 Live" description="Default Live API model for low-latency, bidirectional voice and video agent experiences without reasoning delays." variant="model-card" %} {% section class="model-specs" %} * *Model code* **gemini-3.8-live** * *Context* **128K tokens** * *Max output* **8K tokens** * *Modalities* **Audio, Video, Text → Audio, Text** {% /section %} {% section class="card-actions" %} {% button href="https://aistudio.google.com/live" variant="primary" tooltip="Try Gemini 3.8 Live in AI Studio" %}Try in AI Studio{% /button %} {% button href="/docs/models/gemini-3.8-live" variant="icon-primary" icon="arrow_forward" tooltip="View Gemini 3.8 Live model details" %}{% /button %} {% /section %} {% /card %} {% card title="Gemini 3.8 Flash TTS" description="Flagship creative text-to-speech model for studio-grade voice fidelity, expressive acting, Voice design, and Voice replication." variant="model-card" %} {% section class="model-specs" %} * *Model code* **gemini-3.8-flash-tts** * *Context* **8K tokens** * *Max output* **16K tokens** * *Modalities* **Text → Audio** {% /section %} {% section class="card-actions" %} {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-3.8-flash-tts" variant="primary" tooltip="Try Gemini 3.8 Flash TTS in AI Studio" %}Try in AI Studio{% /button %} {% button href="/docs/models/gemini-3.8-flash-tts" variant="icon-primary" icon="arrow_forward" tooltip="View Gemini 3.8 Flash TTS model details" %}{% /button %} {% /section %} {% /card %} {% card title="Nano Banana Pro" description="State-of-the-art image generation and editing model for studio-quality precision, accurate text rendering, and complex visual creation." variant="model-card" %} {% section class="model-specs" %} * *Model code* **gemini-3-pro-image** * *Context* **65K tokens** * *Max output* **32K tokens** * *Modalities* **Text, Image → Image, Text** {% /section %} {% section class="card-actions" %} {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-3-pro-image" variant="primary" tooltip="Try Nano Banana Pro in AI Studio" %}Try in AI Studio{% /button %} {% button href="/docs/models/gemini-3-pro-image" variant="icon-primary" icon="arrow_forward" tooltip="View Nano Banana Pro model details" %}{% /button %} {% /section %} {% /card %} {% card title="View all models" href="/docs/models" variant="view-more" %} {% /card %} {% /card-grid %} ## Explore Capabilities {% class="hide-from-toc" id="explore-capabilities" %} {% tabs variant="showcase" %} {% tab label="Image" %} {% two-column-layout class="capability-panel" %} {% left-column %} {% tabs %} {% tab label="Python" filename="image_gen.py" %} ```python from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-3.1-flash-image-preview", input="Generate an image of a nano banana dish in a fancy restaurant", generation_config={ "image_config": {"aspect_ratio": "16:9", "image_size": "2k"} }, ) for output in interaction.outputs: if output.type == "image": with open("nano_banana.png", "wb") as f: f.write(output.image_bytes) ``` {% /tab %} {% tab label="JavaScript" filename="image_gen.js" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: "gemini-3.1-flash-image-preview", input: "Generate an image of a nano banana dish in a fancy restaurant", generationConfig: { imageConfig: { aspectRatio: "16:9", imageSize: "2k" }, }, }); for (const output of interaction.outputs) { if (output.type === "image") { fs.writeFileSync("nano_banana.png", Buffer.from(output.data, "base64")); } } ``` {% /tab %} {% /tabs %} {% /left-column %} {% right-column class="capability-details" %} ### Image generation Generate and edit highly contextual images natively with Nano Banana models using text, image, or interleaved multimodal prompts. {% section class="capability-highlights" %} * {% icon name="check" /%} **Up to 4K resolution** with flexible aspect ratios * {% icon name="check" /%} **Multi-turn editing** and character consistency * {% icon name="check" /%} **Search-grounded** visual accuracy and text rendering {% /section %} {% button href="/docs/image-generation" variant="ais" tooltip="Read Image generation docs" %}Read docs{% /button %} {% /right-column %} {% /two-column-layout %} {% /tab %} {% tab label="Video" %} {% two-column-layout class="capability-panel" %} {% left-column %} {% tabs %} {% tab label="Python" filename="video_gen.py" %} ```python import time from google import genai client = genai.Client() operation = client.models.generate_videos( model="gemini-omni-1.1-flash", prompt="A cinematic close-up of two people talking by a window in the rain", ) while not operation.done: time.sleep(10) operation = client.operations.get(operation) video = operation.response.generated_videos[0] client.files.download(file=video.video) video.video.save("dialogue_example.mp4") ``` {% /tab %} {% tab label="JavaScript" filename="video_gen.js" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); let operation = await ai.models.generateVideos({ model: "gemini-omni-1.1-flash", prompt: "A cinematic close-up of two people talking by a window in the rain", }); while (!operation.done) { await new Promise((resolve) => setTimeout(resolve, 10000)); operation = await ai.operations.getVideosOperation({ operation }); } await ai.files.download({ file: operation.response.generatedVideos[0].video, downloadPath: "dialogue_example.mp4", }); ``` {% /tab %} {% /tabs %} {% /left-column %} {% right-column class="capability-details" %} ### Video generation Create high-definition video with natively synchronized dialogue, sound effects, and ambient audio from text or image prompts. {% section class="capability-highlights" %} * {% icon name="check" /%} **Native audio & dialogue** synchronized to motion * {% icon name="check" /%} **Frame interpolation** with first and last frame control * {% icon name="check" /%} **Reference images** to preserve character and style {% /section %} {% button href="/docs/video" variant="ais" tooltip="Read Video generation docs" %}Read docs{% /button %} {% /right-column %} {% /two-column-layout %} {% /tab %} {% tab label="Voice" %} {% two-column-layout class="capability-panel" %} {% left-column %} {% tabs %} {% tab label="Python" filename="live_agent.py" %} ```python import asyncio from google import genai from google.genai import types client = genai.Client() async def main(): config = types.LiveConnectConfig(response_modalities=["AUDIO"]) async with client.aio.live.connect( model="gemini-3.8-live-preview", config=config ) as session: await session.send_client_content( turns={"parts": [{"text": "Hello! Tell me a quick fun fact."}]} ) async for response in session.receive(): if response.data is not None: # Stream raw PCM audio bytes to speaker pass asyncio.run(main()) ``` {% /tab %} {% tab label="JavaScript" filename="live_agent.js" %} ```javascript import { GoogleGenAI, Modality } from "@google/genai"; const ai = new GoogleGenAI({}); const session = await ai.live.connect({ model: "gemini-3.8-live-preview", config: { responseModalities: [Modality.AUDIO] }, callbacks: { onmessage: (message) => { if (message.serverContent?.modelTurn) { // Handle low-latency streaming audio chunks } }, }, }); session.sendClientContent({ turns: [{ parts: [{ text: "Hello! Tell me a quick fun fact." }] }], }); ``` {% /tab %} {% /tabs %} {% /left-column %} {% right-column class="capability-details" %} ### Voice agents with Live API Build real-time, bidirectional voice and video agents with sub-second latency, natural barge-in, and live tool calling. {% section class="capability-highlights" %} * {% icon name="check" /%} **Real-time WebSocket streaming** for audio and video * {% icon name="check" /%} **Natural voice activity detection** and interruption handling * {% icon name="check" /%} **Expressive multilingual voices** with affective dialogue {% /section %} {% button href="/docs/live-api" variant="ais" tooltip="Read Live API docs" %}Read docs{% /button %} {% /right-column %} {% /two-column-layout %} {% /tab %} {% tab label="Thinking" %} {% two-column-layout class="capability-panel" %} {% left-column %} {% tabs %} {% tab label="Python" filename="thinking.py" %} ```python from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-3.8-flash", input="Find the flaw in this distributed lock protocol and fix it.", generation_config={ "thinking_level": "high", "thinking_summaries": "auto", }, ) for output in interaction.outputs: if output.type == "thought": print("Thought summary:", output.summary) elif output.type == "text": print("Answer:", output.text) ``` {% /tab %} {% tab label="JavaScript" filename="thinking.js" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: "gemini-3.8-flash", input: "Find the flaw in this distributed lock protocol and fix it.", generationConfig: { thinkingLevel: "high", thinkingSummaries: "auto", }, }); for (const output of interaction.outputs) { if (output.type === "thought") { console.log("Thought summary:", output.summary); } else if (output.type === "text") { console.log("Answer:", output.text); } } ``` {% /tab %} {% /tabs %} {% /left-column %} {% right-column class="capability-details" %} ### Adaptive thinking Control how deeply Gemini reasons before responding—from zero-latency `minimal` thinking to deep multi-step `high` reasoning. {% section class="capability-highlights" %} * {% icon name="check" /%} **Configurable thinking levels** (minimal, low, medium, high) * {% icon name="check" /%} **Transparent thought summaries** streamed in real time * {% icon name="check" /%} **Interleaved reasoning** across tool calls and code execution {% /section %} {% button href="/docs/thinking" variant="ais" tooltip="Read Adaptive thinking docs" %}Read docs{% /button %} {% /right-column %} {% /two-column-layout %} {% /tab %} {% tab label="Tools" %} {% two-column-layout class="capability-panel" %} {% left-column %} {% tabs %} {% tab label="Python" filename="tools.py" %} ```python from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-3.8-flash", input="Who won the latest F1 Grand Prix and what were the lap times?", tools=[{"type": "google_search"}, {"type": "code_execution"}], ) for output in interaction.outputs: if output.type == "text": print(output.text) ``` {% /tab %} {% tab label="JavaScript" filename="tools.js" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: "gemini-3.8-flash", input: "Who won the latest F1 Grand Prix and what were the lap times?", tools: [{ type: "google_search" }, { type: "code_execution" }], }); const textOutput = interaction.outputs.find((o) => o.type === "text"); console.log(textOutput?.text); ``` {% /tab %} {% /tabs %} {% /left-column %} {% right-column class="capability-details" %} ### Built-in tools & function calling Connect Gemini to live information, computation, and your own backend APIs with hosted tools and custom function declarations. {% section class="capability-highlights" %} * {% icon name="check" /%} **Google Search & URL Context** for live web grounding * {% icon name="check" /%} **Code Execution** in a secure Python sandbox * {% icon name="check" /%} **Custom Function Calling** for parallel multi-tool orchestration {% /section %} {% button href="/docs/tools" variant="ais" tooltip="Read Tools and function calling docs" %}Read docs{% /button %} {% /right-column %} {% /two-column-layout %} {% /tab %} {% tab label="Structured" %} {% two-column-layout class="capability-panel" %} {% left-column %} {% tabs %} {% tab label="Python" filename="structured.py" %} ```python from google import genai from pydantic import BaseModel, Field class FeedbackAnalysis(BaseModel): sentiment: str = Field(description="positive, neutral, or negative") summary: str = Field(description="One-sentence summary of the feedback.") action_items: list[str] client = genai.Client() interaction = client.interactions.create( model="gemini-3.8-flash", input="The new dashboard is fast, but exporting CSVs fails on mobile.", response_format=FeedbackAnalysis.model_json_schema(), ) print(interaction.output_text) ``` {% /tab %} {% tab label="JavaScript" filename="structured.js" %} ```javascript import { GoogleGenAI } from "@google/genai"; import { z } from "zod"; const FeedbackSchema = z.object({ sentiment: z.enum(["positive", "neutral", "negative"]), summary: z.string(), actionItems: z.array(z.string()), }); const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: "gemini-3.8-flash", input: "The new dashboard is fast, but exporting CSVs fails on mobile.", response_format: z.toJSONSchema(FeedbackSchema), }); console.log(JSON.parse(interaction.output_text)); ``` {% /tab %} {% /tabs %} {% /left-column %} {% right-column class="capability-details" %} ### Structured outputs Constrain Gemini responses to follow a strict JSON Schema, Pydantic model, or Zod type for reliable downstream automation. {% section class="capability-highlights" %} * {% icon name="check" /%} **Guaranteed JSON Schema** compliance on every response * {% icon name="check" /%} **Native Pydantic & Zod** schema integration * {% icon name="check" /%} **Compatible with tools** like Google Search and Code Execution {% /section %} {% button href="/docs/structured-output" variant="ais" tooltip="Read Structured outputs docs" %}Read docs{% /button %} {% /right-column %} {% /two-column-layout %} {% /tab %} {% tab label="Long context" %} {% two-column-layout class="capability-panel" %} {% left-column %} {% tabs %} {% tab label="Python" filename="long_context.py" %} ```python from google import genai client = genai.Client() uploaded_file = client.files.upload(file="full_codebase_archive.txt") interaction = client.interactions.create( model="gemini-3.8-flash", input=[ {"type": "file", "file_uri": uploaded_file.uri}, { "type": "text", "text": "Trace how authentication tokens are refreshed across all services.", }, ], ) print(interaction.output_text) ``` {% /tab %} {% tab label="JavaScript" filename="long_context.js" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); const uploadedFile = await ai.files.upload({ file: "full_codebase_archive.txt", }); const interaction = await ai.interactions.create({ model: "gemini-3.8-flash", input: [ { type: "file", fileUri: uploadedFile.uri }, { type: "text", text: "Trace how authentication tokens are refreshed across all services.", }, ], }); console.log(interaction.output_text); ``` {% /tab %} {% /tabs %} {% /left-column %} {% right-column class="capability-details" %} ### Long context Input up to 1 million tokens of code, video, audio, or documents in a single prompt for deep cross-file reasoning and in-context learning. {% section class="capability-highlights" %} * {% icon name="check" /%} **1M+ token context window** (~50,000 lines of code or 8 novels) * {% icon name="check" /%} **Near-perfect recall** across long multimodal inputs * {% icon name="check" /%} **Context caching** to reduce cost and latency on repeated prompts {% /section %} {% button href="/docs/long-context" variant="ais" tooltip="Read Long context docs" %}Read docs{% /button %} {% /right-column %} {% /two-column-layout %} {% /tab %} {% tab label="Function calling" %} {% two-column-layout class="capability-panel" %} {% left-column %} {% tabs %} {% tab label="Python" filename="function_calling.py" %} ```python from google import genai schedule_meeting = { "type": "function", "name": "schedule_meeting", "description": "Schedules a meeting with attendees at a given date and time.", "parameters": { "type": "object", "properties": { "attendees": {"type": "array", "items": {"type": "string"}}, "date": {"type": "string"}, "time": {"type": "string"}, "topic": {"type": "string"}, }, "required": ["attendees", "date", "time", "topic"], }, } client = genai.Client() interaction = client.interactions.create( model="gemini-3.8-flash", input="Schedule a meeting with Bob and Alice tomorrow at 10:00 AM about Q3 planning.", tools=[schedule_meeting], ) for output in interaction.outputs: if output.type == "function_call": print(output.name, output.arguments) ``` {% /tab %} {% tab label="JavaScript" filename="function_calling.js" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); const scheduleMeeting = { type: "function", name: "schedule_meeting", description: "Schedules a meeting with attendees at a given date and time.", parameters: { type: "object", properties: { attendees: { type: "array", items: { type: "string" } }, date: { type: "string" }, time: { type: "string" }, topic: { type: "string" }, }, required: ["attendees", "date", "time", "topic"], }, }; const interaction = await ai.interactions.create({ model: "gemini-3.8-flash", input: "Schedule a meeting with Bob and Alice tomorrow at 10:00 AM about Q3 planning.", tools: [scheduleMeeting], }); for (const output of interaction.outputs) { if (output.type === "function_call") { console.log(output.name, output.arguments); } } ``` {% /tab %} {% /tabs %} {% /left-column %} {% right-column class="capability-details" %} ### Function calling Connect Gemini to your own APIs, databases, and backend services with structured function declarations and automatic argument extraction. {% section class="capability-highlights" %} * {% icon name="check" /%} **Parallel & compositional** multi-step function calls * {% icon name="check" /%} **Strict schema adherence** for tool arguments * {% icon name="check" /%} **Seamless integration** with built-in tools and thinking {% /section %} {% button href="/docs/function-calling" variant="ais" tooltip="Read Function calling docs" %}Read docs{% /button %} {% /right-column %} {% /two-column-layout %} {% /tab %} {% tab label="Document understanding" %} {% two-column-layout class="capability-panel" %} {% left-column %} {% tabs %} {% tab label="Python" filename="document_understanding.py" %} ```python import base64 from google import genai client = genai.Client() with open("financial_report.pdf", "rb") as f: pdf_base64 = base64.b64encode(f.read()).decode("utf-8") interaction = client.interactions.create( model="gemini-3.8-flash", input=[ { "type": "document", "data": pdf_base64, "mime_type": "application/pdf", }, { "type": "text", "text": "Summarize the key revenue drivers and extract the Q4 table.", }, ], ) print(interaction.output_text) ``` {% /tab %} {% tab label="JavaScript" filename="document_understanding.js" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; const ai = new GoogleGenAI({}); const pdfData = fs.readFileSync("financial_report.pdf", { encoding: "base64", }); const interaction = await ai.interactions.create({ model: "gemini-3.8-flash", input: [ { type: "document", data: pdfData, mime_type: "application/pdf", }, { type: "text", text: "Summarize the key revenue drivers and extract the Q4 table.", }, ], }); console.log(interaction.output_text); ``` {% /tab %} {% /tabs %} {% /left-column %} {% right-column class="capability-details" %} ### Document understanding Process up to 1,000 pages of PDFs with native visual and textual comprehension across tables, charts, diagrams, and layouts. {% section class="capability-highlights" %} * {% icon name="check" /%} **Native vision-based PDF parsing** beyond plain OCR * {% icon name="check" /%} **Up to 1,000 pages** per document in a single request * {% icon name="check" /%} **Structured extraction** of complex tables, forms, and figures {% /section %} {% button href="/docs/document-processing" variant="ais" tooltip="Read Document understanding docs" %}Read docs{% /button %} {% /right-column %} {% /two-column-layout %} {% /tab %} {% /tabs %} ## Create agents {% class="hide-from-toc" id="create-agents" %} {% two-column-layout %} {% left-column %} Managed Agents give Gemini a workspace to plan and complete tasks on its own. In a single request, Gemini can write and run code, search the web, and create files in a hosted sandbox environment. Start with our prebuilt Antigravity agent, or customize it with your own instructions and tools. {% button href="/docs/managed-agents-quickstart" variant="ais" %}Agents quickstart{% /button %} {% button href="https://aistudio.google.com/prompts/new_chat?model=antigravity-preview-09-2026" variant="primary" tooltip="Try Managed Agents in AI Studio" %}Try in AI Studio{% /button %} {% /left-column %} {% right-column %} {% tabs %} {% tab label="Python" filename="agent.py" %} ```python from google import genai client = genai.Client() interaction = client.interactions.create( agent="antigravity-preview-09-2026", input=( "Research the top 5 sustainable fashion brands, " "compare their materials and pricing tiers, and " "build an interactive dashboard in analysis.html." ), environment="remote" ) print(interaction.output_text) ``` {% /tab %} {% tab label="JavaScript" filename="agent.js" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ agent: "antigravity-preview-09-2026", input: "Research the top 5 sustainable fashion brands, " + "compare their materials and pricing tiers, and " + "build an interactive dashboard in analysis.html.", environment: "remote", }); console.log(interaction.output_text); ``` {% /tab %} {% tab label="REST" filename="agent.sh" %} ```bash curl -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -d '{ "agent": "antigravity-preview-09-2026", "input": "Research the top 5 sustainable fashion brands, compare their materials and pricing tiers, and build an interactive dashboard in analysis.html.", "environment": "remote" }' ``` {% /tab %} {% tab label="Java" filename="AgentQuickstart.java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.AgentOption; import com.google.genai.gaos.models.interactions.CreateAgentInteraction; import com.google.genai.gaos.models.interactions.CreateAgentInteractionEnvironment; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; Client client = new Client(); CreateAgentInteraction params = CreateAgentInteraction.builder() .agent(AgentOption.of("antigravity-preview-09-2026")) .input( InteractionsInput.of( "Research the top 5 sustainable fashion brands, " + "compare their materials and pricing tiers, and " + "build an interactive dashboard in analysis.html.")) .environment(CreateAgentInteractionEnvironment.of("remote")) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)) .interaction() .get(); System.out.println(interaction.outputText().orElse("")); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateAgentInteraction{ Agent: interactions.AgentOption("antigravity-preview-09-2026"), Input: interactions.NewInteractionsInput( "Research the top 5 sustainable fashion brands, " + "compare their materials and pricing tiers, and " + "build an interactive dashboard in analysis.html.", ), Environment: genai.Ptr(interactions.NewCreateAgentInteractionEnvironment("remote")), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputText != nil { fmt.Println(*res.Interaction.OutputText) } } ``` {% /tab %} {% /tabs %} {% /right-column %} {% /two-column-layout %} ## Interactions API {% class="hide-from-toc" id="interactions-api" %} The **Interactions API** has become our default interface as of June 2026 and is the best way to build with Gemini models and agents going forward. If you're starting a new project, you should use the Interactions API. While it remains supported, the `generateContent` API is now considered legacy. {% card-grid columns="3" %} {% card href="/docs/interactions-overview" title="Interactions Overview" description="Learn how the Interactions API manages conversation state, messages, and output formats." icon="hub" variant="stacked-icon" %} {% /card %} {% card href="/docs/migrate-to-interactions" title="Migration Guide" description="Step-by-step guide to transition your code from generateContent to the Interactions API." icon="swap_horiz" variant="stacked-icon" %} {% /card %} {% card href="/docs/streaming" title="Streaming" description="Stream real-time tokens, incremental thoughts, and tool call events." icon="sensors" variant="stacked-icon" %} {% /card %} {% /card-grid %} # Getting started Source: https://aistudio.google.com/docs/get-started Description: Get started with the Gemini API for Developers using the Interactions API This guide gets you started with the Gemini API using the [Interactions API](/docs/interactions-overview). You'll make your first API call in under a minute and explore text generation, multimodal understanding, image generation, structured output, tools, function calling, agents, and background execution. The Interactions API is available through the [Python](https://github.com/googleapis/python-genai) and [JavaScript](https://github.com/googleapis/js-genai) SDKs, as well as through REST. ## Choose the right Gemini tool {% id="choose-tool" %} Use the [Google GenAI SDKs](/docs/libraries) and [coding agent setup](/docs/coding-agents) when you are **building** Gemini into an application. Use the [Gemini API CLI](/docs/cli) (`gemini-api`) when an agent or script needs to **call** Gemini directly from the shell without adding SDK code to your project: | Tool | What it does | When to use it | | :--- | :--- | :--- | | **[Google GenAI SDKs](/docs/libraries)** | Imports Gemini client libraries into Python, TypeScript, JavaScript, Go, Java, or C# code. | You are building Gemini features into your application, backend service, or real-time [Live API](/docs/live-api) session. | | **[Gemini Docs MCP & skills](/docs/coding-agents)** | Gives coding agents live documentation search and current SDK rules. | Your coding agent is writing application code that imports a Google GenAI SDK. | | **[Gemini API CLI](/docs/cli)** (`gemini-api`) | Calls Gemini models and managed agents from any shell. | Your coding agent, shell script, or CI job needs to generate media, analyze files, or run a background research agent with zero project dependencies. | {% callout type="note" %} `gemini-api` is a stateless API client, not an interactive coding agent like `@google/gemini-cli`. You can run `gemini-api` inside any coding agent. {% /callout %} ## 1. Get an API key {% id="get-api-key" %} To use the Gemini API, you need to have an API key to authenticate your requests, enforce security limits, and track usage to your account. * Google AI Studio automatically creates a project and API key for new users. You can copy it from the [API keys page](https://aistudio.google.com/api-keys). * If you need a new key, click **Create API key** in AI Studio and follow the dialog to add a new key-project pair. {% button href="https://aistudio.google.com/apikey" variant="ais" %}Create a Gemini API Key{% /button %} Set your key as an environment variable: ```bash export GEMINI_API_KEY="YOUR_API_KEY" ``` ### Upgrade to the paid tier {% id="upgrade-paid-tier" %} Upgrading to the paid tier increases your rate limits and requires setting up Cloud Billing. * Click **Set up billing** on the AI Studio [API keys](https://aistudio.google.com/api-keys) or [Projects](https://aistudio.google.com/projects) pages. * Follow the Cloud Billing dialog to create or link a billing account, add a payment method, and prepay a minimum of $5 (or currency equivalent) in paid credits. * View your API usage in [Google AI Studio](https://aistudio.google.com/usage) under **Dashboard** > **Usage**. See the [Billing page](/docs/billing) for more information. ## 2. Install the SDK and make your first call {% id="2-install-the-sdk-and-make-your-first-call" %} Install the SDK and generate text with a single API call. {% tabs %} {% tab label="Python" %} Install the SDK: ```bash pip install -U google-genai ``` Initialize the client and make a request: ```python from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-3.8-flash", input="Explain how AI works in a few words" ) print(interaction.output_text) ``` {% /tab %} {% tab label="JavaScript" %} Install the SDK: ```bash npm install @google/genai ``` Initialize the client and make a request: ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: "gemini-3.8-flash", input: "Explain how AI works in a few words", }); console.log(interaction.output_text); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-3.8-flash")) .input(InteractionsInput.of("Explain how AI works in a few words")) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); System.out.println(interaction.outputText().orElse("")); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.8-flash"), Input: interactions.NewInteractionsInput("Explain how AI works in a few words."), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputText != nil { fmt.Println(*res.Interaction.OutputText) } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-3.8-flash", "input": "Explain how AI works in a few words" }' ``` **Response:** ```json { "id": "v1_ChdpQUFvYXI...", "status": "completed", "usage": { "total_tokens": 197, "total_input_tokens": 8, "total_output_tokens": 12 }, "created": "2026-06-09T12:01:25Z", "steps": [ { "type": "thought", "signature": "EvEFCu4FAQw..." }, { "type": "model_output", "content": [ { "type": "text", "text": "AI learns patterns from data, then uses those patterns to make predictions or decisions on new data." } ] } ], "object": "interaction", "model": "gemini-3.8-flash", } ``` When using REST, the API returns the full `Interaction` resource containing metadata, usage statistics, and the step-by-step history of the turn. {% /tab %} {% /tabs %} While the SDKs expose the full response, they also provide convenience properties like `interaction.output_text` and `interaction.output_image` to access final outputs directly. Learn more about the response structure in the [Interactions overview](/docs/interactions-overview) or read the [text generation guide](/docs/text-generation) for details on system instructions and generation config. {% callout type="info" %} **Building with an AI coding agent?** Install the skill and then paste the prompt to get started with the Gemini API using Interactions: {% /callout %} {% tabs %} {% tab label="Install" %} ```bash npx skills add google-gemini/gemini-skills --skill gemini-api-dev ``` {% /tab %} {% tab label="Prompt" %} ```none Based on what you know about me and my learning style, interactively guide me through the concepts Getting Started for the Gemini API at https://aistudio.google.com/docs/get-started.md using the Interactions API ``` {% /tab %} {% /tabs %} ## 3. Stream the response {% id="3-stream-the-response" %} For more fluid interactions, stream the response as it's generated. Each `step.delta` event delivers a chunk of text you can display immediately. {% tabs %} {% tab label="Python" %} ```python from google import genai client = genai.Client() stream = client.interactions.create( model="gemini-3.8-flash", input="Explain how AI works", stream=True ) for event in stream: print(event) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); const stream = await ai.interactions.create({ model: "gemini-3.8-flash", input: "Explain how AI works", stream: true, }); for await (const event of stream) { console.log(event); } ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.InteractionSSEStreamEvent; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import com.google.genai.gaos.models.operations.CreateInteractionResponse; import com.google.genai.gaos.utils.EventStream; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-3.8-flash")) .input(InteractionsInput.of("Explain how AI works")) .stream(true) .build(); CreateInteractionResponse response = client.interactions.create(CreateInteractionRequestBody.of(params)); try (EventStream stream = response.events()) { for (InteractionSSEStreamEvent event : stream) { System.out.println(event); } } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.8-flash"), Input: interactions.NewInteractionsInput("Write a haiku about coding."), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputText != nil { fmt.Println(*res.Interaction.OutputText) } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions?alt=sse" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ --no-buffer \ -d '{ "model": "gemini-3.8-flash", "input": "Explain how AI works", "stream": true }' ``` When streaming, the server responds with a stream of server-sent events (SSE). Each event includes a type and JSON data. **Response:** ```json event: interaction.created data: {"interaction":{"id":"v1_Chd...","status":"in_progress","model":"gemini-3.8-flash"},"event_type":"interaction.created"} event: step.start data: {"index":0,"step":{"type":"thought"},"event_type":"step.start"} event: step.delta data: {"index":0,"delta":{"signature":"EvEFCu4F...","type":"thought_signature"},"event_type":"step.delta"} event: step.stop data: {"index":0,"event_type":"step.stop"} event: step.start data: {"index":1,"step":{"type":"model_output"},"event_type":"step.start"} event: step.delta data: {"index":1,"delta":{"text":"AI ","type":"text"},"event_type":"step.delta"} event: step.delta data: {"index":1,"delta":{"text":"works ","type":"text"},"event_type":"step.delta"} event: step.stop data: {"index":1,"event_type":"step.stop"} event: interaction.completed data: {"interaction":{"id":"v1_Chd...","status":"completed","usage":{"total_tokens":197}},"event_type":"interaction.completed"} ``` {% /tab %} {% /tabs %} For a detailed look at handling streaming events and delta types, see the [streaming interactions guide](/docs/streaming). ## 4. Multi-turn conversations {% id="4-multi-turn-conversations" %} The Interactions API supports multi-turn conversations with two approaches: * **Stateful (recommended)**: Continue a conversation on the server using `previous_interaction_id`. Ideal for most chat and agentic workflows where you want the server to manage history and optimize caching. * **Stateless**: Manage the conversation history on the client by passing all previous turns (including intermediate model thought and tool steps) in each request. {% tabs %} {% tab title="Stateful (recommended)" %} Chain interactions by passing `previous_interaction_id`. The server manages the full conversation history for you. {% tabs %} {% tab label="Python" %} ```python from google import genai client = genai.Client() # Server-side state (recommended) interaction1 = client.interactions.create( model="gemini-3.8-flash", input="I have 2 dogs in my house.", ) print("Response 1:", interaction1.output_text) interaction2 = client.interactions.create( model="gemini-3.8-flash", input="How many paws are in my house?", previous_interaction_id=interaction1.id, ) print("Response 2:", interaction2.output_text) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); // Server-side state (recommended) const interaction1 = await ai.interactions.create({ model: "gemini-3.8-flash", input: "I have 2 dogs in my house.", }); console.log("Response 1:", interaction1.output_text); const interaction2 = await ai.interactions.create({ model: "gemini-3.8-flash", input: "How many paws are in my house?", previous_interaction_id: interaction1.id, }); console.log("Response 2:", interaction2.output_text); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; Client client = new Client(); // Server-side state (recommended) CreateModelInteraction params1 = CreateModelInteraction.builder() .model(Model.of("gemini-3.8-flash")) .input(InteractionsInput.of("I have 2 dogs in my house.")) .build(); Interaction interaction1 = client.interactions.create(CreateInteractionRequestBody.of(params1)).interaction().get(); System.out.println("Response 1: " + interaction1.outputText().orElse("")); CreateModelInteraction params2 = CreateModelInteraction.builder() .model(Model.of("gemini-3.8-flash")) .input(InteractionsInput.of("How many paws are in my house?")) .previousInteractionId(interaction1.id().orElse("")) .build(); Interaction interaction2 = client.interactions.create(CreateInteractionRequestBody.of(params2)).interaction().get(); System.out.println("Response 2: " + interaction2.outputText().orElse("")); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.8-flash"), Input: interactions.NewInteractionsInput("Explain quantum computing in simple terms."), Stream: genai.Ptr(true), }), }) if err != nil { log.Fatal(err) } stream := res.InteractionSSEStreamEvent defer stream.Close() for stream.Next() { event := stream.Value() if stepDelta := event.GetDataStepDelta(); stepDelta != nil { if textDelta := stepDelta.GetDeltaText(); textDelta != nil { fmt.Print(textDelta.GetText()) } } } if err := stream.Err(); err != nil { log.Fatal(err) } } ``` {% /tab %} {% tab label="REST" %} ```bash RESPONSE1=$(curl -s -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-3.8-flash", "input": "I have 2 dogs in my house." }') INTERACTION_ID=$(echo "$RESPONSE1" | jq -r '.id') echo "Interaction 1 ID: $INTERACTION_ID" curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-3.8-flash", "input": "How many paws are in my house?", "previous_interaction_id": "'$INTERACTION_ID'" }' ``` {% /tab %} {% /tabs %} {% /tab %} {% tab title="Stateless" %} Set `store=false` and manage conversation history on the client side. You must preserve and resend all model-generated steps (including `thought` and `function_call` steps) exactly as received. {% tabs %} {% tab label="Python" %} ```python from google import genai client = genai.Client() history = [ { "type": "user_input", "content": [{"type": "text", "text": "I have 2 dogs in my house."}] } ] interaction1 = client.interactions.create( model="gemini-3.8-flash", store=False, input=history ) print("Response 1:", interaction1.steps[-1].content[0].text) for step in interaction1.steps: history.append(step.model_dump()) history.append({ "type": "user_input", "content": [{"type": "text", "text": "How many paws are in my house?"}] }) interaction2 = client.interactions.create( model="gemini-3.8-flash", store=False, input=history ) print("Response 2:", interaction2.steps[-1].content[0].text) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); const history = [ { type: "user_input", content: [{ type: "text", text: "I have 2 dogs in my house." }] } ]; const interaction1 = await ai.interactions.create({ model: "gemini-3.8-flash", store: false, input: history }); console.log("Response 1:", interaction1.steps.at(-1).content[0].text); history.push(...interaction1.steps); history.push({ type: "user_input", content: [{ type: "text", text: "How many paws are in my house?" }] }); const interaction2 = await ai.interactions.create({ model: "gemini-3.8-flash", store: false, input: history }); console.log("Response 2:", interaction2.steps.at(-1).content[0].text); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.Step; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.interactions.UserInputStep; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.util.ArrayList; import java.util.Arrays; import java.util.List; Client client = new Client(); List history = new ArrayList<>(); history.add( UserInputStep.builder() .content(Arrays.asList(TextContent.builder().text("I have 2 dogs in my house.").build())) .build()); CreateModelInteraction params1 = CreateModelInteraction.builder() .model(Model.of("gemini-3.8-flash")) .store(false) .input(InteractionsInput.ofStep(history)) .build(); Interaction interaction1 = client.interactions.create(CreateInteractionRequestBody.of(params1)).interaction().get(); System.out.println("Response 1: " + interaction1.outputText().orElse("")); interaction1.steps().ifPresent(history::addAll); history.add( UserInputStep.builder() .content(Arrays.asList(TextContent.builder().text("How many paws are in my house?").build())) .build()); CreateModelInteraction params2 = CreateModelInteraction.builder() .model(Model.of("gemini-3.8-flash")) .store(false) .input(InteractionsInput.ofStep(history)) .build(); Interaction interaction2 = client.interactions.create(CreateInteractionRequestBody.of(params2)).interaction().get(); System.out.println("Response 2: " + interaction2.outputText().orElse("")); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } // 1. First turn res1, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.8-flash"), Input: interactions.NewInteractionsInput("Hi, my name is Alex."), }), }) if err != nil { log.Fatal(err) } if res1.Interaction.OutputText != nil { fmt.Println(*res1.Interaction.OutputText) } // 2. Second turn (passing PreviousInteractionID) res2, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.8-flash"), Input: interactions.NewInteractionsInput("What's my name?"), PreviousInteractionID: res1.Interaction.ID, }), }) if err != nil { log.Fatal(err) } if res2.Interaction.OutputText != nil { fmt.Println(*res2.Interaction.OutputText) } } ``` {% /tab %} {% tab label="REST" %} ```bash # Turn 1: Send with store: false RESPONSE1=$(curl -s -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-3.8-flash", "store": false, "input": [ { "type": "user_input", "content": "I have 2 dogs in my house." } ] }') MODEL_STEPS=$(echo "$RESPONSE1" | jq '.steps') # Turn 2: Build full history HISTORY=$(jq -n \ --argjson first_input '[{"type": "user_input", "content": "I have 2 dogs in my house."}]' \ --argjson model_steps "$MODEL_STEPS" \ --argjson second_input '[{"type": "user_input", "content": "How many paws are in my house?"}]' \ '$first_input + $model_steps + $second_input') curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ -d "{ \"model\": \"gemini-3.8-flash\", \"store\": false, \"input\": $HISTORY }" ``` **Response:** ```json { "id": "v2_Chd...", "status": "completed", "usage": { "total_tokens": 240, "total_input_tokens": 60, "total_output_tokens": 20 }, "steps": [ { "type": "model_output", "content": [ { "type": "text", "text": "There are 8 paws in your house. 2 dogs \u00d7 4 paws = 8 paws." } ] } ], "object": "interaction", "model": "gemini-3.8-flash" } ``` The second interaction returns a complete response object that includes only the new steps, but is grounded in the previous turn's context. Learn more about maintaining state in the [multi-turn conversations guide](/docs/text-generation#multi-turn-conversations), or explore [stateless mode](/docs/text-generation#stateless-conversations) for client-side history management. {% /tab %} {% /tabs %} {% /tab %} {% /tabs %} ## 5. Multimodal understanding {% id="5-multimodal-understanding" %} Gemini models understand images, audio, video, and documents natively. Pass media alongside text in a single request. {% tabs %} {% tab label="Python" %} ```python import base64 from google import genai client = genai.Client() # Load a local image with open("sample.jpg", "rb") as f: image_bytes = f.read() image_b64 = base64.b64encode(image_bytes).decode("utf-8") interaction = client.interactions.create( model="gemini-3.8-flash", input=[ {"type": "text", "text": "Compare this local image and this remote audio file."}, { "type": "image", "data": image_b64, "mime_type": "image/jpeg" }, { "type": "audio", "uri": "https://storage.googleapis.com/generativeai-downloads/data/sample.mp3", "mime_type": "audio/mp3" } ] ) print(interaction.output_text) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import fs from "fs"; import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); // Load a local image const imageBytes = fs.readFileSync("sample.jpg"); const imageB64 = imageBytes.toString("base64"); const interaction = await ai.interactions.create({ model: "gemini-3.8-flash", input: [ { type: "text", text: "Compare this local image and this remote audio file." }, { type: "image", data: imageB64, mime_type: "image/jpeg" }, { type: "audio", uri: "https://storage.googleapis.com/generativeai-downloads/data/sample.mp3", mime_type: "audio/mp3" } ], }); console.log(interaction.output_text); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.AudioContent; import com.google.genai.gaos.models.interactions.AudioContentMimeType; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.ImageContentMimeType; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; import java.util.Base64; Client client = new Client(); // Load a local image byte[] imageBytes = Files.readAllBytes(Path.of("sample.jpg")); String imageB64 = Base64.getEncoder().encodeToString(imageBytes); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-3.8-flash")) .input( InteractionsInput.ofContent( Arrays.asList( TextContent.builder() .text("Compare this local image and this remote audio file.") .build(), ImageContent.builder() .data(imageB64) .mimeType(ImageContentMimeType.IMAGE_JPEG) .build(), AudioContent.builder() .uri("https://storage.googleapis.com/generativeai-downloads/data/sample.mp3") .mimeType(AudioContentMimeType.AUDIO_MP3) .build()))) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); System.out.println(interaction.outputText().orElse("")); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "fmt" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } imageBytes, err := os.ReadFile("path/to/organ.jpg") if err != nil { log.Fatal(err) } base64Image := base64.StdEncoding.EncodeToString(imageBytes) res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.8-flash"), Input: interactions.NewInteractionsInput([]interactions.Content{ interactions.NewContent(interactions.TextContent{ Text: "What is in this image?", }), interactions.NewContent(interactions.ImageContent{ Data: genai.Ptr(base64Image), MimeType: interactions.ImageContentMimeTypeImageJpeg.ToPointer(), }), }), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputText != nil { fmt.Println(*res.Interaction.OutputText) } } ``` {% /tab %} {% tab label="REST" %} ```bash # Base64-encode local image BASE64_IMAGE=$(base64 -w 0 sample.jpg) curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-3.8-flash", "input": [ { "type": "text", "text": "Compare this local image and this remote audio file." }, { "type": "image", "data": "'$BASE64_IMAGE'", "mime_type": "image/jpeg" }, { "type": "audio", "uri": "https://storage.googleapis.com/generativeai-downloads/data/sample.mp3", "mime_type": "audio/mp3" } ] }' ``` **Response:** ```json { "id": "v1_Chd...", "status": "completed", "usage": { "total_tokens": 300 }, "steps": [ { "type": "model_output", "content": [ { "type": "text", "text": "The local image displays a pipe organ while the remote audio file is a sample MP3 clip..." } ] } ], "object": "interaction", "model": "gemini-3.8-flash", } ``` {% /tab %} {% /tabs %} Explore how to pass images, video, and audio files in the [image understanding guide](/docs/image-understanding). {% card-grid %} {% card href="/docs/audio" title="Audio understanding" description="Transcribe, summarize, or answer questions about audio files." icon="hearing" %}{% /card %} {% card href="/docs/video-understanding" title="Video understanding" description="Analyze video content, locate events, and describe actions." icon="videocam" %}{% /card %} {% card href="/docs/document-processing" title="Document processing" description="Extract information from PDFs and other document formats." icon="description" %}{% /card %} {% /card-grid %} ## 6. Multimodal generation {% id="6-multimodal-generation" %} Gemini can generate images natively using the [Nano Banana](/docs/image-generation) image models. {% tabs %} {% tab label="Python" %} ```python import base64 from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-3.1-flash-image", input="Generate an image of a futuristic city skyline at sunset", ) with open("generated_image.png", "wb") as f: f.write(base64.b64decode(interaction.output_image.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: "gemini-3.1-flash-image", input: "Generate an image of a futuristic city skyline at sunset", }); const generatedImage = interaction.output_image; if (generatedImage && generatedImage.data) { const buffer = Buffer.from(generatedImage.data, "base64"); fs.writeFileSync("generated_image.png", buffer); } ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Path; import java.util.Base64; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-3.1-flash-image")) .input(InteractionsInput.of("Generate an image of a futuristic city skyline at sunset")) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.outputImage().isPresent()) { ImageContent generatedImage = interaction.outputImage().get(); if (generatedImage.data().isPresent()) { byte[] imageBytes = Base64.getDecoder().decode(generatedImage.data().get()); Files.write(Path.of("generated_image.png"), imageBytes); } } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } weatherTool := interactions.NewTool(interactions.Function{ Name: genai.Ptr("get_current_weather"), Description: genai.Ptr("Gets the current weather for a given location."), Parameters: map[string]any{ "type": "object", "properties": map[string]any{ "location": map[string]any{ "type": "string", "description": "The city and state, e.g. San Francisco, CA", }, }, "required": []string{"location"}, }, }) // 1. Send prompt with tool declaration res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.8-flash"), Input: interactions.NewInteractionsInput("What is the weather like in Boston?"), Tools: []interactions.Tool{weatherTool}, }), }) if err != nil { log.Fatal(err) } // 2. Check if the model requested a function call for _, step := range res.Interaction.Steps { if call := step.FunctionCallStep; call != nil { fmt.Printf("Function to call: %s\n", call.Name) fmt.Printf("Arguments: %v\n", call.Arguments) // 3. Execute your local function and send the result back finalRes, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.8-flash"), PreviousInteractionID: res.Interaction.ID, Input: interactions.NewInteractionsInput([]interactions.Step{ interactions.NewStep(interactions.FunctionResultStep{ Name: genai.Ptr(call.Name), CallID: call.ID, Result: interactions.NewFunctionResultStepResultUnion(`{"temperature": "72F", "condition": "Sunny"}`), }), }), }), }) if err != nil { log.Fatal(err) } if finalRes.Interaction.OutputText != nil { fmt.Println(*finalRes.Interaction.OutputText) } } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -s -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-3.1-flash-image", "input": [ {"type": "text", "text": "Generate an image of a futuristic city skyline at sunset"} ] }' ``` **Response:** ```json { "id": "v1_Chd...", "status": "completed", "steps": [ { "type": "model_output", "content": [ { "type": "image", "data": "BASE64_ENCODED_IMAGE", "mime_type": "image/png" } ] } ], "object": "interaction", "model": "gemini-3.1-flash-image", } ``` {% /tab %} {% /tabs %} When the model generates an image, it returns the base64-encoded image data in a step within the `steps` array, as well as via the `output_image` convenience property. Check out the [image generation guide](/docs/image-generation) to learn about aspect ratios, image editing, and references. {% card-grid %} {% card href="/docs/speech-generation" title="Speech generation" description="Generate expressive, multi-speaker speech with Gemini 3.1 Flash TTS." icon="record_voice_over" %}{% /card %} {% card href="/docs/music-generation" title="Music generation" description="Create clips and full-length songs with Lyria 3.5." icon="music_note" %}{% /card %} {% /card-grid %} ## 7. Use structured output {% id="7-use-structured-output" %} Configure the model to return JSON that matches a schema you define. Structured output works with [Pydantic](https://docs.pydantic.dev/latest/) (Python) and [Zod](https://zod.dev/) (JavaScript). {% tabs %} {% tab label="Python" %} ```python from google import genai from pydantic import BaseModel, Field from typing import List, Optional class Recipe(BaseModel): recipe_name: str = Field(description="Name of the recipe.") ingredients: List[str] = Field(description="List of ingredients.") prep_time_minutes: Optional[int] = Field(description="Prep time in minutes.") client = genai.Client() interaction = client.interactions.create( model="gemini-3.8-flash", input="Give me a recipe for banana bread", response_format={ "type": "text", "mime_type": "application/json", "schema": Recipe.model_json_schema() }, ) recipe = Recipe.model_validate_json(interaction.output_text) print(recipe) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as z from "zod"; const ai = new GoogleGenAI({}); const recipeJsonSchema = { type: "object", properties: { recipe_name: { type: "string", description: "Name of the recipe." }, ingredients: { type: "array", items: { type: "string" }, description: "List of ingredients." }, prep_time_minutes: { type: "integer", description: "Prep time in minutes." } }, required: ["recipe_name", "ingredients"] }; const recipeSchema = z.fromJSONSchema(recipeJsonSchema); const interaction = await ai.interactions.create({ model: "gemini-3.8-flash", input: "Give me a recipe for banana bread", response_format: { type: "text", mime_type: "application/json", schema: recipeJsonSchema }, }); const recipe = recipeSchema.parse(JSON.parse(interaction.output_text)); console.log(recipe); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.CreateModelInteractionResponseFormat; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ResponseFormat; import com.google.genai.gaos.models.interactions.TextResponseFormat; import com.google.genai.gaos.models.interactions.TextResponseFormatMimeType; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.util.Arrays; import java.util.HashMap; import java.util.Map; Client client = new Client(); Map recipeNameProp = new HashMap<>(); recipeNameProp.put("type", "string"); recipeNameProp.put("description", "Name of the recipe."); Map itemsProp = new HashMap<>(); itemsProp.put("type", "string"); Map ingredientsProp = new HashMap<>(); ingredientsProp.put("type", "array"); ingredientsProp.put("items", itemsProp); ingredientsProp.put("description", "List of ingredients."); Map prepTimeProp = new HashMap<>(); prepTimeProp.put("type", "integer"); prepTimeProp.put("description", "Prep time in minutes."); Map properties = new HashMap<>(); properties.put("recipe_name", recipeNameProp); properties.put("ingredients", ingredientsProp); properties.put("prep_time_minutes", prepTimeProp); Map recipeJsonSchema = new HashMap<>(); recipeJsonSchema.put("type", "object"); recipeJsonSchema.put("properties", properties); recipeJsonSchema.put("required", Arrays.asList("recipe_name", "ingredients")); CreateModelInteractionResponseFormat format = CreateModelInteractionResponseFormat.of( ResponseFormat.of( TextResponseFormat.builder() .mimeType(TextResponseFormatMimeType.APPLICATION_JSON) .schema(recipeJsonSchema) .build())); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-3.8-flash")) .input(InteractionsInput.of("Give me a recipe for banana bread")) .responseFormat(format) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); System.out.println(interaction.outputText().orElse("")); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.8-flash"), Input: interactions.NewInteractionsInput("Who won the latest Super Bowl and what was the score?"), Tools: []interactions.Tool{ interactions.NewTool(interactions.GoogleSearch{}), }, }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputText != nil { fmt.Println(*res.Interaction.OutputText) } // Optional: Inspect search queries and citations for _, step := range res.Interaction.Steps { if searchCall := step.GoogleSearchCallStep; searchCall != nil { fmt.Printf("Search queries: %v\n", searchCall.Arguments.Queries) } else if modelOut := step.ModelOutputStep; modelOut != nil { for _, part := range modelOut.Content { if textPart := part.TextContent; textPart != nil { for _, annotation := range textPart.Annotations { if citation := annotation.URLCitation; citation != nil { var title, url string if citation.Title != nil { title = *citation.Title } if citation.URL != nil { url = *citation.URL } fmt.Printf("Source: %s (%s)\n", title, url) } } } } } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-3.8-flash", "input": "Give me a recipe for banana bread", "response_format": { "type": "text", "mime_type": "application/json", "schema": { "type": "object", "properties": { "recipe_name": { "type": "string", "description": "Name of the recipe." }, "ingredients": { "type": "array", "items": { "type": "string" }, "description": "List of ingredients." }, "prep_time_minutes": { "type": "integer", "description": "Prep time in minutes." } }, "required": ["recipe_name", "ingredients"] } } }' ``` **Response:** ```json { "id": "v1_Chd...", "status": "completed", "steps": [ { "type": "model_output", "content": [ { "type": "text", "text": "{\n \"recipe_name\": \"Classic Banana Bread\",\n \"ingredients\": [\n \"3 ripe bananas, mashed\",\n \"1/3 cup melted butter\",\n \"3/4 cup sugar\",\n \"1 egg, beaten\",\n \"1 teaspoon vanilla extract\",\n \"1 teaspoon baking soda\",\n \"Pinch of salt\",\n \"1.5 cups all-purpose flour\"\n ],\n \"prep_time_minutes\": 15\n}" } ] } ], "object": "interaction", "model": "gemini-3.8-flash", } ``` {% /tab %} {% /tabs %} The output text block contains a valid JSON string conforming exactly to the requested schema. To learn how to define more complex structures and recursive schemas, see the [structured output guide](/docs/structured-output). ## 8. Use tools {% id="8-use-tools" %} Ground the model's response in real-time information with Google Search. The API automatically searches, processes results, and returns citations. {% tabs %} {% tab label="Python" %} ```python from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-3.8-flash", input="Who won the euro 2024?", tools=[{"type": "google_search"}] ) print(interaction.output_text) # Print citations for step in interaction.steps: if step.type == "model_output": for content_block in step.content: if content_block.type == "text" and content_block.annotations: print("\nCitations:") for annotation in content_block.annotations: if annotation.type == "url_citation": print(f" [{annotation.title}]({annotation.url})") ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: "gemini-3.8-flash", input: "Who won the euro 2024?", tools: [{ type: "google_search" }] }); console.log(interaction.output_text); // Print citations for (const step of interaction.steps) { if (step.type === "model_output") { for (const contentBlock of step.content || []) { if (contentBlock.type === "text" && contentBlock.annotations) { console.log("\nCitations:"); for (const annotation of contentBlock.annotations) { if (annotation.type === "url_citation") { console.log(` [${annotation.title}](${annotation.url})`); } } } } } } ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Annotation; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.GoogleSearch; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ModelOutputStep; import com.google.genai.gaos.models.interactions.Step; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.interactions.URLCitation; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.util.Arrays; import java.util.Collections; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-3.8-flash")) .input(InteractionsInput.of("Who won the euro 2024?")) .tools(Arrays.asList(new GoogleSearch())) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); System.out.println(interaction.outputText().orElse("")); // Print citations for (Step step : interaction.steps().orElse(Collections.emptyList())) { if (step instanceof ModelOutputStep outputStep) { for (Content contentBlock : outputStep.content().orElse(Collections.emptyList())) { if (contentBlock instanceof TextContent textContent && textContent.annotations().isPresent()) { System.out.println("\nCitations:"); for (Annotation annotation : textContent.annotations().get()) { if (annotation instanceof URLCitation citation) { System.out.printf(" [%s](%s)%n", citation.title().orElse(""), citation.url().orElse("")); } } } } } } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.8-flash"), Input: interactions.NewInteractionsInput("Calculate the 20th Fibonacci number and verify if it is prime."), Tools: []interactions.Tool{ interactions.NewTool(interactions.CodeExecution{}), }, }), }) if err != nil { log.Fatal(err) } for _, step := range res.Interaction.Steps { if codeCall := step.CodeExecutionCallStep; codeCall != nil { fmt.Printf("Generated Code:\n%s\n", codeCall.Arguments.Code) } else if codeRes := step.CodeExecutionResultStep; codeRes != nil { fmt.Printf("Execution Output:\n%s\n", codeRes.Result) } } if res.Interaction.OutputText != nil { fmt.Println(*res.Interaction.OutputText) } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-3.8-flash", "input": "Who won the euro 2024?", "tools": [{"type": "google_search"}] }' ``` **Response:** ```json { "id": "v1_Chd...", "status": "completed", "steps": [ { "type": "thought", "signature": "EvEFCu4F..." }, { "type": "google_search_call", "arguments": { "queries": ["UEFA Euro 2024 winner"] } }, { "type": "google_search_result", "call_id": "search_001", "result": [ { "search_suggestions": "" } ] }, { "type": "model_output", "content": [ { "type": "text", "text": "Spain won Euro 2024, defeating England 2-1 in the final.", "annotations": [ { "type": "url_citation", "url": "https://www.uefa.com/euro2024", "title": "uefa.com", "start_index": 0, "end_index": 56 } ] } ] } ], "object": "interaction", "model": "gemini-3.8-flash", } ``` {% /tab %} {% /tabs %} The search steps are detailed within the interaction history, and the final output includes inline citations pointing to web sources. You can learn how to extract search citations in the [Google Search grounding guide](/docs/google-search), or see how to combine multiple tools in the [tool combination guide](/docs/tool-combination). {% card-grid %} {% card href="/docs/code-execution" title="Code execution" description="Run Python code in a secure sandboxed Borg environment." icon="code" %}{% /card %} {% card href="/docs/url-context" title="URL context" description="Pass public web URLs directly to ground responses in webpage content." icon="link" %}{% /card %} {% card href="/docs/file-search" title="File search" description="Index and search across uploaded documents and media files." icon="search" %}{% /card %} {% card href="/docs/maps-grounding" title="Google Maps" description="Ground responses in real-world geospatial and location data." icon="map" %}{% /card %} {% card href="/docs/computer-use" title="Computer use" description="Browser automation and screen interaction." icon="computer" %}{% /card %} {% /card-grid %} ## 9. Call your own functions {% id="9-call-your-own-functions" %} Function calling lets you connect the model to your code. You declare a function's name and parameters, the model decides when to call it and returns structured arguments, and you execute it locally and send the result back. {% tabs %} {% tab title="Stateful (recommended)" %} {% tabs %} {% tab label="Python" %} ```python import json from google import genai client = genai.Client() weather_tool = { "type": "function", "name": "get_current_temperature", "description": "Gets the current temperature for a given location.", "parameters": { "type": "object", "properties": { "location": { "type": "string", "description": "The city name, e.g. San Francisco", }, }, "required": ["location"], }, } available_functions = { "get_current_temperature": lambda location: { "location": location, "temperature": "22", "unit": "celsius" }, } user_input = "What is the temperature in London?" previous_id = None while True: interaction = client.interactions.create( model="gemini-3.8-flash", input=user_input, tools=[weather_tool], previous_interaction_id=previous_id, ) function_results = [] for step in interaction.steps: if step.type == "function_call": result = available_functions[step.name](**step.arguments) print(f"Called {step.name}({step.arguments}) → {result}") function_results.append({ "type": "function_result", "name": step.name, "call_id": step.id, "result": [{"type": "text", "text": json.dumps(result)}], }) if not function_results: break user_input = function_results previous_id = interaction.id print(interaction.output_text) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); const weatherTool = { type: "function", name: "get_current_temperature", description: "Gets the current temperature for a given location.", parameters: { type: "object", properties: { location: { type: "string", description: "The city name, e.g. San Francisco", }, }, required: ["location"], }, }; const availableFunctions = { get_current_temperature: ({ location }) => ({ location, temperature: "22", unit: "celsius" }), }; let input = "What is the temperature in London?"; let previousId = null; let interaction; while (true) { interaction = await ai.interactions.create({ model: "gemini-3.8-flash", input, tools: [weatherTool], previous_interaction_id: previousId, }); const functionResults = []; for (const step of interaction.steps) { if (step.type === "function_call") { const result = availableFunctions[step.name](step.arguments); console.log(`Called ${step.name}(${JSON.stringify(step.arguments)}) →`, result); functionResults.push({ type: "function_result", name: step.name, call_id: step.id, result: [{ type: "text", text: JSON.stringify(result) }], }); } } if (functionResults.length === 0) break; input = functionResults; previousId = interaction.id; } console.log(interaction.output_text); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Function; import com.google.genai.gaos.models.interactions.FunctionCallStep; import com.google.genai.gaos.models.interactions.FunctionResultStep; import com.google.genai.gaos.models.interactions.FunctionResultStepResultUnion; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.Step; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; Client client = new Client(); Map locationProp = new HashMap<>(); locationProp.put("type", "string"); locationProp.put("description", "The city name, e.g. San Francisco"); Map properties = new HashMap<>(); properties.put("location", locationProp); Map parameters = new HashMap<>(); parameters.put("type", "object"); parameters.put("properties", properties); parameters.put("required", Arrays.asList("location")); Function weatherTool = Function.builder() .name("get_current_temperature") .description("Gets the current temperature for a given location.") .parameters(parameters) .build(); InteractionsInput userInput = InteractionsInput.of("What is the temperature in London?"); String previousId = null; Interaction interaction = null; while (true) { CreateModelInteraction.Builder paramsBuilder = CreateModelInteraction.builder() .model(Model.of("gemini-3.8-flash")) .input(userInput) .tools(Arrays.asList(weatherTool)); if (previousId != null) { paramsBuilder.previousInteractionId(previousId); } interaction = client.interactions.create(CreateInteractionRequestBody.of(paramsBuilder.build())).interaction().get(); List functionResults = new ArrayList<>(); for (Step step : interaction.steps().orElse(Collections.emptyList())) { if (step instanceof FunctionCallStep fcStep) { String resultJson = "{\"location\": \"London\", \"temperature\": \"22\", \"unit\": \"celsius\"}"; System.out.printf( "Called %s(%s) -> %s%n", fcStep.name().orElse(""), fcStep.arguments().orElse(Collections.emptyMap()), resultJson); functionResults.add( FunctionResultStep.builder() .name(fcStep.name().orElse("")) .callId(fcStep.id().orElse("")) .result( FunctionResultStepResultUnion.of( Arrays.asList(TextContent.builder().text(resultJson).build()))) .build()); } } if (functionResults.isEmpty()) { break; } userInput = InteractionsInput.ofStep(functionResults); previousId = interaction.id().orElse(null); } System.out.println(interaction.outputText().orElse("")); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } // Turn 1: Create a CSV file in the sandbox turn1, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.8-flash"), Input: interactions.NewInteractionsInput("Write a Python script to save a CSV file 'sales.csv' with 5 rows of sample data."), Tools: []interactions.Tool{ interactions.NewTool(interactions.CodeExecution{}), }, }), }) if err != nil { log.Fatal(err) } var env *interactions.CreateModelInteractionEnvironment if turn1.Interaction.EnvironmentID != nil { env = genai.Ptr(interactions.NewCreateModelInteractionEnvironment(*turn1.Interaction.EnvironmentID)) } // Turn 2: Reuse the sandbox environment to analyze the file created in Turn 1 turn2, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.8-flash"), PreviousInteractionID: turn1.Interaction.ID, Environment: env, Input: interactions.NewInteractionsInput("Now read 'sales.csv' and compute the total revenue."), Tools: []interactions.Tool{ interactions.NewTool(interactions.CodeExecution{}), }, }), }) if err != nil { log.Fatal(err) } if turn2.Interaction.OutputText != nil { fmt.Println(*turn2.Interaction.OutputText) } } ``` {% /tab %} {% tab label="REST" %} ```bash # Turn 1: Send prompt with function declaration RESPONSE1=$(curl -s -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-3.8-flash", "input": "What is the temperature in London?", "tools": [{ "type": "function", "name": "get_current_temperature", "description": "Gets the current temperature for a given location.", "parameters": { "type": "object", "properties": { "location": {"type": "string", "description": "The city name"} }, "required": ["location"] } }] }') INTERACTION_ID=$(echo "$RESPONSE1" | jq -r '.id') FC_NAME=$(echo "$RESPONSE1" | jq -r '.steps[] | select(.type=="function_call") | .name') FC_ID=$(echo "$RESPONSE1" | jq -r '.steps[] | select(.type=="function_call") | .id') echo "Function: $FC_NAME, Call ID: $FC_ID" # Turn 2: Send function result back curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-3.8-flash", "previous_interaction_id": "'$INTERACTION_ID'", "input": [{ "type": "function_result", "name": "'$FC_NAME'", "call_id": "'$FC_ID'", "result": [{"type": "text", "text": "{\"location\": \"London\", \"temperature\": \"22\", \"unit\": \"celsius\"}"}] }], "tools": [{ "type": "function", "name": "get_current_temperature", "description": "Gets the current temperature for a given location.", "parameters": { "type": "object", "properties": { "location": {"type": "string", "description": "The city name"} }, "required": ["location"] } }] }' ``` {% /tab %} {% /tabs %} {% /tab %} {% tab title="Stateless" %} You can also use function calling in stateless mode by managing the conversation history on the client side and setting `store=false`. In stateless mode, you must pass the full history of the conversation in the `input` field of each subsequent request. This history must include: 1. The initial `user_input` step. 2. All model-generated steps returned in Turn 1 (including `thought` and `function_call` steps) exactly as received. 3. The `function_result` step containing the output of your executed function. {% tabs %} {% tab label="Python" %} ```python import json from google import genai client = genai.Client() weather_tool = { "type": "function", "name": "get_current_temperature", "description": "Gets the current temperature for a given location.", "parameters": { "type": "object", "properties": { "location": { "type": "string", "description": "The city name, e.g. San Francisco", }, }, "required": ["location"], }, } available_functions = { "get_current_temperature": lambda location: { "location": location, "temperature": "22", "unit": "celsius" }, } history = [ { "type": "user_input", "content": [{"type": "text", "text": "What is the temperature in London?"}] } ] while True: interaction = client.interactions.create( model="gemini-3.8-flash", store=False, input=history, tools=[weather_tool], ) function_results = [] for step in interaction.steps: history.append(step.model_dump()) if step.type == "function_call": result = available_functions[step.name](**step.arguments) print(f"Called {step.name}({step.arguments}) → {result}") fn_result = { "type": "function_result", "name": step.name, "call_id": step.id, "result": [{"type": "text", "text": json.dumps(result)}], } function_results.append(fn_result) history.append(fn_result) if not function_results: break print(interaction.output_text) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); const weatherTool = { type: "function", name: "get_current_temperature", description: "Gets the current temperature for a given location.", parameters: { type: "object", properties: { location: { type: "string", description: "The city name, e.g. San Francisco", }, }, required: ["location"], }, }; const availableFunctions = { get_current_temperature: ({ location }) => ({ location, temperature: "22", unit: "celsius" }), }; const history = [ { type: "user_input", content: [{ type: "text", text: "What is the temperature in London?" }] } ]; let interaction; while (true) { interaction = await ai.interactions.create({ model: "gemini-3.8-flash", store: false, input: history, tools: [weatherTool], }); const functionResults = []; for (const step of interaction.steps) { history.push(step); if (step.type === "function_call") { const result = availableFunctions[step.name](step.arguments); console.log(`Called ${step.name}(${JSON.stringify(step.arguments)}) →`, result); const fnResult = { type: "function_result", name: step.name, call_id: step.id, result: [{ type: "text", text: JSON.stringify(result) }], }; functionResults.push(fnResult); history.push(fnResult); } } if (functionResults.length === 0) break; } console.log(interaction.output_text); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Function; import com.google.genai.gaos.models.interactions.FunctionCallStep; import com.google.genai.gaos.models.interactions.FunctionResultStep; import com.google.genai.gaos.models.interactions.FunctionResultStepResultUnion; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.Step; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.interactions.UserInputStep; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; Client client = new Client(); Map locationProp = new HashMap<>(); locationProp.put("type", "string"); locationProp.put("description", "The city name, e.g. San Francisco"); Map properties = new HashMap<>(); properties.put("location", locationProp); Map parameters = new HashMap<>(); parameters.put("type", "object"); parameters.put("properties", properties); parameters.put("required", Arrays.asList("location")); Function weatherTool = Function.builder() .name("get_current_temperature") .description("Gets the current temperature for a given location.") .parameters(parameters) .build(); List history = new ArrayList<>(); history.add( UserInputStep.builder() .content(Arrays.asList(TextContent.builder().text("What is the temperature in London?").build())) .build()); Interaction interaction = null; while (true) { CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-3.8-flash")) .store(false) .input(InteractionsInput.ofStep(history)) .tools(Arrays.asList(weatherTool)) .build(); interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); List functionResults = new ArrayList<>(); for (Step step : interaction.steps().orElse(Collections.emptyList())) { history.add(step); if (step instanceof FunctionCallStep fcStep) { String resultJson = "{\"location\": \"London\", \"temperature\": \"22\", \"unit\": \"celsius\"}"; System.out.printf( "Called %s(%s) -> %s%n", fcStep.name().orElse(""), fcStep.arguments().orElse(Collections.emptyMap()), resultJson); FunctionResultStep fnResult = FunctionResultStep.builder() .name(fcStep.name().orElse("")) .callId(fcStep.id().orElse("")) .result( FunctionResultStepResultUnion.of( Arrays.asList(TextContent.builder().text(resultJson).build()))) .build(); functionResults.add(fnResult); history.add(fnResult); } } if (functionResults.isEmpty()) { break; } } System.out.println(interaction.outputText().orElse("")); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } recipeSchema := map[string]any{ "type": "object", "properties": map[string]any{ "recipe_name": map[string]any{"type": "string"}, "prep_time_minutes": map[string]any{"type": "integer"}, "ingredients": map[string]any{ "type": "array", "items": map[string]any{"type": "string"}, }, }, "required": []string{"recipe_name", "prep_time_minutes", "ingredients"}, } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.8-flash"), Input: interactions.NewInteractionsInput("Give me a quick recipe for chocolate chip cookies."), ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat( interactions.NewResponseFormat(interactions.TextResponseFormat{ MimeType: interactions.TextResponseFormatMimeTypeApplicationJSON.ToPointer(), Schema: recipeSchema, }), )), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputText != nil { fmt.Println(*res.Interaction.OutputText) } } ``` {% /tab %} {% tab label="REST" %} ```bash # Turn 1: Send request with tools and store: false RESPONSE1=$(curl -s -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-3.8-flash", "store": false, "input": [ { "type": "user_input", "content": "What is the temperature in London?" } ], "tools": [{ "type": "function", "name": "get_current_temperature", "description": "Gets the current temperature for a given location.", "parameters": { "type": "object", "properties": { "location": {"type": "string", "description": "The city name"} }, "required": ["location"] } }] }') # Extract model steps (thought, function_call) MODEL_STEPS=$(echo "$RESPONSE1" | jq '.steps') FC_NAME=$(echo "$RESPONSE1" | jq -r '.steps[] | select(.type=="function_call") | .name') FC_ID=$(echo "$RESPONSE1" | jq -r '.steps[] | select(.type=="function_call") | .id') echo "Function: $FC_NAME, Call ID: $FC_ID" # Assume local execution returns: RESULT="{\"location\": \"London\", \"temperature\": \"22\", \"unit\": \"celsius\"}" # Reconstruct history for Turn 2 HISTORY=$(jq -n \ --argjson first_input '[{"type": "user_input", "content": "What is the temperature in London?"}]' \ --argjson model_steps "$MODEL_STEPS" \ --arg fc_name "$FC_NAME" \ --arg fc_id "$FC_ID" \ --arg result "$RESULT" \ '$first_input + $model_steps + [{"type": "function_result", "name": $fc_name, "call_id": $fc_id, "result": [{"type": "text", "text": $result}]}]') # Turn 2: Send the full history curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ -d "{ \"model\": \"gemini-3.8-flash\", \"store\": false, \"input\": $HISTORY, \"tools\": [{ \"type\": \"function\", \"name\": \"get_current_temperature\", \"description\": \"Gets the current temperature for a given location.\", \"parameters\": { \"type\": \"object\", \"properties\": { \"location\": {\"type\": \"string\", \"description\": \"The city name\"} }, \"required\": [\"location\"] } }] }" ``` **Response:** During Turn 1, the model returns a response with status `requires_action` and the `function_call` step: ```json { "id": "v1_Chd...", "status": "requires_action", "steps": [ { "type": "function_call", "id": "call_abc123", "name": "get_current_temperature", "arguments": { "location": "London" } } ], "object": "interaction", "model": "gemini-3.8-flash" } ``` After you run the function locally and submit the result (Turn 2), the final completed interaction returns: ```json { "id": "v1_Chd...", "status": "completed", "steps": [ { "type": "function_call", "id": "call_abc123", "name": "get_current_temperature", "arguments": { "location": "London" } }, { "type": "model_output", "content": [ { "type": "text", "text": "The temperature in London is currently 22°C." } ] } ], "object": "interaction", "model": "gemini-3.8-flash", } ``` {% /tab %} {% /tabs %} {% /tab %} {% /tabs %} For advanced features like parallel function calling or function choice modes, see the [function calling guide](/docs/function-calling). ## 10. Run a managed agent {% id="10-run-a-managed-agent" %} Managed agents run in a remote sandbox with access to tools like code execution and file management. Pass an `agent` instead of a `model` and set `environment="remote"`. {% tabs %} {% tab label="Python" %} ```python from google import genai client = genai.Client() interaction = client.interactions.create( agent="antigravity-preview-09-2026", input="Write a Python script that generates the first 20 Fibonacci numbers and saves them to fibonacci.txt. Then read the file and print its contents.", environment="remote", ) print(f"Environment: {interaction.environment_id}") print(interaction.output_text) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ agent: "antigravity-preview-09-2026", input: "Write a Python script that generates the first 20 Fibonacci numbers and saves them to fibonacci.txt. Then read the file and print its contents.", environment: "remote", }); console.log(`Environment: ${interaction.environment_id}`); console.log(interaction.output_text); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateAgentInteraction; import com.google.genai.gaos.models.interactions.CreateAgentInteractionEnvironment; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; Client client = new Client(); CreateAgentInteraction params = CreateAgentInteraction.builder() .agent("antigravity-preview-09-2026") .input( InteractionsInput.of( "Write a Python script that generates the first 20 Fibonacci numbers and saves them to fibonacci.txt. Then read the file and print its contents.")) .environment(CreateAgentInteractionEnvironment.of("remote")) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); System.out.println("Environment: " + interaction.environmentId().orElse("")); System.out.println(interaction.outputText().orElse("")); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.8-pro"), Input: interactions.NewInteractionsInput("Solve this logic puzzle: Three gods A, B, and C are called True, False, and Random..."), GenerationConfig: &interactions.GenerationConfig{ ThinkingLevel: interactions.ThinkingLevelHigh.ToPointer(), ThinkingSummaries: interactions.ThinkingSummariesAuto.ToPointer(), }, }), }) if err != nil { log.Fatal(err) } // Print thought summaries if returned for _, step := range res.Interaction.Steps { if thought := step.ThoughtStep; thought != nil { for _, part := range thought.Summary { if part.TextContent != nil { fmt.Printf("Thought Summary: %s\n", part.TextContent.Text) } } } } if res.Interaction.OutputText != nil { fmt.Printf("Answer: %s\n", *res.Interaction.OutputText) } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ -d '{ "agent": "antigravity-preview-09-2026", "input": "Write a Python script that generates the first 20 Fibonacci numbers and saves them to fibonacci.txt. Then read the file and print its contents.", "environment": "remote" }' ``` {% /tab %} {% /tabs %} You can also define and save [custom agents](/docs/custom-agents) with your own instructions, skills, and data sources. {% card-grid %} {% card href="/docs/managed-agents-quickstart" title="Quickstart" description="Make your first agent call, stream responses, and build a custom agent." icon="rocket_launch" %}{% /card %} {% card href="/docs/antigravity-agent" title="Antigravity Agent" description="Capabilities, tools, multimodal input, and pricing for the default agent." icon="smart_toy" %}{% /card %} {% card href="/docs/aistudio-agents" title="Agents in AI Studio" description="Visual playground for prototyping agents without writing code." icon="experiment" %}{% /card %} {% /card-grid %} ## 11. Run tasks in the background {% id="11-run-tasks-in-the-background" %} Set `background=True` to run long tasks asynchronously. Poll for results with `interactions.get()`. {% tabs %} {% tab label="Python" %} ```python import time from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-3.8-flash", input="Write a detailed analysis of the impact of artificial intelligence on modern healthcare.", background=True, ) print(f"Started background task: {interaction.id}") print(f"Status: {interaction.status}") # Poll for completion while True: result = client.interactions.get(interaction.id) print(f"Status: {result.status}") if result.status == "completed": print(f"\nResult:\n{result.output_text}") break elif result.status == "failed": print(f"Failed: {result.error}") break time.sleep(5) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: "gemini-3.8-flash", input: "Write a detailed analysis of the impact of artificial intelligence on modern healthcare.", background: true, }); console.log(`Started background task: ${interaction.id}`); console.log(`Status: ${interaction.status}`); // Poll for completion while (true) { const result = await ai.interactions.get(interaction.id); console.log(`Status: ${result.status}`); if (result.status === "completed") { console.log(`\nResult:\n${result.output_text}`); break; } else if (result.status === "failed") { console.log(`Failed: ${JSON.stringify(result.errors)}`); break; } await new Promise(r => setTimeout(r, 5000)); } ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionStatus; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import com.google.genai.gaos.models.operations.GetInteractionByIdRequest; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-3.8-flash")) .input( InteractionsInput.of( "Write a detailed analysis of the impact of artificial intelligence on modern healthcare.")) .background(true) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); String interactionId = interaction.id().orElse(""); System.out.println("Started background task: " + interactionId); System.out.println("Status: " + interaction.status().map(InteractionStatus::value).orElse("")); // Poll for completion while (true) { Interaction result = client.interactions.get(new GetInteractionByIdRequest(interactionId)).interaction().get(); String status = result.status().map(InteractionStatus::value).orElse(""); System.out.println("Status: " + status); if ("completed".equals(status)) { System.out.println("\nResult:\n" + result.outputText().orElse("")); break; } else if ("failed".equals(status)) { System.out.println("Failed: " + result.errors().orElse(null)); break; } Thread.sleep(5000); } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "time" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } // Start a Deep Research agent in the background res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateAgentInteraction{ Agent: interactions.AgentOption("deep-research-preview-04-2026"), Input: interactions.NewInteractionsInput("Research the competitive landscape of solid-state EV batteries in 2026."), Background: genai.Ptr(true), }), }) if err != nil { log.Fatal(err) } interaction := res.Interaction fmt.Printf("Started research job: %s\n", *interaction.ID) // Poll until completion for interaction.Status != interactions.InteractionStatusCompleted && interaction.Status != interactions.InteractionStatusFailed { time.Sleep(10 * time.Second) getRes, err := client.Interactions.Get(ctx, operations.GetInteractionByIDRequest{ ID: *interaction.ID, }) if err != nil { log.Fatal(err) } interaction = getRes.Interaction fmt.Printf("Current status: %s\n", interaction.Status) } if interaction.Status == interactions.InteractionStatusCompleted { if interaction.OutputText != nil { fmt.Println(*interaction.OutputText) } } else { fmt.Printf("Research failed: %v\n", interaction.Errors) } } ``` {% /tab %} {% tab label="REST" %} ```bash # Start a background task RESPONSE=$(curl -s -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-3.8-flash", "input": "Write a detailed analysis of the impact of artificial intelligence on modern healthcare.", "background": true }') INTERACTION_ID=$(echo "$RESPONSE" | jq -r '.id') echo "Started background task: $INTERACTION_ID" # Poll for completion while true; do RESULT=$(curl -s "https://generativelanguage.googleapis.com/v1beta/interactions/$INTERACTION_ID" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Api-Revision: 2026-05-20") STATUS=$(echo "$RESULT" | jq -r '.status') echo "Status: $STATUS" if [ "$STATUS" = "completed" ]; then echo "$RESULT" | jq -r '.steps[] | select(.type=="model_output") | .content[] | select(.type=="text") | .text' break elif [ "$STATUS" = "failed" ]; then echo "Failed" break fi sleep 5 done ``` **Response:** The initial response returns immediately with status `in_progress`: ```json { "id": "v1_abc123", "status": "in_progress", "object": "interaction", "model": "gemini-3.8-flash" } ``` Once the background task is fully executed, checking the interaction state returns: ```json { "id": "v1_abc123", "status": "completed", "steps": [ { "type": "model_output", "content": [ { "type": "text", "text": "Artificial intelligence has transformed modern healthcare in several..." } ] } ], "object": "interaction", "model": "gemini-3.8-flash", } ``` {% /tab %} {% /tabs %} Read about running models and agents asynchronously in the [background execution guide](/docs/background-execution). ## What's next {% id="whats-next" %} - [Text generation](/docs/text-generation): System instructions, generation config, and advanced text patterns. - [Image generation](/docs/image-generation): Aspect ratios, image editing, and style references. - [Image understanding](/docs/image-understanding): Classification, object detection, and visual Q&A. - [Thinking](/docs/thinking): Use chain-of-thought reasoning for complex tasks. - [Function calling](/docs/function-calling): Parallel, compositional, and constrained function modes. - [Google Search](/docs/google-search): Grounding, citations, and search suggestions. - [Managed Agents](/docs/managed-agents-quickstart): Pre-built agents with code execution and file management. - [Deep Research](/docs/deep-research): Autonomous multi-step research with planning and synthesis. - [Structured output](/docs/structured-output): JSON schemas, enums, and recursive type definitions. # Using Gemini API keys Source: https://aistudio.google.com/docs/api-key Description: Get your Gemini API key and start building in less than 5 minutes using the Interactions API. To use the Gemini API, you must authenticate your requests. You can authenticate using a standard or authorization API key. {% button href="https://aistudio.google.com/apikey" variant="ais" %}Create or view a Gemini API Key{% /button %} ## API key types: Standard versus Authorization {% id="api-keys" %} API keys provide access to the Gemini API, but their security characteristics differ. The Gemini API is transitioning from standard API keys to authorization keys to improve security: * **Standard API keys**: Associate requests with a Google Cloud project for billing and quota purposes. Standard keys don't identify a caller, which limits the granularity of permissions and access control they can support. * **Authorization (auth) keys**: Bound directly to a Google Cloud service account. When you use an authorization key, your requests are processed under the identity of that bound service account, enabling granular access control. Authorization keys are restricted to the Generative Language API (Gemini API) by default and provide fast-acting leaked key enforcement that quickly stops the usage of leaked keys detected by our systems. To ensure secure usage, Gemini API will move from standard keys to auth keys: * **Auth keys default**: Starting May 28, 2026, all new API keys created in Google AI Studio are automatically created as auth keys. * **Unrestricted keys rejected**: The Gemini API rejects requests from **unrestricted standard keys**. Standard API keys that have explicit restrictions applied continue to work. This restriction prevents the unauthorized use of keys that might be shared publicly or linked to other services. {% callout type="note" %} Requests authenticated by authorization keys are not recorded in Google Cloud service account usage metrics. {% /callout %} ## Managing API keys in Google AI Studio {% id="getting-started" %} You can manage your projects and keys directly in [Google AI Studio](https://aistudio.google.com/apikey). ### Google Cloud projects {% id="google-cloud-projects" %} Every Gemini API key is associated with a [Google Cloud project](https://cloud.google.com/resource-manager/docs/creating-managing-projects). Google Cloud projects manage billing, collaborators, and permissions. Google AI Studio provides a lightweight interface to access these projects. * **Default project**: If you are a new user, Google AI Studio automatically creates a default Google Cloud project and API key after you accept the Terms of Service. You can rename this project by navigating to the **Projects** view in your dashboard. * **Existing projects**: If you already have a Google Cloud account, AI Studio does not create a default project. Instead, you must import your existing projects. ### Importing projects {% id="import-projects" %} By default, Google AI Studio does not display all of your Google Cloud projects. You must import the projects you want to use: 1. Go to [Google AI Studio](https://aistudio.google.com). 2. Open the **Dashboard** from the left panel and select **Projects**. 3. Click the **Import projects** button. 4. Search for and select the Google Cloud project you want to import, then click **Import**. 5. Once imported, navigate to the **API Keys** page in the dashboard to create a key in that project. ### Troubleshooting key creation permissions {% id="key-permission" %} If the **Create API key** button is unavailable and displays the message: *"You do not have permission to create a key in this project"*, you lack the required IAM permissions. Ask your Google Cloud project or organization administrator to grant you a role containing the following permissions (such as Project Editor): * `resourcemanager.projects.get`: Allows AI Studio to verify the project. * `apikeys.keys.create`: Allows key generation. * `serviceusage.services.enable`: Ensures the Generative Language API is enabled. * `iam.serviceAccounts.create`: Required to create the linked service account. * `iam.serviceAccountApiKeyBindings.create`: Binds the service account to the API key. If you cannot get administrative access, you can create a new Google Cloud project that is not associated with an organization to generate your keys. ### Unknown keys on the Usage page {% id="unknown-keys" %} The [Usage page](https://aistudio.google.com/usage) in Google AI Studio groups requests it can't match to a named API key in the project under **(unknown keys)**. This includes keys deleted more than 30 days ago, keys without a display name, and requests made with other credentials, such as OAuth. ## Creating keys in the Google Cloud console {% id="cloud-console" %} Google AI Studio only displays keys that are unrestricted or restricted to the Gemini API. If you can't use AI Studio, or you want to manage all of your API keys in one place, follow the Cloud documentation on [creating an API key](https://cloud.google.com/docs/authentication/api-keys#create). Creating a Gemini API key requires binding it to a [service account](https://cloud.google.com/iam/docs/service-account-overview). ## Setting up your environment {% id="setup-environment" %} Once you have a key, configure your environment to use it securely in your applications. ### Option 1: Use environment variables (Recommended) {% id="set-api-env-var" %} Set the environment variable `GEMINI_API_KEY` or `GOOGLE_API_KEY`. The Gemini API client libraries automatically detect and use these variables. If both are set, `GOOGLE_API_KEY` takes precedence. Select your operating system to set the variable: {% tabs %} {% tab label="Linux/macOS - Bash" %} Verify if you have a bash configuration file: ```posix-terminal ~/.bashrc ``` If not, create one and open it: ```posix-terminal touch ~/.bashrc && open ~/.bashrc ``` Add the export command at the end of the file: ```posix-terminal export GEMINI_API_KEY=[YOUR_API_KEY_HERE] ``` Save the file, then apply the changes: ```posix-terminal source ~/.bashrc ``` {% /tab %} {% tab label="macOS - Zsh" %} Verify if you have a zsh configuration file: ```posix-terminal ~/.zshrc ``` If not, create one and open it: ```posix-terminal touch ~/.zshrc && open ~/.zshrc ``` Add the export command: ```posix-terminal export GEMINI_API_KEY=[YOUR_API_KEY_HERE] ``` Save the file, then apply the changes: ```posix-terminal source ~/.zshrc ``` {% /tab %} {% tab label="Windows" %} 1. Search for "Environment Variables" in the Windows search bar. 2. Click **Environment Variables** in the System Properties dialog. 3. Under **User variables** or **System variables**, click **New...**. 4. Set the variable name to `GEMINI_API_KEY` and the value to your API key. 5. Click **OK** to save. Open a new terminal session to load the variable. {% /tab %} {% /tabs %} ### Option 2: Provide the API key explicitly in code {% id="provide-api-key-explicitly" %} You can pass the API key explicitly when initializing the client. Only do this if you cannot use environment variables. {% tabs %} {% tab label="Python" %} ```python from google import genai client = genai.Client(api_key="YOUR_API_KEY") interaction = client.interactions.create( model="gemini-3.8-flash", input="Explain how AI works in a few words" ) print(interaction.output_text) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({ apiKey: "YOUR_API_KEY" }); async function main() { const interaction = await ai.interactions.create({ model: "gemini-3.8-flash", input: "Explain how AI works in a few words", }); console.log(interaction.output_text); } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; Client client = Client.builder().apiKey("YOUR_API_KEY").build(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-3.8-flash")) .input(InteractionsInput.of("Explain how AI works in a few sentences.")) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); System.out.println(interaction.outputText().orElse("")); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, &genai.ClientConfig{ APIKey: "{{ 'YOUR_API_KEY' }}", }) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.8-flash"), Input: interactions.NewInteractionsInput("Explain how AI works in a few sentences."), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputText != nil { fmt.Println(*res.Interaction.OutputText) } } ``` {% /tab %} {% tab label="REST" %} ```bash curl "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H 'Content-Type: application/json' \ -H "x-goog-api-key: YOUR_API_KEY" \ -H "Api-Revision: 2026-05-20" \ -X POST \ -d '{ "model": "gemini-3.8-flash", "input": "Explain how AI works in a few words" }' ``` {% /tab %} {% /tabs %} ## Security and secret management {% id="security" %} Treat your Gemini API key like a password. If compromised, others can consume your project's quota, incur unexpected billing charges, and access private resources. ### Critical security rules {% id="critical-security-rules" %} * **Keep keys confidential**: Never check API keys into source control systems like Git. * **Never expose keys client-side in production**: Do not hardcode API keys directly in web or mobile apps. Keys compiled in client-side code can be extracted by users. To secure client-side apps, run a backend proxy server to make the actual API calls. ### Secret management best practices {% id="secret-management" %} * **Environment variables**: Read keys from environment variables rather than configuration files. * **Secret Manager**: For production, store your keys in a secure secret store such as [Google Cloud Secret Manager](https://cloud.google.com/secret-manager). * **Billing alerts**: Set up billing alerts in the Google Cloud console to notify you if usage or costs spike. ### Leak response checklist {% id="leak-response" %} If you suspect your API key has been leaked: 1. **Generate a new key**: Create a replacement key in Google AI Studio or the Cloud console. 2. **Update your application**: Deploy your code using the new key. 3. **Disable or delete the compromised key**: Disable the leaked key in the Cloud console once the new key is verified. Do not delete the old key until the new key is fully active to avoid application downtime. 4. **Audit usage**: Check billing logs and API usage in the Google Cloud console to identify unauthorized activity. ## Restricting and securing your keys {% id="restricting-keys" %} Adding restrictions to your API keys minimizes the potential damage if a key is compromised. ### Apply request origin restrictions {% id="request-origin-restrictions" %} Origin restrictions limit which IP addresses, websites, or applications can use your key. 1. Go to the [Google Cloud console credentials page](https://console.cloud.google.com/apis/credentials). 2. Select your project, and click the name of the API key you want to restrict. 3. Under **Application restrictions**, select **IP addresses** (or the appropriate restriction type for your environment). 4. Specify the allowed IP addresses or ranges, then click **Save**. ### Securing unrestricted standard API keys {% id="secure-unrestricted-keys" %} To continue using the Gemini API, you must secure any unrestricted keys. #### Method A: Restrict the key to the Gemini API only (AI Studio) {% id="method-a-restrict-the-key-to-the-gemini-api-only-ai-studio" %} If you only use the key for the Gemini API, secure it directly in AI Studio: 1. On the **API Keys** page in [Google AI Studio](https://aistudio.google.com/api-keys), locate keys marked with the **Unrestricted** label. 2. Hover over the label and click **Add restrictions** in the dialog. 3. Select **Restrict to Gemini API only**. 4. Click **Restrict key** to confirm. {% callout type="note" %} To restrict an API key, you must have the `apikeys.keys.update` permission on the associated Google Cloud project. This permission is included in roles like **API Keys Admin** or **Editor**. {% /callout %} #### Method B: Restrict the key for other services (Google Cloud console) {% id="method-b-restrict-the-key-for-other-services-google-cloud-console" %} If the key is shared with other Google APIs (not recommended), restrict it in the Cloud console. **Note: Gemini API requests using this key will fail after these restrictions are applied.** 1. Visit the [Google Cloud console credentials page](https://console.cloud.google.com/apis/credentials). 2. Select the project and the API key. 3. Under **API restrictions**, select **Restrict key**. 4. From the drop-down, select the APIs you want this key to access. Do not select the **Generative Language API**. 5. Click **Save**. Create a separate, restricted key in AI Studio to continue using the Gemini API. ### Blocked dormant keys {% id="blocked-keys" %} Starting May 7, 2026, the Gemini API blocks unrestricted API keys that have been dormant for an extended period. These keys show a **Blocked** tag in AI Studio. You must generate a new key or use an existing restricted key to continue. ## Migrate to an auth key {% id="migrate-to-auth-key" %} Follow these steps to create a new auth API key and update your applications: 1. Go to the [AI Studio API Keys page](https://aistudio.google.com/api-keys). 2. Check the **Key Type** column to identify any keys listed as **Standard**. 3. Click **Create API key** to generate a new key. All new keys created in AI Studio are automatically created as auth keys. 4. Copy the new auth API key. 5. Update your application code, environment variables, and any deployment configurations to use the new auth API key. 6. Test your application to confirm it works correctly with the new key. 7. Once verified, delete or revoke your old traffic key to prevent misuse. {% callout type="note" %} If you don't see your keys, you may need to import your Cloud projects into AI Studio. Refer to the [import projects](/docs/api-key#import-projects) section for instructions. {% /callout %} ## Limitations {% id="limitations" %} Google AI Studio imposes the following project and key management limitations: * You can create a maximum of 10 projects at a time from the Google AI Studio **Projects** page. * The **API keys** and **Projects** pages display a maximum of 100 keys and 50 projects. * Only API keys that are unrestricted or restricted specifically to the Generative Language API (Gemini API) are displayed. For advanced project management or to modify keys with other restrictions, use the [Google Cloud console credentials page](https://console.cloud.google.com/apis/credentials). # Gemini Developer API pricing Source: https://aistudio.google.com/docs/pricing Description: Gemini Developer API Pricing Start building free of charge with generous limits, then scale up with prepaid and pay-as-you-go pricing for your production-ready applications. {% card-grid %} {% card title="Free" %} For developers and small projects getting started with the Gemini API. {% hr /%} {% section class="checkmark-icon-list" %} * {% icon name="check_circle" /%} Limited access to certain models * {% icon name="check_circle" /%} Free input & output tokens * {% icon name="check_circle" /%} Google AI Studio access * {% icon name="check_circle" /%} Content used to improve our products{% sup %}[*](/docs/terms){% /sup %} {% /section %} {% section class="center-content align-bottom" %} {% button href="https://aistudio.google.com" %} Get started for Free {% /button %} {% /section %} {% /card %} {% card title="Paid" %} For production applications that require higher volumes and advanced features. {% hr /%} {% section class="checkmark-icon-list" %} * {% icon name="check_circle" /%} Higher rate limits for production deployments * {% icon name="check_circle" /%} Access to Context caching * {% icon name="check_circle" /%} Batch API (50% cost reduction) * {% icon name="check_circle" /%} Access to Google's most advanced models * {% icon name="check_circle" /%} Content **not** used to improve our products{% sup %}[*](/docs/terms){% /sup %} {% /section %} {% section class="center-content align-bottom" %} {% button href="https://aistudio.google.com/api-keys" %} Upgrade to Paid {% /button %} {% /section %} {% /card %} {% card title="Enterprise" %} For enterprise deployments, powered by [Gemini Enterprise Agent Platform](https://cloud.google.com/gemini-enterprise-agent-platform). {% hr /%} {% section class="checkmark-icon-list" %} * {% icon name="check_circle" /%} All features in Paid, plus optional access to: * {% icon name="check_circle" /%} Dedicated support channels * {% icon name="check_circle" /%} Advanced security & compliance * {% icon name="check_circle" /%} Provisioned throughput * {% icon name="check_circle" /%} Volume-based discounts (based on usage) * {% icon name="check_circle" /%} ML ops, model garden and more {% /section %} {% section class="center-content align-bottom" %} {% button href="https://cloud.google.com/contact" %} Contact Sales {% /button %} {% /section %} {% /card %} {% /card-grid %} ## Gemini 4 Argon {% id="gemini-4-argon" %} {% two-column-layout %} {% left-column class="center-vertically" %} *[`gemini-4-argon`](/docs/models/gemini-4-argon)* {% /left-column %} {% right-column class="center-vertically right-align" %} {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-4-argon" variant="ais" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} Our flagship reasoning model, built for complex software engineering, deep mathematical and scientific problem solving, autonomous multi-step agents, and long-decode generation up to 1M tokens. {% callout type="note" %} Gemini 4 Argon is not available on the Free tier. Every token the model processes is counted and billed, including thinking tokens and internal tool system instructions and function declarations when using grounding. {% /callout %} {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $2.00 through November 30, 2026. \ $4.00 starting December 1, 2026. --- * Output price (including thinking tokens) * Not available * $10.00 through November 30, 2026. \ $20.00 starting December 1, 2026. --- * Context caching price * Not available * $0.10 through November 30, 2026. \ $0.20 starting December 1, 2026. \ Implicit caching only (explicit caching is not supported). --- * Grounding with Google Search{% sup %}*{% /sup %} * Not available * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Grounding with Google Maps * Not available * 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * Used to improve our products * Not available * [No](/docs/terms) {% /table %} {% sup %}*{% /sup %} A customer-submitted request to Gemini may result in one or more queries to Google Search. You will be charged for each individual search query performed. {% /tab %} {% tab title="Batch" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $1.00 through November 30, 2026. \ $2.00 starting December 1, 2026. --- * Output price (including thinking tokens) * Not available * $5.00 through November 30, 2026. \ $10.00 starting December 1, 2026. --- * Context caching price * Not available * $0.05 through November 30, 2026. \ $0.10 starting December 1, 2026. \ Implicit caching only (explicit caching is not supported). --- * Used to improve our products * Not available * [No](/docs/terms) {% /table %} {% sup %}*{% /sup %} A customer-submitted request to Gemini may result in one or more queries to Google Search. You will be charged for each individual search query performed. {% /tab %} {% tab title="Flex" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $1.00 through November 30, 2026. \ $2.00 starting December 1, 2026. --- * Output price (including thinking tokens) * Not available * $5.00 through November 30, 2026. \ $10.00 starting December 1, 2026. --- * Context caching price * Not available * $0.05 through November 30, 2026. \ $0.10 starting December 1, 2026. \ Implicit caching only (explicit caching is not supported). --- * Used to improve our products * Not available * [No](/docs/terms) {% /table %} {% sup %}*{% /sup %} A customer-submitted request to Gemini may result in one or more queries to Google Search. You will be charged for each individual search query performed. {% /tab %} {% tab title="Priority" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $3.60 through November 30, 2026. \ $7.20 starting December 1, 2026. --- * Output price (including thinking tokens) * Not available * $18.00 through November 30, 2026. \ $36.00 starting December 1, 2026. --- * Context caching price * Not available * $0.18 through November 30, 2026. \ $0.36 starting December 1, 2026. \ Implicit caching only (explicit caching is not supported). --- * Grounding with Google Search{% sup %}*{% /sup %} * Not available * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Grounding with Google Maps * Not available * 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * Used to improve our products * Not available * [No](/docs/terms) {% /table %} {% sup %}*{% /sup %} A customer-submitted request to Gemini may result in one or more queries to Google Search. You will be charged for each individual search query performed. {% /tab %} {% tab title="Contributor" %} {% callout type="note" %} The Gemini API Contributor Tier is offered as a private preview on an invite-only basis. Speed and reliability are equivalent to [Standard Tier inference](/docs/optimization). Eligible users will be invited by email and see a callout in AI Studio. {% /callout %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD{% sup %}*{% /sup %} --- * Input price * Not available * $1.00 --- * Output price (including thinking tokens) * Not available * $5.00 --- * Context caching price * Not available * $0.05 \ Implicit caching only (explicit caching is not supported). --- * Used to improve our products * Not available * [Yes](/docs/logs-policy#contributor-tier) {% /table %} {% sup %}*{% /sup %} Discounts and model availability are subject to change. {% /tab %} {% /tabs %} ## Gemini 3.8 Flash {% id="gemini-3.8-flash" %} {% two-column-layout %} {% left-column class="center-vertically" %} *[`gemini-3.8-flash`](/docs/models/gemini-3.8-flash)* {% /left-column %} {% right-column class="center-vertically right-align" %} {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-3.8-flash" variant="ais" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} Our most intelligent Flash model, engineered for long-horizon software engineering, autonomous agents, and complex enterprise workflows. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $0.75 through December 31, 2026. \ $1.50 starting January 1, 2027. --- * Output price (including thinking tokens) * Free of charge * $3.75 through December 31, 2026. \ $7.50 starting January 1, 2027. --- * Context caching price * Free of charge * $0.075 through December 31, 2026. \ $0.15 starting January 1, 2027. \ $0.50 / 1,000,000 tokens per hour (storage price) through December 31, 2026. \ $1.00 / 1,000,000 tokens per hour (storage price) starting January 1, 2027. --- * Grounding with Google Search * Not available * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Grounding with Google Maps * Not available * 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Batch" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.375 through December 31, 2026. \ $0.75 starting January 1, 2027. --- * Output price (including thinking tokens) * Not available * $1.875 through December 31, 2026. \ $3.75 starting January 1, 2027. --- * Context caching price * Not available * $0.0375 through December 31, 2026. \ $0.075 starting January 1, 2027. \ $0.50 / 1,000,000 tokens per hour (storage price) through December 31, 2026. \ $1.00 / 1,000,000 tokens per hour (storage price) starting January 1, 2027. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Flex" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.375 through December 31, 2026. \ $0.75 starting January 1, 2027. --- * Output price (including thinking tokens) * Not available * $1.875 through December 31, 2026. \ $3.75 starting January 1, 2027. --- * Context caching price * Not available * $0.0375 through December 31, 2026. \ $0.075 starting January 1, 2027. \ $0.50 / 1,000,000 tokens per hour (storage price) through December 31, 2026. \ $1.00 / 1,000,000 tokens per hour (storage price) starting January 1, 2027. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Priority" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $1.35 through December 31, 2026. \ $2.70 starting January 1, 2027. --- * Output price (including thinking tokens) * Free of charge * $6.75 through December 31, 2026. \ $13.50 starting January 1, 2027. --- * Context caching price * Free of charge * $0.135 through December 31, 2026. \ $0.27 starting January 1, 2027. \ $0.50 / 1,000,000 tokens per hour (storage price) through December 31, 2026. \ $1.00 / 1,000,000 tokens per hour (storage price) starting January 1, 2027. --- * Grounding with Google Search{% sup %}*{% /sup %} * Not available{% sup %}**{% /sup %} * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Grounding with Google Maps * Not available{% sup %}**{% /sup %} * 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Contributor" %} {% callout type="note" %} The Gemini API Contributor Tier is offered as a private preview on an invite-only basis. Speed and reliability are equivalent to [Standard Tier inference](/docs/optimization). Eligible users will be invited by email and see a callout in AI Studio. {% /callout %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD{% sup %}*{% /sup %} --- * Input price * Free of charge * $0.375 --- * Output price (including thinking tokens) * Free of charge * $1.875 --- * Context caching price * Free of charge * $0.0375 \ $0.50 / 1,000,000 tokens per hour (storage price) --- * Used to improve our products * [Yes](/docs/terms) * [Yes](/docs/logs-policy#contributor-tier) {% /table %} {% sup %}*{% /sup %} Discounts and model availability are subject to change. {% /tab %} {% /tabs %} ## Gemini 3.6 Flash {% id="gemini-3.6-flash" %} {% two-column-layout %} {% left-column %} *[`gemini-3.6-flash`](/docs/models/gemini-3.6-flash)* {% /left-column %} {% right-column class="center-vertically right-align" %} {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-3.6-flash" variant="ais" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} Our previous generation Flash model, balancing speed and multimodal capabilities across general agentic and everyday tasks. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $0.75 through December 31, 2026. \ $1.50 starting January 1, 2027. --- * Output price (including thinking tokens) * Free of charge * $3.75 through December 31, 2026. \ $7.50 starting January 1, 2027. --- * Context caching price * Free of charge * $0.075 through December 31, 2026. \ $0.15 starting January 1, 2027. \ $0.50 / 1,000,000 tokens per hour (storage price) through December 31, 2026. \ $1.00 / 1,000,000 tokens per hour (storage price) starting January 1, 2027. --- * Grounding with Google Search{% sup %}*{% /sup %} * Not available{% sup %}**{% /sup %} * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Grounding with Google Maps * Not available{% sup %}**{% /sup %} * 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Batch" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.375 through December 31, 2026. \ $0.75 starting January 1, 2027. --- * Output price (including thinking tokens) * Not available * $1.875 through December 31, 2026. \ $3.75 starting January 1, 2027. --- * Context caching price * Not available * $0.0375 through December 31, 2026. \ $0.075 starting January 1, 2027. \ $0.50 / 1,000,000 tokens per hour (storage price) through December 31, 2026. \ $1.00 / 1,000,000 tokens per hour (storage price) starting January 1, 2027. --- * Grounding with Google Search{% sup %}*{% /sup %} * Not available{% sup %}**{% /sup %} * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Grounding with Google Maps * Not available{% sup %}**{% /sup %} * 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Flex" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.375 through December 31, 2026. \ $0.75 starting January 1, 2027. --- * Output price (including thinking tokens) * Not available * $1.875 through December 31, 2026. \ $3.75 starting January 1, 2027. --- * Context caching price * Not available * $0.0375 through December 31, 2026. \ $0.075 starting January 1, 2027. \ $0.50 / 1,000,000 tokens per hour (storage price) through December 31, 2026. \ $1.00 / 1,000,000 tokens per hour (storage price) starting January 1, 2027. --- * Grounding with Google Search{% sup %}*{% /sup %} * Not available{% sup %}**{% /sup %} * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Grounding with Google Maps * Not available{% sup %}**{% /sup %} * 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Priority" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $1.35 through December 31, 2026. \ $2.70 starting January 1, 2027. --- * Output price (including thinking tokens) * Free of charge * $6.75 through December 31, 2026. \ $13.50 starting January 1, 2027. --- * Context caching price * Free of charge * $0.135 through December 31, 2026. \ $0.27 starting January 1, 2027. \ $0.50 / 1,000,000 tokens per hour (storage price) through December 31, 2026. \ $1.00 / 1,000,000 tokens per hour (storage price) starting January 1, 2027. --- * Grounding with Google Search{% sup %}*{% /sup %} * Not available{% sup %}**{% /sup %} * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Grounding with Google Maps * Not available{% sup %}**{% /sup %} * 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% /tabs %} {% sup %}*{% /sup %} A customer-submitted request to Gemini may result in one or more queries to Google Search. You will be charged for each individual search query performed. {% sup %}**{% /sup %} Can be tested in Google AI Studio. ## Gemini 3.5 Transcribe Live {% id="gemini-3.5-transcribe-live" %} {% two-column-layout %} {% left-column %} *[`gemini-3.5-transcribe-live`](/docs/models/gemini-3.5-transcribe)* {% /left-column %} {% right-column class="center-vertically right-align" %} {% button href="https://aistudio.google.com?model=gemini-3.5-transcribe-live" variant="ais" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} Our low-latency, real-time speech-to-text model for bidirectional streaming audio transcription over WebSockets. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $3.50 or $0.005/min{% sup %}*{% /sup %} (audio) --- * Output price (including thinking tokens) * Free of charge * $21.00 or $0.004/min{% sup %}*{% /sup %} (text) --- * Grounding with Google Search * Not Supported * --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% /tabs %} {% sup %}*{% /sup %} Estimated pricing is based on 25 audio tokens per second for input and 175 text tokens per minute for output, for an effective blended rate of ~$0.009 per min for Live Transcribe. ## Gemini 3.5 Transcribe {% id="gemini-3.5-transcribe" %} {% two-column-layout %} {% left-column %} *[`gemini-3.5-transcribe`](/docs/models/gemini-3.5-transcribe)* {% /left-column %} {% right-column class="center-vertically right-align" %} {% button href="https://aistudio.google.com?model=gemini-3.5-transcribe" variant="ais" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} Our speech-to-text model with automatic language detection, speaker diarization, word-level timestamps, and custom vocabulary biasing. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $2.00 or $0.003/min{% sup %}*{% /sup %} (audio) --- * Output price (including thinking tokens) * Free of charge * $12.00 or $0.002/min{% sup %}*{% /sup %} (text) --- * Grounding with Google Search * Not Supported * --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% /tabs %} {% sup %}*{% /sup %} Estimated pricing is based on 25 audio tokens per second for input and 175 text tokens per minute for output, for an effective blended rate of ~$0.005 per min for Transcribe. ## Gemini 3.5 Flash-Lite {% id="gemini-3.5-flash-lite" %} {% two-column-layout %} {% left-column %} *[`gemini-3.5-flash-lite`](/docs/models/gemini-3.5-flash-lite)* {% /left-column %} {% right-column class="center-vertically right-align" %} {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-3.5-flash-lite" variant="ais" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} A cost-efficient model, optimized for high-volume agentic tasks, translation, and simple data processing. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $0.30 (text / image / video / audio) --- * Output price (including thinking tokens) * Free of charge * $2.50 --- * Context caching price * Not available * $0.03 \ $1.00 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search{% sup %}*{% /sup %} * Not available{% sup %}**{% /sup %} * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Grounding with Google Maps * Not available{% sup %}**{% /sup %} * 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% sup %}*{% /sup %} A customer-submitted request to Gemini may result in one or more queries to Google Search. You will be charged for each individual search query performed. {% sup %}**{% /sup %} Can be tested in Google AI Studio. {% /tab %} {% tab title="Batch" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $0.15 (text / image / video / audio) --- * Output price (including thinking tokens) * Free of charge * $1.25 --- * Context caching price * Not available * $0.015 \ $1.00 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search{% sup %}*{% /sup %} * Not available{% sup %}**{% /sup %} * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Grounding with Google Maps * Not available{% sup %}**{% /sup %} * 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% sup %}*{% /sup %} A customer-submitted request to Gemini may result in one or more queries to Google Search. You will be charged for each individual search query performed. {% sup %}**{% /sup %} Can be tested in Google AI Studio. {% /tab %} {% tab title="Flex" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.15 (text / image / video / audio) --- * Output price (including thinking tokens) * Not available * $1.25 --- * Context caching price * Not available * $0.02 \ $1.00 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search{% sup %}*{% /sup %} * Not available{% sup %}**{% /sup %} * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Grounding with Google Maps * Not available{% sup %}**{% /sup %} * 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% sup %}*{% /sup %} A customer-submitted request to Gemini may result in one or more queries to Google Search. You will be charged for each individual search query performed. {% sup %}**{% /sup %} Can be tested in Google AI Studio. {% /tab %} {% tab title="Priority" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $0.54 (text / image / video / audio) --- * Output price (including thinking tokens) * Free of charge * $4.50 --- * Context caching price * Not available * $0.05 \ $1.00 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search{% sup %}*{% /sup %} * Not available{% sup %}**{% /sup %} * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Grounding with Google Maps * Not available{% sup %}**{% /sup %} * 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% sup %}*{% /sup %} A customer-submitted request to Gemini may result in one or more queries to Google Search. You will be charged for each individual search query performed. {% sup %}**{% /sup %} Can be tested in Google AI Studio. {% /tab %} {% tab title="Contributor" %} {% callout type="note" %} The Gemini API Contributor Tier is offered as a private preview on an invite-only basis. Speed and reliability are equivalent to [Standard Tier inference](/docs/optimization). Eligible users will be invited by email and see a callout in AI Studio. {% /callout %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD{% sup %}*{% /sup %} --- * Input price * Free of charge * $0.15 (text / image / video / audio) --- * Output price (including thinking tokens) * Free of charge * $1.25 --- * Context caching price * Not available * $0.015 \ $1.00 / 1,000,000 tokens per hour (storage price) --- * Used to improve our products * [Yes](/docs/terms) * [Yes](/docs/logs-policy#contributor-tier) {% /table %} {% sup %}*{% /sup %} Discounts and model availability are subject to change. {% /tab %} {% /tabs %} ## Gemini Omni Flash {% id="gemini-omni-1.1-flash" %} {% two-column-layout %} {% left-column class="center-vertically" %} *[`gemini-omni-1.1-flash`](/docs/models/gemini-omni-flash)* {% /left-column %} {% right-column class="center-vertically right-align" %} {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-omni-1.1-flash" variant="ais" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} Our next-generation video generation and editing model, now generally available to developers on the paid tier of the Gemini API. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $1.50 (text / image / video / audio) --- * Output price (including thinking tokens) * Not available * $9.00 (text) \ $17.50 (video){% sup %}*{% /sup %} --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% /tabs %} {% sup %}*{% /sup %} Billing is based on total output token consumption, calculated at a rate of 5,792 tokens per second of 720p video. Under Standard pricing, this equates to an effective price of approximately $0.10 per second. ## Gemini 3.8 Live, Gemini 3.8 Live Extended Thinking, and Gemini 3.1 Flash Live Preview {% id="gemini-3.8-live" %} {% two-column-layout %} {% left-column class="center-vertically" %} *[`gemini-3.8-live`](/docs/models/gemini-3.8-live), [`gemini-3.8-live-extended-thinking`](/docs/models/gemini-3.8-live-extended-thinking), [`gemini-3.1-flash-live-preview`](/docs/models/gemini-3.1-flash-live-preview)* {% /left-column %} {% right-column class="center-vertically right-align" %} {% button href="https://aistudio.google.com/live?model=gemini-3.8-live" variant="ais" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} Our low-latency, audio-to-audio models optimized for real-time dialogue with acoustic nuance detection, numeric precision, and multimodal awareness. {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $0.75 (text) \ $3.00 or $0.005/min (audio) \ $1.00 or $0.002/min (image/video) --- * Output price (including thinking tokens) * Free of charge * $4.50 (text) \ $12.00 or $0.018/min (audio) --- * Grounding with Google Search{% sup %}*{% /sup %} * Supported * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% sup %}*{% /sup %} A customer-submitted request to Gemini may result in one or more queries to Google Search. You will be charged for each individual search query performed. ## Gemini 3.5 Live Translate {% id="gemini-3.5-live-translate-preview" %} {% two-column-layout %} {% left-column class="center-vertically" %} *[`gemini-3.5-live-translate-preview`](/docs/models/gemini-3.5-live-translate-preview)* {% /left-column %} {% right-column class="center-vertically right-align" %} {% button href="https://aistudio.google.com/live?model=gemini-3.5-live-translate-preview" variant="ais" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} Our low-latency, real-time speech to speech translation model that supports 70+ languages. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $3.50 or $0.0053/min{% sup %}*{% /sup %} (audio) --- * Output price (including thinking tokens) * Free of charge * $21.00 or $0.0315/min{% sup %}*{% /sup %} (audio) --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% /tabs %} {% sup %}*{% /sup %} Billing is based on total input and output audio token consumption, calculated at a rate of 25 tokens per second of audio, equating to an effective price of approximately $0.0368 per minute. ## Gemini 3.1 Flash-Lite {% id="gemini-3.1-flash-lite" %} {% two-column-layout %} {% left-column class="center-vertically" %} *[`gemini-3.1-flash-lite`](/docs/models/gemini-3.1-flash-lite)* {% /left-column %} {% right-column class="center-vertically right-align" %} {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-3.1-flash-lite" variant="ais"%} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} A cost-efficient model, optimized for high-volume agentic tasks, translation, and simple data processing. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $0.25 (text / image / video) \ $0.50 (audio) --- * Output price (including thinking tokens) * Free of charge * $1.50 --- * Context caching price * Not available * $0.025 (text / image / video) \ $0.05 (audio) \ $1.00 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search{% sup %}*{% /sup %} * Not available{% sup %}**{% /sup %} * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Grounding with Google Maps * Not available{% sup %}**{% /sup %} * 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Batch" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $0.125 (text / image / video) \ $0.25 (audio) --- * Output price (including thinking tokens) * Free of charge * $0.75 --- * Context caching price * Not available * $0.0125 (text / image / video) \ $0.025 (audio) \ $0.50 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search{% sup %}*{% /sup %} * Not available{% sup %}**{% /sup %} * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Grounding with Google Maps * Not available{% sup %}**{% /sup %} * 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Flex" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $0.125 (text / image / video) \ $0.25 (audio) --- * Output price (including thinking tokens) * Free of charge * $0.75 --- * Context caching price * Not available * $0.0125 (text / image / video) \ $0.025 (audio) \ $0.50 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search{% sup %}*{% /sup %} * Not available{% sup %}**{% /sup %} * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Grounding with Google Maps * Not available{% sup %}**{% /sup %} * 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Priority" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $0.45 (text / image / video) \ $0.90 (audio) --- * Output price (including thinking tokens) * Free of charge * $2.70 --- * Context caching price * Not available * $0.045 (text / image / video) \ $0.09 (audio) \ $1.80 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search{% sup %}*{% /sup %} * Not available{% sup %}**{% /sup %} * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Grounding with Google Maps * Not available{% sup %}**{% /sup %} * 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% /tabs %} {% sup %}*{% /sup %} A customer-submitted request to Gemini may result in one or more queries to Google Search. You will be charged for each individual search query performed. {% sup %}**{% /sup %} Can be tested in Google AI Studio. ## Gemini 3.1 Pro Preview {% id="gemini-3.1-pro-preview" %} {% two-column-layout %} {% left-column class="center-vertically" %} *[`gemini-3.1-pro-preview`](/docs/models/gemini-3.1-pro-preview) and [`gemini-3.1-pro-preview-customtools`](/docs/models/gemini-3.1-pro-preview#gemini-31-pro-preview-customtools)* {% /left-column %} {% right-column class="center-vertically right-align" %} {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-3.1-pro-preview" variant="ais" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} Our 3rd generation Pro model, built for multimodal understanding, agentic capabilities, and vibe-coding. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $2.00, prompts <= 200k tokens \ $4.00, prompts > 200k tokens --- * Output price (including thinking tokens) * Not available * $12.00, prompts <= 200k tokens \ $18.00, prompts > 200k --- * Context caching price * Not available * $0.20, prompts <= 200k tokens \ $0.40, prompts > 200k \ $4.50 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search{% sup %}*{% /sup %} * Not available{% sup %}**{% /sup %} * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Grounding with Google Maps * Not available{% sup %}**{% /sup %} * 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * Used to improve our products * Not available * [No](/docs/terms) {% /table %} {% sup %}*{% /sup %} A customer-submitted request to Gemini may result in one or more queries to Google Search. You will be charged for each individual search query performed. {% sup %}**{% /sup %} Can be tested in Google AI Studio. {% /tab %} {% tab title="Batch" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $1.00, prompts <= 200k tokens \ $2.00, prompts > 200k tokens --- * Output price (including thinking tokens) * Not available * $6.00, prompts <= 200k tokens \ $9.00, prompts > 200k --- * Context caching price * Not available * *Same as Standard* \ $0.20, prompts <= 200k tokens \ $0.40, prompts > 200k \ $4.50 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search{% sup %}*{% /sup %} * Not available{% sup %}**{% /sup %} * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Grounding with Google Maps * Not available{% sup %}**{% /sup %} * 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * Used to improve our products * Not available * [No](/docs/terms) {% /table %} {% sup %}*{% /sup %} A customer-submitted request to Gemini may result in one or more queries to Google Search. You will be charged for each individual search query performed. {% sup %}**{% /sup %} Can be tested in Google AI Studio. {% /tab %} {% tab title="Flex" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $1.00, prompts <= 200k tokens \ $2.00, prompts > 200k tokens --- * Output price (including thinking tokens) * Not available * $6.00, prompts <= 200k tokens \ $9.00, prompts > 200k --- * Context caching price * Not available * *Same as Standard* \ $0.20, prompts <= 200k tokens \ $0.40, prompts > 200k \ $4.50 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search{% sup %}*{% /sup %} * Not available{% sup %}**{% /sup %} * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Grounding with Google Maps * Not available{% sup %}**{% /sup %} * 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * Used to improve our products * Not available * [No](/docs/terms) {% /table %} {% sup %}*{% /sup %} A customer-submitted request to Gemini may result in one or more queries to Google Search. You will be charged for each individual search query performed. {% sup %}**{% /sup %} Can be tested in Google AI Studio. {% /tab %} {% tab title="Priority" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $3.60, prompts <= 200k tokens \ $7.20, prompts > 200k tokens --- * Output price (including thinking tokens) * Not available * $21.60, prompts <= 200k tokens \ $32.40, prompts > 200k --- * Context caching price * Not available * $0.36, prompts <= 200k tokens \ $0.72, prompts > 200k \ $8.10 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search{% sup %}*{% /sup %} * Not available{% sup %}**{% /sup %} * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Grounding with Google Maps * Not available{% sup %}**{% /sup %} * 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * Used to improve our products * Not available * [No](/docs/terms) {% /table %} {% sup %}*{% /sup %} A customer-submitted request to Gemini may result in one or more queries to Google Search. You will be charged for each individual search query performed. {% sup %}**{% /sup %} Can be tested in Google AI Studio. {% /tab %} {% tab title="Contributor" %} {% callout type="note" %} The Gemini API Contributor Tier is offered as a private preview on an invite-only basis. Speed and reliability are equivalent to [Standard Tier inference](/docs/optimization). Eligible users will be invited by email and see a callout in AI Studio. {% /callout %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD{% sup %}*{% /sup %} --- * Input price * Not available * $1.00, prompts <= 200k tokens \ $2.00, prompts > 200k tokens --- * Output price (including thinking tokens) * Not available * $6.00, prompts <= 200k tokens \ $9.00, prompts > 200k tokens --- * Context caching price * Not available * $0.10, prompts <= 200k tokens \ $0.20, prompts > 200k tokens \ $4.50 / 1,000,000 tokens per hour (storage price) --- * Used to improve our products * Not available * [Yes](/docs/logs-policy#contributor-tier) {% /table %} {% sup %}*{% /sup %} Discounts and model availability are subject to change. {% /tab %} {% /tabs %} ## Gemini Nano Banana 2.1 🍌 {% id="gemini-nano-banana-2.1" %} {% two-column-layout %} {% left-column class="center-vertically" %} *[`gemini-nano-banana-2.1`](/docs/models/gemini-nano-banana-2.1)* {% /left-column %} {% right-column class="center-vertically right-align" %} {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-nano-banana-2.1" variant="ais" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} An update to Nano Banana 2 (Gemini 3.1 Flash Image), built for high-efficiency image generation and conversational editing with improved visual quality, multi-turn character consistency, accurate text rendering, and search-grounded generation across 1K, 2K, and 4K resolutions. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $1.50 (text/image/video) --- * Output price * Not available * $7.50 (text and thinking) \ $30.00 (images) \ Equivalent to $0.0336 per 1K image{% sup %}*{% /sup %}, \ $0.0504 per 2K image{% sup %}*{% /sup %}, \ and $0.113 per 4K image{% sup %}*{% /sup %}. --- * Grounding with Google Web and Image Search{% sup %}**{% /sup %} * Not available * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests for text and image-based grounding (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Batch" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.75 (text/image/video) --- * Output price * Not available * $3.75 (text and thinking) \ $15.00 (images) \ Equivalent to $0.0168 per 1K image{% sup %}*{% /sup %}, \ $0.0252 per 2K image{% sup %}*{% /sup %}, \ and $0.0567 per 4K image{% sup %}*{% /sup %}. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% /tabs %} {% sup %}*{% /sup %} Image output is priced at $30 per 1,000,000 tokens (Standard) and $15 per 1,000,000 tokens (Batch). Output images at 1K (1024x1024px) consume 1120 tokens and are equivalent to $0.0336 per image. Output images at 2K (2048x2048px) consume 1680 tokens and are equivalent to $0.0504 per image. Output images at 4K (4096x4096px) consume 3780 tokens and are equivalent to $0.113 per image. {% sup %}**{% /sup %} A customer-submitted request to Gemini may result in one or more queries to Google Search. You will be charged for each individual search query performed. Retrieved context (text or images) provided by Grounding with Google Search is not charged as input tokens. ## Gemini 3.1 Flash Image (Nano Banana 2) 🍌 {% id="gemini-3.1-flash-image" %} {% two-column-layout %} {% left-column class="center-vertically" %} *[`gemini-3.1-flash-image`](/docs/models/gemini-3.1-flash-image)* {% /left-column %} {% right-column class="center-vertically right-align" %} {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-3.1-flash-image" variant="ais" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} Designed for speed and efficiency, the Gemini 3.1 Flash Image generation model is effective for quick, interactive responses and high throughput. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.50 (text/image) --- * Output price * Not available * $3 (text and thinking) \ $60.00 (images) \ Equivalent to $0.045 per 0.5K image{% sup %}*{% /sup %} \ $0.067 per 1K image{% sup %}*{% /sup %}, \ $0.101 per 2K image{% sup %}*{% /sup %}, \ and $0.151 per 4K image{% sup %}*{% /sup %}. --- * Grounding with Google Web and Image Search{% sup %}**{% /sup %} * Not available{% sup %}**{% /sup %} * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests for text and image-based grounding (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% /tabs %} {% sup %}*{% /sup %} Image output is priced at $60 per 1,000,000 tokens. Output images at 0.5K (512px) consume 747 tokens and are equivalent to $0.045 per image. Output images at 1K (1024x1024px) consume 1120 tokens and are equivalent to $0.067 per image. Output images at 2K (2048x2048px) consume 1680 tokens and are equivalent to $0.101 per image. Output images at 4K (4096x4096px) consume 2520 tokens and are equivalent to $0.151 per image. ## Gemini 3.1 Flash Lite Image (Nano Banana 2 Lite) 🍌 {% id="gemini-3.1-flash-lite-image" %} {% two-column-layout %} {% left-column class="center-vertically" %} *[`gemini-3.1-flash-lite-image`](/docs/models/gemini-3.1-flash-lite-image)* {% /left-column %} {% right-column class="center-vertically right-align" %} {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-3.1-flash-lite-image" variant="ais" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} Designed as the efficiency specialist of the image generation family, the Gemini 3.1 Flash Lite Image model is designed for ultra-low latency and cost-effective image generation and editing. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.25 (text/image/video) --- * Output price * Not available * $1.50 (text and thinking) \ $30.00 (images) \ Equivalent to $0.0336 per 1K resolution image{% sup %}*{% /sup %} --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Batch" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.125 (text/image/video) --- * Output price * Not available * $0.75 (text and thinking) \ $15.00 (images) \ Equivalent to $0.0168 per 1K resolution image{% sup %}*{% /sup %} --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% /tabs %} {% sup %}*{% /sup %} Image output is priced at $30 per 1,000,000 tokens. Output images at 1K (1024x1024px) consume 1120 tokens and are equivalent to $0.0336 per image. ## Gemini 3.8 Flash TTS {% id="gemini-3.8-flash-tts" %} {% two-column-layout %} {% left-column %} *[`gemini-3.8-flash-tts`](/docs/models/gemini-3.8-flash-tts)* {% /left-column %} {% right-column %} {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-3.8-flash-tts" variant="ais" class="right-align" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} Our 3.8 Flash Text-to-Speech audio model engineered for studio-grade voice fidelity, expressive acting, and long-form stability. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $0.50 (text) through December 31, 2026. \ $1.00 (text) starting January 1, 2027. --- * Output price * Free of charge * $9.00 (audio) through December 31, 2026. \ $18.00 (audio) starting January 1, 2027. \ Equivalent to $0.00225 per 10s audio{% sup %}*{% /sup %} through December 31, 2026. \ Equivalent to $0.0045 per 10s audio{% sup %}*{% /sup %} starting January 1, 2027. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Batch" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.25 (text) through December 31, 2026. \ $0.50 (text) starting January 1, 2027. --- * Output price * Not available * $4.50 (audio) through December 31, 2026. \ $9.00 (audio) starting January 1, 2027. \ Equivalent to $0.001125 per 10s audio{% sup %}*{% /sup %} through December 31, 2026. \ Equivalent to $0.00225 per 10s audio{% sup %}*{% /sup %} starting January 1, 2027. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Flex" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.25 (text) through December 31, 2026. \ $0.50 (text) starting January 1, 2027. --- * Output price * Not available * $4.50 (audio) through December 31, 2026. \ $9.00 (audio) starting January 1, 2027. \ Equivalent to $0.001125 per 10s audio{% sup %}*{% /sup %} through December 31, 2026. \ Equivalent to $0.00225 per 10s audio{% sup %}*{% /sup %} starting January 1, 2027. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Priority" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $0.90 (text) through December 31, 2026. \ $1.80 (text) starting January 1, 2027. --- * Output price * Free of charge * $16.20 (audio) through December 31, 2026. \ $32.40 (audio) starting January 1, 2027. \ Equivalent to $0.00405 per 10s audio{% sup %}*{% /sup %} through December 31, 2026. \ Equivalent to $0.0081 per 10s audio{% sup %}*{% /sup %} starting January 1, 2027. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% /tabs %} {% sup %}*{% /sup %} Audio tokens correspond to 25 tokens per second of audio. ## Gemini 3.8 Flash-Lite TTS {% id="gemini-3.8-flash-lite-tts" %} {% two-column-layout %} {% left-column %} *[`gemini-3.8-flash-lite-tts`](/docs/models/gemini-3.8-flash-lite-tts)* {% /left-column %} {% right-column %} {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-3.8-flash-lite-tts" variant="ais" class="right-align" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} Our 3.8 Flash-Lite Text-to-Speech audio model optimized for high-throughput, low-latency, and cost-efficient conversational speech. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $0.50 (text) through December 31, 2026. \ $1.00 (text) starting January 1, 2027. --- * Output price * Free of charge * $6.00 (audio) through December 31, 2026. \ $12.00 (audio) starting January 1, 2027. \ Equivalent to $0.0015 per 10s audio{% sup %}*{% /sup %} through December 31, 2026. \ Equivalent to $0.003 per 10s audio{% sup %}*{% /sup %} starting January 1, 2027. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Batch" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.25 (text) through December 31, 2026. \ $0.50 (text) starting January 1, 2027. --- * Output price * Not available * $3.00 (audio) through December 31, 2026. \ $6.00 (audio) starting January 1, 2027. \ Equivalent to $0.00075 per 10s audio{% sup %}*{% /sup %} through December 31, 2026. \ Equivalent to $0.0015 per 10s audio{% sup %}*{% /sup %} starting January 1, 2027. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Flex" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.25 (text) through December 31, 2026. \ $0.50 (text) starting January 1, 2027. --- * Output price * Not available * $3.00 (audio) through December 31, 2026. \ $6.00 (audio) starting January 1, 2027. \ Equivalent to $0.00075 per 10s audio{% sup %}*{% /sup %} through December 31, 2026. \ Equivalent to $0.0015 per 10s audio{% sup %}*{% /sup %} starting January 1, 2027. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Priority" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $0.90 (text) through December 31, 2026. \ $1.80 (text) starting January 1, 2027. --- * Output price * Free of charge * $10.80 (audio) through December 31, 2026. \ $21.60 (audio) starting January 1, 2027. \ Equivalent to $0.0027 per 10s audio{% sup %}*{% /sup %} through December 31, 2026. \ Equivalent to $0.0054 per 10s audio{% sup %}*{% /sup %} starting January 1, 2027. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% /tabs %} {% sup %}*{% /sup %} Audio tokens correspond to 25 tokens per second of audio. ## Gemini 3.1 Flash TTS Preview {% id="gemini-3.1-flash-tts-preview" %} {% two-column-layout %} {% left-column class="center-vertically" %} *[`gemini-3.1-flash-tts-preview`](/docs/models/gemini-3.1-flash-tts-preview)* {% /left-column %} {% right-column class="center-vertically right-align" %} {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-3.1-flash-tts-preview" variant="ais" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} Our 3.1 Flash Text-to-Speech audio model optimized for price-performant, low-latency, controllable speech generation. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $1.00 (text) --- * Output price * Free of charge * $20.00 (audio) --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Batch" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.50 (text) --- * Output price * Not available * $10.00 (audio) --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% /tabs %} {% sup %}*{% /sup %} Audio tokens correspond to 25 tokens per second of audio. ## Gemini 3 Flash Preview {% id="gemini-3-flash-preview" %} {% two-column-layout %} {% left-column class="center-vertically" %} *[`gemini-3-flash-preview`](/docs/models/gemini-3-flash-preview)* {% /left-column %} {% right-column class="center-vertically right-align" %} {% button href="https://aistudio.google.com?model=gemini-3-flash-preview" variant="ais" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} Our legacy Flash model, providing baseline speed and intelligence. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $0.50 (text / image / video) \ $1.00 (audio) --- * Output price (including thinking tokens) * Free of charge * $3.00 --- * Context caching price * Free of charge * $0.05 (text / image / video) \ $0.10 (audio) \ $1.00 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search{% sup %}*{% /sup %} * Not available{% sup %}**{% /sup %} * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Grounding with Google Maps * Not available{% sup %}**{% /sup %} * 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Batch" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.25 (text / image / video) \ $0.50 (audio) --- * Output price (including thinking tokens) * Not available * $1.50 --- * Context caching price * Not available * *Same as Standard* \ $0.05 (text / image / video) \ $0.10 (audio) \ $1.00 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search{% sup %}*{% /sup %} * Not available{% sup %}**{% /sup %} * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Grounding with Google Maps * Not available{% sup %}**{% /sup %} * 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Flex" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.25 (text / image / video) \ $0.50 (audio) --- * Output price (including thinking tokens) * Not available * $1.50 --- * Context caching price * Not available * *Same as Standard* \ $0.05 (text / image / video) \ $0.10 (audio) \ $1.00 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search{% sup %}*{% /sup %} * Not available{% sup %}**{% /sup %} * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Grounding with Google Maps * Not available{% sup %}**{% /sup %} * 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Priority" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $0.90 (text / image / video) \ $1.80 (audio) --- * Output price (including thinking tokens) * Free of charge * $5.40 --- * Context caching price * Free of charge * $0.09 (text / image / video) \ $0.18 (audio) \ $1.80 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search{% sup %}*{% /sup %} * Not available{% sup %}**{% /sup %} * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Grounding with Google Maps * Not available{% sup %}**{% /sup %} * 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% /tabs %} {% sup %}*{% /sup %} A customer-submitted request to Gemini may result in one or more queries to Google Search. You will be charged for each individual search query performed. {% sup %}**{% /sup %} Can be tested in Google AI Studio. ## Gemini 3 Pro Image (Nano Banana Pro) 🍌 {% id="gemini-3-pro-image" %} {% two-column-layout %} {% left-column class="center-vertically" %} *[`gemini-3-pro-image`](/docs/models/gemini-3-pro-image)* {% /left-column %} {% right-column class="center-vertically right-align" %} {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-3-pro-image" variant="ais" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} Our native image generation model, optimized for speed, flexibility, and contextual understanding. **Text input and output** is priced the same as [Gemini 3.1 Pro](/docs/pricing#gemini-3.1-pro-preview). {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $2.00 (text/image), \ equivalent to $0.0011 per image{% sup %}*{% /sup %} --- * Output price * Not available * $12.00 (text and thinking) \ $120.00 (images) \ Equivalent to $0.134 per 1K/2K image{% sup %}**{% /sup %} \ and $0.24 per 4K image{% sup %}**{% /sup %} --- * Grounding with Google Search{% sup %}***{% /sup %} * Not available{% sup %}****{% /sup %} * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Used to improve our products * N/A * [No](/docs/terms) {% /table %} {% /tab %} {% /tabs %} {% sup %}*{% /sup %} Image input is set at 560 tokens or $0.0011 per image. {% sup %}**{% /sup %} Image output is priced at $120 per 1,000,000 tokens. Output images from 1024x1024px (1K) and up to 2048x2048px (2K) consume 1120 tokens and are equivalent to $0.134 per image. Output images up to 4096x4096px (4K) consume 2000 tokens and are equivalent to $0.24 per image. {% sup %}***{% /sup %} A customer-submitted request to Gemini may result in one or more queries to Google Search. You will be charged for each individual search query performed. {% sup %}****{% /sup %} Can be tested in Google AI Studio. ## Gemini 2.5 Pro {% id="gemini-2.5-pro" %} *[`gemini-2.5-pro`](/docs/models/gemini-2.5-pro)* {% hr /%} {% callout type="caution" %} Gemini 2.5 Pro (`gemini-2.5-pro`) is [deprecated](/docs/deprecations#gemini-2.5-pro-models) and is no longer available to select in Google AI Studio. Effective December 1, 2026, all API requests to `gemini-2.5-pro` will automatically route to [Gemini 3.8 Flash (`gemini-3.8-flash`)](/docs/models/gemini-3.8-flash) and be billed at [Gemini 3.8 Flash rates](/docs/pricing#gemini-3.8-flash). {% /callout %} A Pro model which excels at coding and complex reasoning tasks. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $1.25, prompts <= 200k tokens \ $2.50, prompts > 200k tokens --- * Output price (including thinking tokens) * Free of charge * $10.00, prompts <= 200k tokens \ $15.00, prompts > 200k --- * Context caching price * Not available * $0.125, prompts <= 200k tokens \ $0.25, prompts > 200k \ $4.50 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search * Not available * 1,500 RPD (free), then $35 / 1,000 grounded prompts --- * Grounding with Google Maps * Not available * 10,000 RPD (free), then $25 / 1,000 grounded prompts --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Batch" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.625, prompts <= 200k tokens \ $1.25, prompts > 200k tokens --- * Output price (including thinking tokens) * Not available * $5.00, prompts <= 200k tokens \ $7.50, prompts > 200k --- * Context caching price * Not available * $0.125, prompts <= 200k tokens \ $0.25, prompts > 200k \ $4.50 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search * Not available * 1,500 RPD (free), then $35 / 1,000 grounded prompts --- * Grounding with Google Maps * Not available * Not available --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Flex" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.625, prompts <= 200k tokens \ $1.25, prompts > 200k tokens --- * Output price (including thinking tokens) * Not available * $5.00, prompts <= 200k tokens \ $7.50, prompts > 200k --- * Context caching price * Not available * $0.125, prompts <= 200k tokens \ $0.25, prompts > 200k \ $4.50 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search * Not available * 1,500 RPD (free), then $35 / 1,000 grounded prompts --- * Grounding with Google Maps * Not available * Not available --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Priority" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $2.25, prompts <= 200k tokens \ $4.50, prompts > 200k tokens --- * Output price (including thinking tokens) * Free of charge * $18.00, prompts <= 200k tokens \ $27.00, prompts > 200k --- * Context caching price * Not available * $0.225, prompts <= 200k tokens \ $0.45, prompts > 200k \ $8.10 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search * Not available * 1,500 RPD (free), then $35 / 1,000 grounded prompts --- * Grounding with Google Maps * Not available * 10,000 RPD (free), then $25 / 1,000 grounded prompts --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% /tabs %} ## Gemini 2.5 Flash {% id="gemini-2.5-flash" %} *[`gemini-2.5-flash`](/docs/models/gemini-2.5-flash)* {% hr /%} {% callout type="caution" %} Gemini 2.5 Flash (`gemini-2.5-flash`) is [deprecated](/docs/deprecations#gemini-2.5-flash-models) and is no longer available to select in Google AI Studio. Effective December 1, 2026, all API requests to `gemini-2.5-flash` will automatically route to [Gemini 3.5 Flash-Lite (`gemini-3.5-flash-lite`)](/docs/models/gemini-3.5-flash-lite) and be billed at [Gemini 3.5 Flash-Lite rates](/docs/pricing#gemini-3.5-flash-lite). {% /callout %} Our first hybrid reasoning model which supports a 1M token context window and has thinking budgets. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $0.30 (text / image / video) \ $1.00 (audio) --- * Output price (including thinking tokens) * Free of charge * $2.50 --- * Context caching price * Not available * $0.03 (text / image / video) \ $0.1 (audio) \ $1.00 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search * Free of charge, up to 500 RPD (limit shared with Flash-Lite RPD) * 1,500 RPD (free, limit shared with Flash-Lite RPD), then $35 / 1,000 grounded prompts --- * Grounding with Google Maps * 500 RPD * 1,500 RPD (free), then $25 / 1,000 grounded prompts --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Batch" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.15 (text / image / video) \ $0.50 (audio) --- * Output price (including thinking tokens) * Not available * $1.25 --- * Context caching price * Not available * $0.03 (text / image / video) \ $0.1 (audio) \ $1.00 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search * Not available * 1,500 RPD (free, limit shared with Flash-Lite RPD), then $35 / 1,000 grounded prompts --- * Grounding with Google Maps * Not available * Not available --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Flex" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.15 (text / image / video) \ $0.50 (audio) --- * Output price (including thinking tokens) * Not available * $1.25 --- * Context caching price * Not available * $0.03 (text / image / video) \ $0.1 (audio) \ $1.00 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search * Not available * 1,500 RPD (free, limit shared with Flash-Lite RPD), then $35 / 1,000 grounded prompts --- * Grounding with Google Maps * Not available * Not available --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Priority" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $0.54 (text / image / video) \ $1.80 (audio) --- * Output price (including thinking tokens) * Free of charge * $4.50 --- * Context caching price * Not available * $0.054 (text / image / video) \ $0.18 (audio) \ $1.80 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search * Free of charge, up to 500 RPD (limit shared with Flash-Lite RPD) * 1,500 RPD (free, limit shared with Flash-Lite RPD), then $35 / 1,000 grounded prompts --- * Grounding with Google Maps * 500 RPD * 1,500 RPD (free), then $25 / 1,000 grounded prompts --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% /tabs %} ## Gemini 2.5 Flash-Lite {% id="gemini-2.5-flash-lite" %} {% two-column-layout %} {% left-column class="center-vertically" %} *[`gemini-2.5-flash-lite`](/docs/models/gemini-2.5-flash-lite)* {% /left-column %} {% right-column class="center-vertically right-align" %} {% button href="https://aistudio.google.com?model=gemini-2.5-flash-lite" variant="ais" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} A small and cost effective model, built for at scale usage. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price (text, image, video) * Free of charge * $0.10 (text / image / video) \ $0.30 (audio) --- * Output price (including thinking tokens) * Free of charge * $0.40 --- * Context caching price * Not available * $0.01 (text / image / video) \ $0.03 (audio) \ $1.00 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search * Free of charge, up to 500 RPD (limit shared with Flash RPD) * 1,500 RPD (free, limit shared with Flash RPD), then $35 / 1,000 grounded prompts --- * Grounding with Google Maps * 500 RPD * 1,500 RPD (free), then $25 / 1,000 grounded prompts --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Batch" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price (text, image, video) * Not available * $0.05 (text / image / video) \ $0.15 (audio) --- * Output price (including thinking tokens) * Not available * $0.20 --- * Context caching price * Not available * $0.01 (text / image / video) \ $0.03 (audio) \ $1.00 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search * Not available * 1,500 RPD (free, limit shared with Flash RPD), then $35 / 1,000 grounded prompts --- * Grounding with Google Maps * Not available * Not available --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Flex" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price (text, image, video) * Not available * $0.05 (text / image / video) \ $0.15 (audio) --- * Output price (including thinking tokens) * Not available * $0.20 --- * Context caching price * Not available * $0.01 (text / image / video) \ $0.03 (audio) \ $1.00 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search * Not available * 1,500 RPD (free, limit shared with Flash RPD), then $35 / 1,000 grounded prompts --- * Grounding with Google Maps * Not available * Not available --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Priority" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price (text, image, video) * Free of charge * $0.18 (text / image / video) \ $0.54 (audio) --- * Output price (including thinking tokens) * Free of charge * $0.72 --- * Context caching price * Not available * $0.018 (text / image / video) \ $0.054 (audio) \ $1.80 / 1,000,000 tokens per hour (storage price) --- * Grounding with Google Search * Free of charge, up to 500 RPD (limit shared with Flash RPD) * 1,500 RPD (free, limit shared with Flash RPD), then $35 / 1,000 grounded prompts --- * Grounding with Google Maps * 500 RPD * 1,500 RPD (free), then $25 / 1,000 grounded prompts --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% /tabs %} ## Gemini 2.5 Flash Native Audio (Live API) {% id="gemini-2.5-flash-native-audio" %} {% two-column-layout %} {% left-column class="center-vertically" %} *[`gemini-2.5-flash-native-audio-preview-12-2025`](/docs/models/gemini-2.5-flash-native-audio-preview-12-2025)* {% /left-column %} {% right-column class="center-vertically right-align" %} {% button href="https://aistudio.google.com/app/live#gemini-2.5-flash-native-audio-preview-12-2025" variant="ais" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} Our [Live API](/docs/live-api) native audio models optimized for higher quality audio outputs with better pacing, voice naturalness, verbosity, and mood. {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $0.50 (text) \ $3.00 (audio / video) --- * Output price (including thinking tokens) * Free of charge * $2.00 (text) \ $12.00 (audio) --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} ## Gemini 2.5 Flash Image (Nano Banana) 🍌 {% id="gemini-2.5-flash-image" %} {% two-column-layout %} {% left-column class="center-vertically" %} *[`gemini-2.5-flash-image`](/docs/models/gemini-2.5-flash-image)* {% /left-column %} {% right-column class="center-vertically right-align" %} {% button href="https://aistudio.google.com?model=gemini-2.5-flash-image" variant="ais" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} {% callout type="warning" %} **Warning:** Gemini 2.5 Flash Image (`gemini-2.5-flash-image`) is [deprecated](/docs/deprecations) and will be shut down on March 15, 2027; migrate to [Gemini 3.1 Flash Lite Image](/docs/models/gemini-3.1-flash-lite-image) to avoid service disruption. {% /callout %} A native image generation model, optimized for speed, flexibility, and contextual understanding. Text input and output is priced the same as [2.5 Flash](/docs/pricing#gemini-2.5-flash). {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.30 (text / image) --- * Output price * Not available * $0.039 per image{% sup %}*{% /sup %} --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Batch" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.15 (text / image) --- * Output price * Not available * $0.0195 per image{% sup %}*{% /sup %} --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Flex" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.15 (text / image) --- * Output price * Not available * $0.0195 per image{% sup %}*{% /sup %} --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Priority" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.54 (text / image) --- * Output price * Not available * $0.0702 per image{% sup %}*{% /sup %} --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% /tabs %} {% sup %}*{% /sup %} Image output is priced at $30 per 1,000,000 tokens. Output images up to 1024x1024px consume 1290 tokens and are equivalent to $0.039 per image. ## Gemini 2.5 Flash Preview TTS {% id="gemini-2.5-flash-preview-tts" %} {% two-column-layout %} {% left-column class="center-vertically right-align" %} *[`gemini-2.5-flash-preview-tts`](/docs/models/gemini-2.5-flash-preview-tts)* {% /left-column %} {% right-column %} {% button href="https://aistudio.google.com/generate-speech" variant="ais" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} Our 2.5 Flash text-to-speech audio model optimized for price-performant, low-latency, controllable speech generation. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $0.50 (text) --- * Output price * Free of charge * $10.00 (audio) --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Batch" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.25 (text) --- * Output price * Not available * $5.00 (audio) --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% /tabs %} ## Gemini 2.5 Pro Preview TTS {% id="gemini-2.5-pro-preview-tts" %} {% two-column-layout %} {% left-column class="center-vertically right-align" %} *[`gemini-2.5-pro-preview-tts`](/docs/models/gemini-2.5-pro-preview-tts)* {% /left-column %} {% right-column %} {% button href="https://aistudio.google.com/generate-speech" variant="ais" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} Our 2.5 Pro text-to-speech audio model optimized for powerful, low-latency speech generation for more natural outputs and easier to steer prompts. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $1.00 (text) --- * Output price * Not available * $20.00 (audio) --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Batch" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.50 (text) --- * Output price * Not available * $10.00 (audio) --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% /tabs %} ## Lyria 3.5 {% id="lyria-3-5" %} *[`lyria-3.5`](/docs/models/lyria-3.5)* {% hr /%} Google's music generation model. {% table %} * Feature * Free Tier * Paid Tier, per request in USD --- * Lyria 3.5 (Full Song) * Not available * $0.08 per song --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} ## Lyria 3 {% id="lyria-3" %} *[`lyria-3-clip-preview`](/docs/models/lyria-3-clip-preview) and [`lyria-3-pro-preview`](/docs/models/lyria-3-pro-preview)* {% hr /%} Google's family of legacy music generation models. {% table %} * Feature * Free Tier * Paid Tier, per request in USD --- * Lyria 3 Clip Preview (30s) * Not available * $0.04 per song --- * Lyria 3 Pro Preview (Full Song) * Not available * $0.08 per song --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} ## Gemini Embedding 2 {% id="gemini-embedding-2" %} {% two-column-layout %} {% left-column class="center-vertically" %} *[`gemini-embedding-2`](/docs/models/gemini-embedding-2)* {% /left-column %} {% right-column class="center-vertically right-align" %} {% button href="/docs/embeddings" variant="ais" %} Try the API {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} Our first multimodal embedding model, mapping text, images, video, audio, and PDFs into a unified embedding space. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Text input price * Free of charge * $0.20 --- * Image input price * Free of charge * $0.45 ($0.00012 per image) --- * Audio input price * Free of charge * $6.50 ($0.00016 per second) --- * Video input price * Free of charge * $12.00 ($0.00079 per frame) --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Batch" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Text input price * Not available * $0.10 --- * Image input price * Not available * $0.225 ($0.00006 per image) --- * Audio input price * Not available * $3.25 ($0.00008 per second) --- * Video input price * Not available * $6.00 ($0.000395 per frame) --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% /tabs %} ## Gemini Embedding {% id="gemini-embedding" %} {% two-column-layout %} {% left-column class="center-vertically" %} *[`gemini-embedding-001`](/docs/models/gemini-embedding-001)* {% /left-column %} {% right-column class="center-vertically right-align" %} {% button href="/docs/embeddings" variant="ais" %} Try the API {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} Our first Gemini Embeddings model for text-only use cases. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $0.15 --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Batch" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.075 --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% /tabs %} ## Gemini Robotics ER 2 Preview {% id="gemini-robotics-er-2" %} {% two-column-layout %} {% left-column %} *[`gemini-robotics-er-2-preview`](/docs/models/gemini-robotics-er-2-preview)* {% /left-column %} {% right-column %} {% button href="https://aistudio.google.com?model=gemini-robotics-er-2-preview" variant="ais" class="right-align" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} Gemini Robotics ER 2, short for Gemini Robotics Embodied Reasoning 2, is a vision-language model endpoint that enables robots to understand their environments precisely, supporting agentic orchestration of robots, video progress understanding, multi-robot collaboration, and advanced spatial reasoning. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $1.00 (text / image / video / audio) through December 31, 2026. \\ $2.00 (text / image / video / audio) starting January 1, 2027. --- * Output price (including thinking tokens) * Free of charge * $5.00 through December 31, 2026. \\ $10.00 starting January 1, 2027. --- * Context caching price * Not available * $0.10 through December 31, 2026. \\ $0.20 starting January 1, 2027. \\ $0.50 / 1,000,000 tokens per hour (storage price) through December 31, 2026. \\ $1.00 / 1,000,000 tokens per hour (storage price) starting January 1, 2027. --- * Grounding with Google Search * Not available * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% tab title="Batch" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Not available * $0.50 (text / image / video / audio) through December 31, 2026. \\ $1.00 (text / image / video / audio) starting January 1, 2027. --- * Output price (including thinking tokens) * Not available * $2.50 through December 31, 2026. \\ $5.00 starting January 1, 2027. --- * Context caching price * Not available * $0.05 through December 31, 2026. \\ $0.10 starting January 1, 2027. \\ $0.50 / 1,000,000 tokens per hour (storage price) through December 31, 2026. \\ $1.00 / 1,000,000 tokens per hour (storage price) starting January 1, 2027. --- * Grounding with Google Search * Not available * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% /tabs %} ## Gemini Robotics ER 2 Streaming Preview {% id="gemini-robotics-er-2-streaming" %} {% two-column-layout %} {% left-column %} *[`gemini-robotics-er-2-streaming-preview`](/docs/models/gemini-robotics-er-2-streaming-preview)* {% /left-column %} {% right-column %} {% button href="https://aistudio.google.com?model=gemini-robotics-er-2-streaming-preview" variant="ais" class="right-align" %} Try it in Google AI Studio {% /button %} {% /right-column %} {% /two-column-layout %} {% hr /%} Gemini Robotics ER 2 Streaming is a vision-language model endpoint for robotics optimized for real-time text streaming using the Live API. It accepts text, image, video, and audio input and supports bidirectional streaming with function calling. {% tabs %} {% tab title="Standard" %} {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * $1.00 (text / image / video / audio) through December 31, 2026. \\ $2.00 (text / image / video / audio) starting January 1, 2027. --- * Output price * Free of charge * $5.00 through December 31, 2026. \\ $10.00 starting January 1, 2027. --- * Grounding with Google Search * Not available * 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests (subject to a [daily cap](/docs/pricing#pricing-for-tools) of 1,500 requests per day). --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} {% /tab %} {% /tabs %} ## [Gemma 4](https://ai.google.dev/gemma/docs/core/model_card_4) {% id="gemma-4" %} {% hr /%} Our lightweight, state-of the art, open model built from the same technology that powers our Gemini models. {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * Input price * Free of charge * Not available --- * Output price * Free of charge * Not available --- * Context caching price * Free of charge * Not available --- * Context caching (storage) * Free of charge * Not available --- * Tuning price * Not available * Not available --- * Grounding with Google Search * Not available * Not available --- * Used to improve our products * [Yes](/docs/terms) * [No](/docs/terms) {% /table %} ## Pricing for tools {% id="pricing-for-tools" %} Tools are priced at their own rates, applied to the model using them. Check the [Models](/docs/models) page for which tools are available to each model. {% table %} * Feature * Free Tier * Paid Tier, per 1M tokens in USD --- * [Google Search](/docs/google-search#pricing) * 500 RPD free (limit shared for Flash and Flash-Lite). \ Not available for Pro. * Gemini 2.5 models: \ 1,500 RPD free (limit shared for Flash and Flash-Lite). \ Then $35 / 1,000 grounded prompts \ Gemini 3 and newer models: \ 5,000 free search requests per month (shared across all Gemini 3 and newer models), then $14 per 1,000 requests. (Subject to a default daily cap of 1,500 requests per day (RPD) per project on the Gemini Developer API.) --- * [Google Maps](/docs/maps-grounding#pricing-and-rate-limits) * 500 RPD \ Not available for Pro. * Gemini 2.5 models: \ 1,500 RPD free (limit shared for Flash and Flash-Lite) \ 10,000 RPD free for Pro. \ Then $25 / 1,000 grounded prompts \ Gemini 3 and newer models: \ 5,000 requests per month (free, shared across all Gemini 3 and newer models), then $14 / 1,000 search queries. --- * [Code execution](/docs/code-execution#billing) * Free of charge * Code execution is billed at the standard token rates for the selected model. \ Costs are determined solely by tool usage; no charges accrue for session \ runtime. Generated code and execution results are billed as **Output \ tokens** when created, and as **Input tokens** when used by the model in \ its iterative reasoning process. --- * [URL context](/docs/url-context#limitations) * Free of charge * Charged as input tokens per model pricing. --- * [Computer use](/docs/computer-use) * Not available * Charged as regular tokens per model pricing (e.g., standard [Gemini 3.8 Flash](/docs/pricing#gemini-3.8-flash) pricing). --- * [File search](/docs/file-search#pricing) * Free of charge * Charged for embeddings at [Gemini Embedding](/docs/pricing#gemini-embedding) ($0.15 / 1M tokens) or [Gemini Embedding 2](/docs/pricing#gemini-embedding-2) rates. \ Retrieved document tokens charged as regular tokens per model pricing. --- * [Custom Tools endpoint (Gemini 3.1 Pro Preview)](/docs/models/gemini-3.1-pro-preview) * Not available * Same as [Gemini 3.1 Pro Preview](/docs/pricing#gemini-3.1-pro-preview) pricing {% /table %} ## Pricing for agents {% id="pricing-for-agents" %} Agent usage costs are calculated based on the underlying token consumption and usage of the tools. {% table %} * Feature * Model * Tools --- * [Gemini Deep Research agent](/docs/deep-research) * All model inference is charged at standard Gemini list rates, including input, \ output, and intermediate input / reasoning tokens generated during agentic \ loops. * Tool usage fees apply per existing pricing structure, maintaining standard \ distinctions for Search Grounding (retrieved tokens excluded) versus \ Url_context / File Search (retrieved tokens included in all other tools). --- * [Managed agents in Gemini API](/docs/agents) * All model inference is charged at standard Gemini list rates, including input, \ output, and intermediate input / reasoning tokens generated during agentic \ loops. (See [pricing details](/docs/agents#pricing)). * Environment compute (CPU, memory, sandbox execution) is not billed during the preview period. --- * [Antigravity Agent](/docs/antigravity-agent) * All model inference is charged at standard Gemini list rates, including input, \ output, and intermediate input / reasoning tokens generated during agentic \ loops. (See [pricing details](/docs/agents#pricing)). * Environment compute (CPU, memory, sandbox execution) is not billed during the \ preview period. {% /table %} ## Notes {% id="notes" %} * **Agentic video understanding:** When using agentic video understanding, token usage is variable based on the content loaded by the model rather than full video length. This typically results in up to 88% fewer input tokens for long-form video, though token counts depend on query complexity and dynamic sampling depth (which may exceed 1 FPS for detailed visual segments). See [Agentic video understanding](/docs/video-understanding#agentic-video-understanding). * **Document token billing:** Tokens for the `DOCUMENT` modality (for example, PDFs) are billed at the image token rate. In API responses, these tokens appear under the `DOCUMENT` modality within `promptTokensDetails`. * Google AI Studio usage is free of charge in all [available regions](/docs/available-regions). See [Billing FAQs](/docs/billing) for details. * Prices may differ from the prices listed here and the prices offered on Gemini Enterprise Agent Platform. For Gemini Enterprise Agent Platform prices, see the [Gemini Enterprise Agent Platform pricing page](https://cloud.google.com/products/gemini-enterprise-agent-platform). * If you are using [dynamic retrieval](/docs/google-search) to optimize costs, only requests that contain at least one grounding support URL from the web in their response are charged for Grounding with Google Search. Costs for Gemini always apply. Rate limits are subject to change. * **Search Grounding rate limits:** On the Gemini Developer API, Grounding with Google Search on Gemini 3 and newer models is subject to a default daily rate limit of 1,500 requests per day (RPD) per project across all paid tiers, resetting daily at midnight Pacific Time. For high-volume production workloads requiring higher daily limits, consider using [Vertex AI](https://cloud.google.com/vertex-ai/generative-ai/docs/grounding/grounding-with-google-search#considerations), which provides a default quota of 1,000,000 search queries per day. # Coding agent setup & developer resources Source: https://aistudio.google.com/docs/coding-agents Description: Use Gemini API skills, MCP tools, plugins, and machine-readable documentation to help your coding agent write accurate Gemini code. AI coding agents rely on training data that cuts off at a set date. Because of this, agents often suggest deprecated models (`gemini-1.5`), older SDKs (`google-generativeai`), or outdated code patterns. Connecting your agent to official Gemini developer resources helps it write accurate code using current models, the `google-genai` SDK, and the [Interactions API](/docs/interactions-overview). You can connect your coding agent to Gemini documentation, rules, and CLI tools in five ways: ## Summary of agent resources {% id="summary" %} | Resource | What it provides | Availability | | :--- | :--- | :--- | | **[Gemini Agent Skills](/docs/coding-agents#available-skills)** | Step-by-step rules, SDK patterns, and helper scripts for specific features (`gemini-api-dev`, `gemini-live-api-dev`, `gemini-omni-flash-api`). | Pre-installed in [AI Studio Build](https://ai.studio/build); install with `skills.sh`, Context7, or Managed Agents. | | **[Gemini Docs MCP Server](/docs/coding-agents#mcp-setup)** | Live search (`gemini_search_docs`) and full page reads (`gemini_get_doc`) across all documentation. | Supported in Claude Code, Cursor, OpenAI Codex, and VS Code. | | **[Gemini API Plugin](/docs/coding-agents#gemini-api-plugin)** | Bundled package with official Gemini skills, the Docs MCP server, and API key tools. | Antigravity. | | **[Machine-Readable Docs](/docs/coding-agents#machine-readable-docs)** | Clean Markdown pages, `llms.txt` indexes, and content negotiation headers. | All documentation pages on `aistudio.google.com/docs`. | | **[Gemini API CLI](/docs/cli)** | Stateless CLI (`gemini-api`) to generate media, analyze files, and run managed agents from the shell without writing SDK code. | Install on macOS, Linux, or Windows with the install script, Go, or prebuilt binaries. | ## Install Gemini agent skills {% id="available-skills" %} Agent skills give your coding agent procedural rules, current model names, and SDK code patterns. Instead of adding long instructions to your prompt, your agent loads each skill only when needed. This helps your agent avoid deprecated SDKs and use modern Gemini patterns. Skills work alongside the Gemini Docs MCP server. If your agent does not have the MCP server installed, the skill falls back to [`llms.txt`](https://aistudio.google.com/llms.txt). To learn more about how skills work, read the [Gemini API Skills guide](https://aistudio.google.com/learn/gemini-api-skills). {% callout type="note" %} Skills come pre-installed in [Google AI Studio Build](https://ai.studio/build) and are bundled in the [Gemini API plugin](/docs/coding-agents#gemini-api-plugin) for Antigravity. {% /callout %} ### Install with the CLI (`skills.sh` or Context7) {% id="install-skills-cli" %} Install skills using [skills.sh](https://skills.sh) (recommended) or [Context7](https://context7.com): ```bash # List all available skills in the repository npx skills add google-gemini/gemini-skills --list # Install a specific skill globally with skills.sh npx skills add google-gemini/gemini-skills --skill --global # Or install with Context7 npx ctx7 skills install /google-gemini/gemini-skills ``` ### Available skills {% id="skills-catalog" %} #### `gemini-api-dev` {% id="gemini-api-dev" %} Skill for building applications with the [Interactions API](/docs/interactions-overview) and the official Gemini API SDKs (`google-genai` for Python and `@google/genai` for TypeScript). This skill covers: - Text generation, multi-turn chat, streaming, structured outputs, and function calling - Image generation, text-to-speech (TTS), and multimodal inputs - Server-side conversation state management, background execution, Deep Research, and managed agents - Current model names and migrating legacy `generateContent` or `google-generativeai` code ```bash npx skills add google-gemini/gemini-skills --skill gemini-api-dev --global ``` #### `gemini-live-api-dev` {% id="gemini-live-api-dev" %} Skill for building real-time audio and video streaming applications with the [Gemini Live API](/docs/live-api). This skill covers: - WebSocket session management, ephemeral client tokens, and session resumption - Streaming audio, video, and text with voice activity detection (VAD) and barge-in support - Background reasoning (extended thinking), non-blocking asynchronous tool calls, transcription, and live speech translation ```bash npx skills add google-gemini/gemini-skills --skill gemini-live-api-dev --global ``` #### `gemini-omni-flash-api` {% id="gemini-omni-flash-api" %} Skill for generating and editing video with Gemini Omni Flash using the Interactions API. Includes helper scripts (`upload_file.py`, `generate_video.py`, `prep_video.py`, `inspect_video.py`) and covers: - Text-to-video generation and prompt crafting - First-and-last-frame transitions and reference-guided video generation - Video extensions and media preprocessing workflows ```bash npx skills add google-gemini/gemini-skills --skill gemini-omni-flash-api --global ``` ### Mount skills in Managed Agents {% id="managed-agents-skills" %} When you run remote managed agents with the Interactions API, you can mount the `google-gemini/gemini-skills` repository into the agent's workspace. See the [Gemini API Skills guide](https://aistudio.google.com/learn/gemini-api-skills) for details: ```python from google import genai client = genai.Client() interaction = client.interactions.create( agent="antigravity-preview-09-2026", input="Build a script that generates a 5-second video of a neon cityscape.", environment={ "type": "remote", "sources": [ { "type": "repository", "source": "https://github.com/google-gemini/gemini-skills", "target": ".agents", } ], }, ) ``` ## Connect the Gemini Docs MCP server {% id="mcp-setup" %} The public **Gemini Docs MCP server** (`https://gemini-api-docs-mcp.dev`) gives your agent live access to the entire documentation site. Your agent can search and read documentation pages to check request schemas, model limits, and new features: - `gemini_search_docs`: Searches Gemini API documentation by topic or query. - `gemini_get_doc`: Reads the full Markdown content of a specific documentation page. ### Quick setup {% id="mcp-quick-setup" %} Run this command in your terminal or project root to configure your detected coding agents automatically: ```bash npx add-mcp "https://gemini-api-docs-mcp.dev" ``` ### Configuration by environment {% id="mcp-by-environment" %} {% tabs %} {% tab label="Claude Code" %} Run in your terminal: ```bash $ claude mcp add --transport http geminiDocs https://gemini-api-docs-mcp.dev ``` {% /tab %} {% tab label="Cursor" %} Add to `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (project): ```json { "mcpServers": { "geminiDocs": { "url": "https://gemini-api-docs-mcp.dev" } } } ``` {% /tab %} {% tab label="OpenAI Codex" %} Run in your terminal: ```bash $ codex mcp add geminiDocs --url https://gemini-api-docs-mcp.dev ``` Or add to `~/.codex/config.toml`: ```toml [mcp_servers.geminiDocs] url = "https://gemini-api-docs-mcp.dev" ``` {% /tab %} {% tab label="VS Code (Copilot)" %} Add to `.vscode/mcp.json` in your workspace: ```json { "servers": { "geminiDocs": { "type": "http", "url": "https://gemini-api-docs-mcp.dev" } } } ``` {% /tab %} {% /tabs %} ## Gemini API plugin {% id="gemini-api-plugin" %} If you use **Antigravity**, the **Gemini API plugin** is the fastest way to set up your workspace. It bundles the Gemini Docs MCP server, all official Gemini skills (`gemini-api-dev`, `gemini-live-api-dev`, `gemini-omni-flash-api`), and API key tools in one download. - **Install in Antigravity (UI):** Go to **Settings > Customizations > Build with Google Plugins** and download **Gemini API**. - **Install with the CLI:** ```bash agy plugin install https://github.com/google-gemini/gemini-skills ``` ## Machine-readable documentation {% id="machine-readable-docs" %} Standard web pages include HTML tags, navigation bars, and scripts that take up context window space. AI Studio serves documentation as clean Markdown to save tokens and help agents read documentation directly. ### How to access Markdown {% id="markdown-access-methods" %} | Method | How to use | Why use it | | :--- | :--- | :--- | | **Accept header (content negotiation)** | Send `Accept: text/markdown` on any `/docs/...` URL | Gets raw Markdown from the same URL you visit in a browser without changing the path. | | **Direct `.md` URLs** | Add `.md` to any doc URL (such as `/docs/coding-agents.md`) | Gives you a clean Markdown link to share in prompts, `AGENTS.md` files, or scripts. | | **`llms.txt` index** | [`https://aistudio.google.com/llms.txt`](https://aistudio.google.com/llms.txt) | Lists every documentation page with links to each raw Markdown file. | | **`llms-full.txt` file** | [`https://aistudio.google.com/llms-full.txt`](https://aistudio.google.com/llms-full.txt) | Combines all Gemini API documentation pages into a single file for full context loading. | | **Discovery headers** | Included on all `/docs` HTTP responses | Sets `Link` and `X-Llms-Txt` headers, and adds an `AI Agent Context` block to Markdown pages to point agents to the documentation indexes. | To fetch Markdown from any documentation URL using the `Accept` header: ```bash curl --header "Accept: text/markdown" https://aistudio.google.com/docs/interactions-overview ``` You can also click **Copy page** at the top of any documentation page to copy the Markdown source to your clipboard. ## Recommended project rules (`AGENTS.md`) {% id="project-rules" %} A project rules file (`AGENTS.md`, `.cursorrules`, or `CLAUDE.md`) sets baseline rules that load at the start of every agent session. Add these guidelines to your project root so coding agents default to current models and SDKs: ```markdown # Gemini API Guidelines - Before writing Gemini API code, consult the `geminiDocs` MCP server (`gemini_search_docs` / `gemini_get_doc`) or `https://aistudio.google.com/llms.txt`. - Always use the current Google Gen AI SDK (`google-genai` for Python, `@google/genai` for TypeScript/JavaScript). Never use legacy SDKs (`google-generativeai` or `@google/generative-ai`). - Use the Interactions API (`client.interactions.create`) for new applications unless a specific feature requires `generateContent`. - Use current recommended models (see https://aistudio.google.com/docs/models) and avoid deprecated models. ``` ## Verify and troubleshoot {% id="verification-troubleshooting" %} ### Verify your setup {% id="verify-setup" %} To test your setup, ask your coding agent: ```none Look up the request schema for the Gemini Interactions API in the documentation. ``` A configured agent will use `gemini_search_docs` on the `geminiDocs` MCP server and write code using `client.interactions.create` with the `google-genai` or `@google/genai` SDK. ### Status commands {% id="status-commands" %} | Environment | MCP verification | Skills verification | | :--- | :--- | :--- | | **Claude Code** | Run `/mcp` | Run `/skills` | | **Cursor** | Open **Settings > Features > MCP** | Open **Settings > Rules** | | **OpenAI Codex** | Run `codex mcp list` | Check `.codex/skills/` or `~/.codex/skills/` | | **Antigravity** | Open **Customizations > Connections** | Open **Customizations > Rules** or run `/skills list` | | **VS Code (Copilot)** | Open **Extensions > MCP** or Output panel | Click **Select Tools** in Copilot Chat | ### Troubleshooting {% id="troubleshooting" %} - **Skill or MCP server not detected:** Restart your editor (Cursor or VS Code) or terminal session (Claude Code or Codex). Most agents load MCP servers and skills only when they start. - **Global skill conflict:** If your agent ignores a globally installed skill, install the skill in your project root without `--global`: ```bash npx skills add google-gemini/gemini-skills --skill gemini-api-dev ``` - **Rules ignored:** Make sure your `AGENTS.md`, `.cursorrules`, or `CLAUDE.md` file is in the root directory of your project. ## What's next {% id="whats-next" %} - [Gemini API CLI](/docs/cli) - [Gemini API Skills guide](https://aistudio.google.com/learn/gemini-api-skills) - [Gemini API skills on GitHub](https://github.com/google-gemini/gemini-skills) - [Interactions API](/docs/interactions-overview) - [Available models](/docs/models) - [Libraries and SDKs](/docs/libraries) # Gemini API CLI Source: https://aistudio.google.com/docs/cli Description: Give coding agents, shell scripts, and CI pipelines a stateless CLI to generate text and media, analyze files, and run Gemini managed agents. The Gemini API CLI (`gemini-api`) is a stateless, zero-dependency command-line client built for AI agents with shell access, scripts, and CI pipelines. Your coding agent can use it to generate text and media, analyze files, and delegate tasks to [Gemini managed agents](/docs/agents). It works with Antigravity, Claude Code, Cursor, and any standard shell environment. Every feature runs as a standard shell command on the [Interactions API](/docs/interactions-overview). Run the same commands from an agent subprocess, your terminal, or a CI pipeline: ```bash # 1. Install on macOS or Linux curl -fsSL https://raw.githubusercontent.com/google-gemini/gemini-api-cli/main/scripts/install.sh | bash # 2. Set your API key export GEMINI_API_KEY="YOUR_API_KEY" # 3. Generate media, analyze a file, or launch a background managed agent gemini-api image "Minimalist isometric icon of a cloud database" --out ./assets/db-icon.jpg gemini-api analyze -i ./docs/quarterly-report.pdf "Summarize the key findings in three bullets." gemini-api agent run "Compare WebRTC SFU architectures and cite sources" \ --agent deep-research-preview-04-2026 \ --background \ --stream=false ``` {% callout type="note" %} `gemini-api` is an open-source beta release that evolves alongside the [Interactions API](/docs/interactions-overview). Breaking changes can occur between minor versions. Pin a specific [release version](https://github.com/google-gemini/gemini-api-cli/releases) in automated agent environments and CI pipelines. {% /callout %} ## How it works {% id="how-it-works" %} Raw REST calls and interactive CLIs often cause issues for coding agents. Base64 media fills the context window, interactive prompts block subprocesses, and stale training data causes hallucinated flags. Four design choices keep `gemini-api` reliable for agents: - **Offline schema lookup:** Pass `--usage` to print the command tree (in [KDL](https://kdl.dev)), or `--schema` to print the JSON Schema for `--body` requests. - **Files on disk, paths on `stdout`:** Media and transcription commands write files to disk and print only the output path, keeping binary data out of context. - **Dry runs and structured output:** `--dry-run` validates inputs, redacts credentials, and previews the HTTP request offline. Pass `-o json`, `-o toon`, or `--jq` for machine-readable output. Add `--agent-mode` to return structured JSON errors on `stderr`, and check [exit codes](/docs/cli#exit-codes) to handle failures. Commands never prompt unless you pass `--interactive`. - **Stateless by default:** Commands keep no hidden local state. Chain multi-step work explicitly with `--previous-interaction-id`, an uploaded `files/` URI, or a background interaction ID. With `-o json`, media commands still write the file to disk and print metadata to `stdout`: ```json { "kind": "image", "mime_type": "image/jpeg", "path": "/path/to/project/assets/db-icon.jpg", "response_id": "v1_...", "size_bytes": 2914159, "status": "completed" } ``` ## Get started {% id="get-started" %} Install the CLI, put `gemini-api` on your `PATH`, set `GEMINI_API_KEY`, and add usage rules to your coding agent. ### 1. Install the binary {% id="install" %} {% tabs %} {% tab label="macOS and Linux" %} ```bash curl -fsSL https://raw.githubusercontent.com/google-gemini/gemini-api-cli/main/scripts/install.sh | bash ``` To install a specific release, set `GEMINI_VERSION` to a release tag: ```bash curl -fsSL https://raw.githubusercontent.com/google-gemini/gemini-api-cli/main/scripts/install.sh | GEMINI_VERSION= bash ``` {% /tab %} {% tab label="Windows (PowerShell)" %} ```bash iwr -useb https://raw.githubusercontent.com/google-gemini/gemini-api-cli/main/scripts/install.ps1 | iex ``` {% /tab %} {% tab label="Go" %} ```bash go install github.com/google-gemini/gemini-api-cli/cmd/gemini-api@latest ``` {% /tab %} {% tab label="Prebuilt binaries" %} Download versioned archives for macOS, Linux, and Windows from [GitHub Releases](https://github.com/google-gemini/gemini-api-cli/releases) and place `gemini-api` on your `PATH`. Use prebuilt archives to pin exact versions in Docker images and CI. {% /tab %} {% /tabs %} ### 2. Configure authentication and verify {% id="authentication" %} Create an API key in [Google AI Studio](https://aistudio.google.com/apikey) (see [API keys](/docs/api-key)). Set `GEMINI_API_KEY` in your shell and your agent's subprocess environment: ```bash export GEMINI_API_KEY="YOUR_API_KEY" ``` On a local workstation, you can save the key in your OS keychain (macOS Keychain, Linux Secret Service, or Windows Credential Manager). Pass `--no-keyring` to store the key in `~/.config/gemini-api/config.yaml` instead: ```bash # Save to your OS keychain (or run gemini-api configure --interactive) gemini-api configure --api-key "YOUR_API_KEY" # Check the active credential source, then preview a request offline gemini-api whoami gemini-api generate "Confirm CLI setup in one sentence." --dry-run ``` {% callout type="warning" %} Treat `GEMINI_API_KEY` as a secret. In CI, inject the key from your secret store instead of committing it to a repository or build file. {% /callout %} ### 3. Give your agent instructions {% id="agent-instructions" %} Add this snippet to your project's `AGENTS.md`, `CLAUDE.md`, `.cursorrules`, or system prompt so your coding agent knows how to use `gemini-api`: ```markdown ## Gemini API CLI (`gemini-api`) You have access to `gemini-api` through the shell. Use it to generate text or media (images, speech, music, video), analyze documents and recordings, or run and manage Gemini managed agents. 1. Run `gemini-api --help` or `gemini-api --usage` to choose a command, and `gemini-api --schema` before building a `--body` JSON payload. 2. Preview unfamiliar or complex calls offline with `--dry-run -o json`. 3. For a single JSON result or `--jq` filtering on `generate` or `agent run`, pass `--stream=false -o json`. 4. To chain multi-step workflows, capture the output paths that media and transcription commands print to stdout, and the `id` values returned by `generate` or `agent run`. ``` Then prompt your coding agent as usual: ```none Build a landing page for our developer tool. Use Gemini to generate a hero illustration and a 15-second welcome voiceover, and start a background Deep Research agent to compare competing CLI onboarding flows. Wire the assets and findings into the page. ``` ## Commands {% id="commands" %} Run `gemini-api --help` to list all commands, or `gemini-api explore` to browse them interactively. | Group | Command | What it does | | :--- | :--- | :--- | | Create | `image` | Generates or edits images (`-i`), writes a JPEG file, and prints its path. | | Create | `tts` | Synthesizes 24 kHz mono WAV speech (one or two speakers) and prints the output path. | | Create | `music` | Generates music tracks or loops, writes the audio file, and prints its path. | | Create | `video` | Generates or edits MP4 clips and waits until done (`--async` returns an ID immediately). | | Create | `generate` | Generates text and streams it to `stdout` (`--stream=false` returns one complete result). | | Understand | `analyze` | Answers questions about PDFs, images, audio, video, CSV and text files, or public YouTube URLs. | | Understand | `transcribe` | Writes speaker-labeled, timestamped transcripts (`md`, `text`, `json`, or `srt`) and prints the output paths. | | Manage agents | `agent` | Runs managed agents (`run`, `status`, `cancel`, `delete-interaction`) and manages custom agent definitions (`create`, `list`, `get`, `delete`). | | Manage agents | `environments`, `credentials`, `webhooks`, `triggers` | Configures sandbox environments, stored credentials, webhook delivery, and scheduled runs for managed agents. | | Setup and files | `configure`, `auth`, `whoami` | Configures credentials and defaults, and shows the active auth state. | | Setup and files | `files` | Uploads, lists, inspects, and deletes files in the Files API. | | Setup and files | `models` | Lists available models. | ## Workflows {% id="workflows" %} Each command defaults to a model suited for its task. Pass `--model` (`-m`) to pick a different model. Run `gemini-api models` to list available options. ### Image generation and editing {% id="image" %} Agents building web or mobile UIs can generate placeholders, icons, and hero images with [Nano Banana](/docs/image-generation). Pass a generated path back in with `-i` to edit the image: ```bash # Generate a 16:9 image at 2K resolution (512, 1K, 2K, or 4K) and capture its path HERO_PATH=$(gemini-api image "Friendly robot mascot in a sunlit workshop, space on left for headline" \ --aspect-ratio 16:9 \ --image-size 2K \ --out ./public/images/hero.jpg) # Edit the generated image gemini-api image "Add a winter scarf and soft snowfall outside the window" \ -i "$HERO_PATH" \ --out ./public/images/hero-winter.jpg ``` Pass `-i` multiple times to combine reference images, such as a character and a style guide. ### Speech synthesis {% id="tts" %} `gemini-api tts` synthesizes 24 kHz WAV audio for UI cues, accessibility previews, and narrated walkthroughs. The default voice is `Kore`; choose another with `--voice`. For two-speaker dialogue, label each turn in the prompt and map speakers to voices: ```bash gemini-api tts "Build succeeded. All integration tests passed." \ --voice Aoede \ --out ./public/audio/build-ok.wav gemini-api tts "Alice: Welcome to the release walkthrough! Bob: Let's look at what shipped today." \ --multi-speaker "Alice=Kore,Bob=Puck" \ --out ./public/audio/release-intro.wav ``` ### Music and video {% id="music-video" %} Compose original tracks with [Lyria](/docs/music-generation), and generate MP4 clips with [Gemini Omni](/docs/video): ```bash gemini-api music "Warm ambient synth and acoustic guitar background loop, 95 BPM" \ --out ./public/audio/bg-loop.mp3 gemini-api video "A drone shot of a mountain landscape at sunrise." \ --aspect-ratio 16:9 \ --resolution 1080p \ --out ./public/video/mountain-sunrise.mp4 ``` By default, the `video` command waits for generation to finish and writes the MP4 file to disk. Pass `--async` to return an interaction ID immediately, then run `gemini-api video --resume --out ` later. Pass `-i` to animate an existing image. ### Text generation {% id="generate" %} `gemini-api generate` streams text to `stdout`: ```bash gemini-api generate "Write a one-paragraph welcome message for new users of a note-taking app." ``` Add `--stdin` to pipe text into the prompt. Pass `--previous-interaction-id` to continue an earlier interaction. ### Document analysis and transcription {% id="analyze" %} `analyze` answers questions about PDFs, spreadsheets, screenshots, audio and video files, and public YouTube URLs. `transcribe` writes a formatted transcript (`md`, `text`, `json`, or `srt`) to disk: ```bash gemini-api analyze -i ./docs/product-brief.pdf "List the open questions and who owns each one." > open-questions.md gemini-api transcribe -i ./fixtures/customer-call.mp4 --format srt --out ./fixtures/customer-call.srt ``` Pass `-i` multiple times to `analyze` to compare files, such as before-and-after screenshots. `gemini-api` sends local files inline up to 14 MB (20 MB after base64 encoding). For larger files, upload once with `files upload --wait` and reuse the returned `files/` URI: ```bash FILE_URI=$(gemini-api files upload ./recordings/all-hands.mp4 --wait) gemini-api analyze -i "$FILE_URI" "List action items with owners and timestamps." gemini-api transcribe -i "$FILE_URI" --format json --out ./recordings/all-hands.json ``` ### Run and manage agents {% id="managed-agents" %} Your coding agent can delegate multi-step research or sandboxed tasks to [Gemini managed agents](/docs/agents), such as the [Deep Research agent](/docs/deep-research). Pass `--background --stream=false` to get an interaction ID immediately instead of holding a stream open: ```bash # Launch a Deep Research job in the background and capture its interaction ID RESEARCH_ID=$(gemini-api agent run "Compare open-source vector index benchmarks and cite primary papers." \ --agent deep-research-preview-04-2026 \ --background \ --stream=false \ --jq '.id') # Check status or fetch the finished result while continuing other work gemini-api agent status "$RESEARCH_ID" -o json ``` Run `gemini-api agent cancel ` to stop a running job. You can also launch the [Antigravity agent](/docs/antigravity-agent) in a remote sandbox with `agent run`, or manage [custom agents](/docs/custom-agents) with `agent create`, `list`, `get`, and `delete`. See [Environments](/docs/agent-environment) to configure agent sandboxes. ## Custom request bodies {% id="custom-bodies" %} For options without dedicated flags, pass a raw [Interactions API](/docs/interactions-overview) JSON payload with `--body` (inline or as `@file.json`). Pass `--body` to set `response_format` schemas, function-calling tools, `generation_config`, or `"store": false`. Run `gemini-api --schema` first to check valid fields: ```bash # Inspect the JSON Schema for the request body gemini-api generate --schema > generate-schema.json # Return schema-constrained JSON and skip storing the interaction cat logs.txt | gemini-api generate "Extract every error message from these logs." \ --stdin \ --body '{ "response_format": { "type": "text", "mime_type": "application/json", "schema": { "type": "object", "properties": {"errors": {"type": "array", "items": {"type": "string"}}}, "required": ["errors"] } }, "store": false }' ``` `--body` merges with command flags. If both set the same key, the command fails with exit code `2` so conflicting inputs fail fast. ## Exit codes {% id="exit-codes" %} Every command returns a typed exit code so scripts and agents can handle failures without parsing error text. For example, `3` signals an authentication problem and `2` signals invalid command syntax: | Code | Meaning | | :--- | :--- | | `0` | The command succeeded. | | `1` | Runtime or API error, such as a network failure, rate limit, or failed background job. | | `2` | Usage or validation error, such as an unknown flag, missing input, or duplicate `--body` key. | | `3` | Authentication or authorization failure, such as a missing or invalid API key or token. | Run `gemini-api --help-global` to list global flags shared by every command (authentication, output, network, and diagnostics). ## Limitations {% id="limitations" %} - Streaming commands (`generate` and `agent run`) require `--stream=false` when combined with `-o json` or `--jq` to return a single JSON response object. - Inline `-i` file inputs cap at 14 MB of raw file data (20 MB request payload including base64 encoding). Upload large files with `gemini-api files upload`. The Files API deletes uploaded files after 48 hours. - `gemini-api` supports standard HTTP requests, SSE streaming, and async polling, not bidirectional WebSockets. For real-time voice and video streaming, use the [Live API](/docs/live-api) with the [Google GenAI SDKs](/docs/libraries). ## What's next {% id="whats-next" %} - [Coding agent setup](/docs/coding-agents) - [Interactions API](/docs/interactions-overview) - [Gemini managed agents](/docs/agents) - [gemini-api-cli on GitHub](https://github.com/google-gemini/gemini-api-cli) # Models Source: https://aistudio.google.com/docs/models Description: Learn about all of Google's most advanced AI models ## Gemini 4 {% id="gemini-4" %} {% card-grid columns="2" %} {% card title="Gemini 4 Argon" description="Our flagship reasoning model with a shared 1M context window and long decodes up to 1M tokens." variant="model-card" %} {% section class="model-specs" %} * *Model code* **gemini-4-argon** * *Context* **1M tokens** * *Max output* **65K / 1M tokens** * *Modalities* **Text, Image, Audio, Video, PDF** {% /section %} {% section class="card-actions" %} {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-4-argon" variant="primary" %}Try in AI Studio{% /button %} {% button href="/docs/models/gemini-4-argon" variant="icon-primary" icon="arrow_forward" tooltip="View models" %}{% /button %} {% /section %} {% /card %} {% /card-grid %} ## All Gemini 4 models {% id="all-gemini-4-models" %} {% table variant="model" %} * Model * Endpoint --- * [Gemini 4 Argon](/docs/models/gemini-4-argon) * `gemini-4-argon` {% /table %} ## Gemini 3 {% id="gemini-3" %} {% card-grid %} {% card href="/docs/models/gemini-3.8-flash" title="Gemini 3.8 Flash" description="Our most intelligent Flash model, engineered for long-horizon software engineering, autonomous agents, and complex enterprise workflows." badge="New" icon="spark" variant="model" %} {% /card %} {% card href="/docs/models/gemini-3.8-live" title="Gemini 3.8 Live" description="Default Live API model for most low-latency voice agent experiences without reasoning delays." badge="New" icon="settings_voice" variant="model" %} {% /card %} {% card href="/docs/models/gemini-3.8-live-extended-thinking" title="Gemini 3.8 Live Extended Thinking" description="High-reasoning Live API model for voice interactions, recommended when higher background reasoning is required." badge="New" icon="psychology" variant="model" %} {% /card %} {% card href="/docs/models/gemini-3.8-flash-tts" title="Gemini 3.8 Flash TTS" description="Flagship creative text-to-speech model for studio-grade voice fidelity, expressive acting, Voice design, and Voice replication." badge="New" icon="graphic_eq" variant="model" %} {% /card %} {% card href="/docs/models/gemini-3.8-flash-lite-tts" title="Gemini 3.8 Flash-Lite TTS" description="Fast, cost-efficient text-to-speech model for high-volume production, real-time voice agent cascades, and Voice replication." badge="New" icon="graphic_eq" variant="model" %} {% /card %} {% card href="/docs/models/gemini-3.6-flash" title="Gemini 3.6 Flash" description="Our previous-generation Flash model, balancing speed and multimodal capabilities across general agentic and everyday tasks." badge="Stable" icon="spark" variant="model" %} {% /card %} {% card href="/docs/models/gemini-3.5-flash-lite" title="Gemini 3.5 Flash-Lite" description="Our fastest, most cost-effective 3.5 model for high-throughput execution." badge="Stable" icon="bolt" variant="model" %} {% /card %} {% card href="/docs/models/gemini-3.1-flash-lite" title="Gemini 3.1 Flash-Lite" description="Frontier-class performance rivaling larger models at a fraction of the cost." badge="Stable" icon="bolt" variant="model" %} {% /card %} {% card href="/docs/models/gemini-nano-banana-2.1" title="Nano Banana 2.1" description="High-efficiency image generation and editing model with improved visual quality, typography, and multi-turn consistency." badge="New" icon="banana_spark" variant="model" %} {% /card %} {% card href="/docs/models/gemini-3.1-flash-image" title="Nano Banana 2" description="Powerful, high-efficiency image generation and editing, optimized for speed and high-volume use cases." badge="Stable" icon="banana_spark" variant="model" %} {% /card %} {% card href="/docs/models/gemini-3.1-flash-lite-image" title="Nano Banana 2 Lite" description="Ultra-low latency and cost-effective image generation and editing, designed for high-volume interactive use cases." badge="Stable" icon="banana_spark" variant="model" %} {% /card %} {% card href="/docs/models/gemini-3-pro-image" title="Nano Banana Pro" description="State-of-the-art image generation and editing models for highly contextual native image creation." badge="Stable" icon="banana_spark" variant="model" %} {% /card %} {% card href="/docs/models/gemini-3.5-transcribe" title="Gemini 3.5 Transcribe" description="Low-latency speech-to-text model with utterance-based language detection, speaker diarization, and word timestamps." badge="Stable" icon="speech_to_text" variant="model" %} {% /card %} {% card href="/docs/models/gemini-omni-flash" title="Gemini Omni Flash" description="Fast video generation, editing, keyframe interpolation, and extension with native audio." badge="Stable" icon="movie_filter" variant="model" %} {% /card %} {% card href="/docs/models/gemini-3-flash-preview" title="Gemini 3 Flash" description="Frontier-class performance rivaling larger models at a fraction of the cost." badge="Preview" icon="spark" variant="model" %} {% /card %} {% card href="/docs/models/gemini-3.5-live-translate-preview" title="Gemini 3.5 Live Translate" description="Low-latency, real-time speech to speech translation model that supports 70+ languages." badge="Preview" icon="translate" variant="model" %} {% /card %} {% card href="/docs/models/gemini-3.1-flash-live-preview" title="Gemini 3.1 Flash Live" description="Legacy Live API preview model. We recommend updating to Gemini 3.8 Live." badge="Preview" icon="settings_voice" variant="model" %} {% /card %} {% card href="/docs/models/gemini-3.1-flash-tts-preview" title="Gemini 3.1 Flash TTS" description="Legacy TTS preview model. We recommend updating to Gemini 3.8 Flash TTS or Gemini 3.8 Flash-Lite TTS." badge="Preview" icon="graphic_eq" variant="model" %} {% /card %} {% /card-grid %} ## All Gemini 3 models {% id="all-gemini-3-models" %} {% table variant="model" %} * Model * Endpoint --- * [Gemini 3.8 Flash](/docs/models/gemini-3.8-flash) * `gemini-3.8-flash` --- * [Gemini 3.8 Live](/docs/models/gemini-3.8-live) * `gemini-3.8-live` --- * [Gemini 3.8 Live Extended Thinking](/docs/models/gemini-3.8-live-extended-thinking) * `gemini-3.8-live-extended-thinking` --- * [Gemini 3.8 Flash TTS](/docs/models/gemini-3.8-flash-tts) * `gemini-3.8-flash-tts` --- * [Gemini 3.8 Flash-Lite TTS](/docs/models/gemini-3.8-flash-lite-tts) * `gemini-3.8-flash-lite-tts` --- * [Gemini 3.6 Flash](/docs/models/gemini-3.6-flash) * `gemini-3.6-flash` --- * [Gemini 3.5 Flash-Lite](/docs/models/gemini-3.5-flash-lite) * `gemini-3.5-flash-lite` --- * [Gemini 3.1 Flash-Lite](/docs/models/gemini-3.1-flash-lite) * `gemini-3.1-flash-lite` --- * [Nano Banana 2.1](/docs/models/gemini-nano-banana-2.1) * `gemini-nano-banana-2.1` --- * [Nano Banana 2](/docs/models/gemini-3.1-flash-image) * `gemini-3.1-flash-image` --- * [Nano Banana 2 Lite](/docs/models/gemini-3.1-flash-lite-image) * `gemini-3.1-flash-lite-image` --- * [Nano Banana Pro](/docs/models/gemini-3-pro-image) * `gemini-3-pro-image` --- * [Gemini 3.5 Transcribe](/docs/models/gemini-3.5-transcribe) * `gemini-3.5-transcribe` \ `gemini-3.5-transcribe-live` --- * [Gemini Omni Flash](/docs/models/gemini-omni-flash) * `gemini-omni-1.1-flash` --- * [Gemini 3.1 Pro](/docs/models/gemini-3.1-pro-preview) * `gemini-3.1-pro-preview` --- * [Gemini 3 Flash](/docs/models/gemini-3-flash-preview) * `gemini-3-flash-preview` --- * [Gemini 3.5 Live Translate](/docs/models/gemini-3.5-live-translate-preview) * `gemini-3.5-live-translate-preview` --- * [Gemini 3.1 Flash Live](/docs/models/gemini-3.1-flash-live-preview) * `gemini-3.1-flash-live-preview` --- * [Gemini 3.1 Flash TTS](/docs/models/gemini-3.1-flash-tts-preview) * `gemini-3.1-flash-tts-preview` {% /table %} ## Gemini 2.5 Flash {% id="gemini-25-flash" %} {% callout type="caution" %} `gemini-2.5-flash` is [deprecated](/docs/deprecations#gemini-2.5-flash-models) and is no longer available to select in Google AI Studio (API access to the 2.5 models is limited to existing users). Effective December 1, 2026, all API requests to `gemini-2.5-flash` will automatically route to [`gemini-3.5-flash-lite`](/docs/models/gemini-3.5-flash-lite). Update your model string to `gemini-3.5-flash-lite` and review the [Gemini 3.5 Flash-Lite migration guide](/docs/whats-new-gemini-3.6#migrate-to-gemini-3-5-flash-lite) before December 1, 2026. {% /callout %} {% table variant="model" %} * Model * Description * Endpoint --- * [Gemini 2.5 Flash](/docs/models/gemini-2.5-flash) * Our best price-performance model for low-latency, high-volume tasks that require reasoning. * `gemini-2.5-flash` --- * [Nano Banana](/docs/models/gemini-2.5-flash-image) * State-of-the-art native image generation and editing designed for fast, creative workflows. * `gemini-2.5-flash-image` --- * [Gemini 2.5 Flash Live](/docs/models/gemini-2.5-flash-native-audio-preview-12-2025) * Optimized for real-time conversational agents with sub-second native audio streaming. * `gemini-2.5-flash-native-audio-preview-12-2025` --- * [Gemini 2.5 Flash TTS](/docs/models/gemini-2.5-flash-preview-tts) * Controllable text-to-speech audio generation with fine control over style and pacing. * `gemini-2.5-flash-preview-tts` {% /table %} ## Gemini 2.5 Flash-Lite {% id="gemini-25-flash-lite" %} {% callout type="note" %} To ensure reliable performance for everyone, we are limiting access to the 2.5 models to users who have actively used them in the past. `gemini-2.5-flash-lite` is not deprecated and will continue to be served until further notice through the API. For any new projects, use our latest models: 3.5 Flash-Lite or 3.8 Flash. This helps us maintain sufficient capacity for both ongoing legacy workflows and new applications. {% /callout %} {% table variant="model" %} * Model * Description * Endpoint --- * [Gemini 2.5 Flash-Lite](/docs/models/gemini-2.5-flash-lite) * The fastest and most budget-friendly multimodal model in the 2.5 family. * `gemini-2.5-flash-lite` {% /table %} ## Gemini 2.5 Pro {% id="gemini-25-pro" %} {% callout type="caution" %} `gemini-2.5-pro` is [deprecated](/docs/deprecations#gemini-2.5-pro-models) and is no longer available to select in Google AI Studio (API access to the 2.5 models is limited to existing users). Effective December 1, 2026, all API requests to `gemini-2.5-pro` will automatically route to [`gemini-3.8-flash`](/docs/models/gemini-3.8-flash). Update your model string to `gemini-3.8-flash` and review the [Gemini 3.8 Flash migration guide](/docs/whats-new-gemini-3.8#migrate-to-gemini-3-8-flash) before December 1, 2026. {% /callout %} {% table variant="model" %} * Model * Description * Endpoint --- * [Gemini 2.5 Pro](/docs/models/gemini-2.5-pro) * Our most advanced model for complex tasks, featuring deep reasoning and coding capabilities in the 2.5 family. * `gemini-2.5-pro` --- * [Gemini 2.5 Pro TTS](/docs/models/gemini-2.5-pro-preview-tts) * High-fidelity speech synthesis optimized for quality in structured workflows like podcasts and audiobooks. * `gemini-2.5-pro-preview-tts` {% /table %} ## Audio models {% id="audio-models" %} *This section contains all audio models, including ones that may already be listed in other sections* {% table variant="model" %} * Model * Description * Endpoint --- * [Gemini 3.8 Live](/docs/models/gemini-3.8-live) * The default option for most low-latency voice agent experiences and real-time dialogue without reasoning delays. * `gemini-3.8-live` --- * [Gemini 3.8 Live Extended Thinking](/docs/models/gemini-3.8-live-extended-thinking) * Our high-reasoning audio-to-audio model, recommended when higher background reasoning is required during live interactions. * `gemini-3.8-live-extended-thinking` --- * [Gemini 3.8 Flash TTS](/docs/models/gemini-3.8-flash-tts) * Flagship creative text-to-speech model for studio-grade voice fidelity, expressive acting, and regional dialects across 130 languages. * `gemini-3.8-flash-tts` --- * [Gemini 3.8 Flash-Lite TTS](/docs/models/gemini-3.8-flash-lite-tts) * Fast, cost-efficient text-to-speech model built for high-throughput production workloads across 101 languages. * `gemini-3.8-flash-lite-tts` --- * [Gemini 3.1 Flash Live](/docs/models/gemini-3.1-flash-live-preview) * Legacy audio-to-audio preview model. We recommend updating to Gemini 3.8 Live. * `gemini-3.1-flash-live-preview` --- * [Gemini 3.1 Flash TTS](/docs/models/gemini-3.1-flash-tts-preview) * Legacy text-to-speech preview model. We recommend updating to Gemini 3.8 Flash TTS or Gemini 3.8 Flash-Lite TTS. * `gemini-3.1-flash-tts-preview` --- * [Gemini 2.5 Flash Live](/docs/models/gemini-2.5-flash-native-audio-preview-12-2025) * Our flagship Live API model for low-latency, bidirectional voice and video agents with native audio reasoning. * `gemini-2.5-flash-native-audio-preview-12-2025` --- * [Gemini 2.5 Flash TTS](/docs/models/gemini-2.5-flash-preview-tts) * Fast and controllable text-to-speech for low-latency, cost-efficient applications and real-time assistants. * `gemini-2.5-flash-preview-tts` --- * [Gemini 2.5 Pro TTS](/docs/models/gemini-2.5-pro-preview-tts) * High-fidelity speech synthesis optimized for quality in structured workflows like podcasts and audiobooks. * `gemini-2.5-pro-preview-tts` {% /table %} ## Generative media models {% id="generative-media-models" %} *This section contains all generative media models, including ones that may already be listed in other sections* {% table variant="model" %} * Model * Description * Endpoint --- * [Nano Banana 2.1](/docs/models/gemini-nano-banana-2.1) * High-efficiency image generation and editing model with improved visual quality, typography, and multi-turn consistency. * `gemini-nano-banana-2.1` --- * [Nano Banana 2](/docs/models/gemini-3.1-flash-image) * High-efficiency production-scale visual creation, combining the intelligence of the Gemini 3 series with lightning-fast generation speeds. * `gemini-3.1-flash-image` --- * [Nano Banana 2 Lite](/docs/models/gemini-3.1-flash-lite-image) * Our fastest and cheapest Gemini image model, engineered for velocity and scale where speed and cost are the primary operational constraints. Not optimized for multiple reference inputs or multi-turn sequential editing. * `gemini-3.1-flash-lite-image` --- * [Nano Banana Pro](/docs/models/gemini-3-pro-image) * A professional design engine with a reasoning core for studio-quality 4K visuals, complex layouts, and precise text rendering. * `gemini-3-pro-image` --- * [Gemini Omni Flash](/docs/models/gemini-omni-flash) * Fast video generation, editing, keyframe interpolation, and extension with native audio. * `gemini-omni-1.1-flash` --- * [Nano Banana](/docs/models/gemini-2.5-flash-image) * State-of-the-art native image generation and editing designed for fast, creative workflows. * `gemini-2.5-flash-image` --- * Imagen 4 (Shut down) * Text-to-image model featuring fast and ultra-fast generation (shut down). * `imagen-4.0-generate` {% /table %} ## Music generation models {% id="music-models" %} *This section contains all music generation models, including ones that may already be listed in other sections* {% table variant="model" %} * Model * Description * Endpoint --- * [Lyria 3.5](/docs/models/lyria-3.5) * Our flagship music generation model, optimized for full-length songs with complex structural coherence. * `lyria-3.5` --- * [Lyria 3 Clip](/docs/models/lyria-3-clip-preview) * Optimized for generating short musical clips, loops, and previews up to 30 seconds. * `lyria-3-clip-preview` --- * [Lyria 3 Pro](/docs/models/lyria-3-pro-preview) * Previous generation music generation model for full-length songs. * `lyria-3-pro-preview` --- * [Lyria RealTime](/docs/models/lyria-realtime-exp) * High-fidelity music generation model providing granular creative control and real-time streaming capabilities. * `lyria-realtime-exp` {% /table %} ## Tool and agent models {% id="tool-and-agent-models" %} {% table variant="model" %} * Model * Description * Endpoint --- * [Gemini Deep Research](/docs/models/deep-research-preview-04-2026) * An agentic model that autonomously plans and executes multi-step research across hundreds of sources to produce cited, interactive reports. * `deep-research-preview-04-2026` --- * [Gemini Deep Research Max](/docs/models/deep-research-max-preview-04-2026) * Maximum comprehensiveness for automated context gathering and synthesis across hundreds of sources. * `deep-research-max-preview-04-2026` --- * [Antigravity Agent](/docs/models/antigravity-preview-09-2026) * A general-purpose managed agent that autonomously plans, reasons, runs code, manages files, and browses the web inside a secure, isolated Linux sandbox. * `antigravity-preview-09-2026` {% /table %} ## Specialized task models {% id="specialized-task-models" %} {% table variant="model" %} * Model * Description * Endpoint --- * [Gemini Embedding 2](/docs/models/gemini-embedding-2) * Our first multimodal embedding model, mapping text, images, video, audio, and PDFs into a unified embedding space for advanced semantic search and RAG systems. * `gemini-embedding-2` --- * [Gemini Embedding](/docs/models/gemini-embedding-001) * High-dimensional vector representations for advanced semantic search, text classification, and RAG systems. * `gemini-embedding-001` --- * [Gemini Robotics ER 2](/docs/robotics-overview) * Embodied reasoning model delivering advanced video understanding, spatial reasoning, multi-step tool orchestration, and multi-robot collaboration for robotics tasks. * `gemini-robotics-er-2-preview` {% /table %} ## Previous models {% id="previous-models" %} {% callout type="warning" %} These models are [deprecated](/docs/deprecations) and will be shut down soon; migrate to newer models to prevent service interruptions. {% /callout %} {% table variant="model" %} * Model * Description * Endpoint --- * [Gemini Robotics ER 1.6](/docs/models/gemini-robotics-er-1.6-preview) (Shut down) * Advanced embodied reasoning model that understands physical spaces and plans multi-step tasks for robotic agents with new capabilities like instrument reading, improved spatial and physical reasoning. * `gemini-robotics-er-1.6-preview` --- * [Computer Use](/docs/models/gemini-2.5-computer-use-preview-10-2025) (Shut down) * A specialized model that can "see" a digital screen and perform UI actions like clicking, typing, and navigating to automate complex browser tasks. * `gemini-2.5-computer-use-preview-10-2025` --- * [Gemini 2.0 Flash](/docs/models/gemini-2.0-flash) (Shut down) * Our second generation workhorse model, with next-gen features and improved capabilities, including superior speed, native tool use, and a 1M token context window. * `gemini-2.0-flash` --- * [Gemini 2.0 Flash-Lite](/docs/models/gemini-2.0-flash-lite) (Shut down) * Our fastest second generation model, optimized for cost efficiency and low latency. * `gemini-2.0-flash-lite` --- * [Gemini 3.1 Flash-Lite Preview](/docs/models/gemini-3.1-flash-lite-preview) (Shut down) * Our most cost-efficient multimodal model, offering the fastest performance for high-frequency, lightweight tasks. * `gemini-3.1-flash-lite-preview` --- * [Gemini 3 Pro Preview](/docs/models/gemini-3-pro-preview) (Shut down) * Our state-of-the-art reasoning model, with advanced multimodal understanding. * `gemini-3-pro-preview` {% /table %} ## Model version name patterns {% id="model-versions" %} Gemini models are available in either _stable_, _preview_, _latest_, or _experimental_ versions. {% callout type="note" %} Note: The following list refers to the model string naming convention as of September, 2025. Models released prior to that may have different naming conventions. Refer to the exact model string if you are using an older model. {% /callout %} ### Stable {% class="hide-from-toc" id="stable" %} Points to a specific stable model. Stable models usually don't change. Most production apps should use a specific stable model. For example: `gemini-3.6-flash`. ### Preview {% class="hide-from-toc" id="preview" %} Points to a preview model which may be used for production. Preview models will typically have billing enabled, might come with more restrictive rate limits and will be deprecated with at least 2 weeks notice. For example: `gemini-2.5-flash-preview-09-2025`. ### Latest {% class="hide-from-toc" id="latest" %} Points to the latest release for a specific model variation. This can be a stable, preview or experimental release. This alias will get hot-swapped with every new release of a specific model variation. A **2-week notice** will be provided through email before the version behind latest is changed. For example: `gemini-flash-latest`. ### Experimental {% class="hide-from-toc" id="experimental" %} Points to an experimental model which will typically not be suitable for production use and come with more restrictive rate limits. We release experimental models to gather feedback and get our latest updates into the hands of developers quickly. Experimental models are not stable and availability of model endpoints is subject to change. ## Model deprecations {% id="model-deprecations" %} For information about model deprecations, visit the [Gemini deprecations](/docs/deprecations) page. # Gemini 4 Argon Source: https://aistudio.google.com/docs/models/gemini-4-argon Description: Explore Gemini 4 Argon (gemini-4-argon), Google's latest Gemini 4 model for coding, reasoning, and agents, featuring a 1M context window and long decode. Gemini 4 Argon (`gemini-4-argon`) is our flagship reasoning model, built for complex software engineering, deep mathematical and scientific problem solving, autonomous multi-step agents, and long decode up to 1M tokens. {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-4-argon" variant="ais" %}Try in Google AI Studio{% /button %} ## Documentation {% id="documentation" %} Visit the [Latest model](/docs/latest-model) page for full coverage of features, API changes, and migration guidance. ## gemini-4-argon {% id="gemini-4-argon" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-4-argon` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text, Image, Video, Audio, and PDF **Output** Text --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Context window (unified input and output token limit)** 1,048,576 **Max output** 65,536 (default synchronous) / up to 1,048,576 (with [long decode](/docs/long-decode)) --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Agentic video understanding** {% badge type="supported" label="Supported (defaults to static)" /%} {% /section %} {% section %} **Audio generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="supported" label="Supported (Implicit only)" /%} Note: Explicit caching is not supported. {% /section %} {% section %} **Code execution** {% badge type="supported" /%} {% /section %} {% section %} **Computer use** {% badge type="supported" /%} {% /section %} {% section %} **File search** {% badge type="supported" /%} {% /section %} {% section %} **Flex inference** {% badge type="supported" /%} {% /section %} {% section %} **Function calling** {% badge type="supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Priority inference** {% badge type="supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="supported" /%} {% /section %} {% section %} **Thinking** {% badge type="supported" label="Supported (low, medium, high)" /%} {% /section %} {% section %} **URL context** {% badge type="supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Stable: `gemini-4-argon` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * October 2026 --- * {% section class="model-property" %} {% icon name="id_card" /%}Model card {% /section %} * [Model card](https://deepmind.google/models/model-cards/gemini-4-argon/) --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-4-argon) {% /table %} # Gemini Nano Banana 2.1 Source: https://aistudio.google.com/docs/models/gemini-nano-banana-2.1 Description: Learn about Gemini Nano Banana 2.1 from Google **Gemini Nano Banana 2.1** (`gemini-nano-banana-2.1`) is the latest high-efficiency image generation and conversational editing model. An update to Nano Banana 2 ([Gemini 3.1 Flash Image](/docs/models/gemini-3.1-flash-image)), it maintains Flash-level speed and cost efficiency while delivering significant improvements in visual quality, prompt adherence, multi-turn character consistency, and text rendering. It serves as the more efficient counterpart to [Gemini 3 Pro Image](/docs/models/gemini-3-pro-image) (Nano Banana Pro). **Key updates:** * Improved visual quality and realism across `1K`, `2K`, and `4K` output resolutions (default `1K`) * Fixed tiling artifacts on wide and panoramic aspect ratios (`1:4`, `4:1`, `1:8`, `8:1`) at `2K` and `4K` resolutions * Enhanced text rendering and infographic layout accuracy * Multi-image fusion supporting up to 14 reference images (character consistency for up to 4 characters and object fidelity for up to 10 objects) * Grounding with Google Web and Image Search * Configurable Thinking levels (`minimal`, `medium` default, and `high`) {% button href="https://aistudio.google.com?model=gemini-nano-banana-2.1" variant="ais" %}Try in Google AI Studio{% /button %} ## Documentation {% id="documentation" %} Visit the [Image generation](/docs/image-generation) page for full coverage of features and capabilities. ## gemini-nano-banana-2.1 {% id="gemini-nano-banana-2-1" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-nano-banana-2.1` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text, Image, Video, and PDF **Output** Image and Text --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 131,072 **Output token limit** 32,768 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="not-supported" /%} {% /section %} {% section %} **Code execution** {% badge type="not-supported" /%} {% /section %} {% section %} **File search** {% badge type="not-supported" /%} {% /section %} {% section %} **Flex inference** {% badge type="not-supported" /%} {% /section %} {% section %} **Function calling** {% badge type="not-supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="not-supported" /%} {% /section %} {% section %} **Image generation** {% badge type="supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Priority inference** {% badge type="not-supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="not-supported" /%} {% /section %} {% section %} **Thinking** {% badge type="supported" /%} {% /section %} {% section %} **URL context** {% badge type="not-supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Stable: `gemini-nano-banana-2.1` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * October 2026 --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-nano-banana-2.1) {% /table %} # Gemini 3.1 Flash image Source: https://aistudio.google.com/docs/models/gemini-3.1-flash-image Description: Learn about Gemini 3.1 Flash Image from Google **Nano Banana 2** provides high-quality image generation and conversational editing at a mainstream price point and low latency. It serves as the high-efficiency counterpart to [Gemini 3 Pro Image](/docs/models/gemini-3-pro-image), optimized for speed and high-volume developer use cases. **Key updates:** * New output resolution options: * New support for 0.5K, 2K and 4K, default 1K * New Image Search Grounding: * Integration of both text and image search results to inform generation with real-time web data * Supported with Thinking on or off * New 1:4, 4:1, 1:8 and 8:1 aspect ratios * Improved aspect ratio adherence * Improved image quality and consistency * Improved i18n text rendering {% button href="https://aistudio.google.com?model=gemini-3.1-flash-image" variant="ais" %}Try in Google AI Studio{% /button %} ## Documentation {% id="documentation" %} Visit the [Image generation](/docs/image-generation) page for full coverage of features and capabilities. ## gemini-3.1-flash-image {% id="gemini-31-flash-image" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-3.1-flash-image` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text, Image, Video, and PDF **Output** Image and Text --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 131,072 **Output token limit** 32,768 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="not-supported" /%} {% /section %} {% section %} **Code execution** {% badge type="not-supported" /%} {% /section %} {% section %} **File search** {% badge type="not-supported" /%} {% /section %} {% section %} **Flex inference** {% badge type="not-supported" /%} {% /section %} {% section %} **Function calling** {% badge type="not-supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="not-supported" /%} {% /section %} {% section %} **Image generation** {% badge type="supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Priority inference** {% badge type="not-supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="not-supported" /%} {% /section %} {% section %} **Thinking** {% badge type="supported" /%} {% /section %} {% section %} **URL context** {% badge type="not-supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Stable: `gemini-3.1-flash-image` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * February 2026 --- * {% section class="model-property" %} {% icon name="id_card" /%}Model card {% /section %} * [Model card](https://deepmind.google/models/model-cards/gemini-3-1-flash-image/) --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-3.1-flash-image) {% /table %} # Gemini 3.1 Pro preview Source: https://aistudio.google.com/docs/models/gemini-3.1-pro-preview Description: Learn about Gemini 3.1 Pro Preview from Google Built to refine the performance and reliability of the Gemini 3 Pro series, Gemini 3.1 Pro Preview provides better thinking, improved token efficiency, and a more grounded, factually consistent experience. It's optimized for software engineering behavior and usability, as well as agentic workflows requiring precise tool usage and reliable multi-step execution across real-world domains. {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-3.1-pro-preview" variant="ais" %} Try in Google AI Studio {% /button %} ## Documentation {% id="documentation" %} Visit the [Gemini 3 Developer Guide](/docs/latest-model) page for full coverage of features and capabilities. ## gemini-3.1-pro-preview {% id="gemini-31-pro-preview" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-3.1-pro-preview` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text, Image, Video, Audio, and PDF **Output** Text --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 1,048,576 **Output token limit** 65,536 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="supported" /%} {% /section %} {% section %} **Code execution** {% badge type="supported" /%} {% /section %} {% section %} **File search** {% badge type="supported" /%} {% /section %} {% section %} **Flex inference** {% badge type="supported" /%} {% /section %} {% section %} **Function calling** {% badge type="supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Priority inference** {% badge type="supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="supported" /%} {% /section %} {% section %} **Thinking** {% badge type="supported" /%} {% /section %} {% section %} **URL context** {% badge type="supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Preview: `gemini-3.1-pro-preview` * Preview: [`gemini-3.1-pro-preview-customtools`](/docs/models/gemini-3.1-pro-preview#gemini-31-pro-preview-customtools) --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * February 2026 --- * {% section class="model-property" %} {% icon name="id_card" /%}Model card {% /section %} * [Model card](https://deepmind.google/models/model-cards/gemini-3-1-pro/) --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-3.1-pro-preview) {% /table %} #### gemini-3.1-pro-preview-customtools {% id="gemini-31-pro-preview-customtools" %} For those building with a mix of bash and custom tools, Gemini 3.1 Pro Preview comes with a separate endpoint available via the API called `gemini-3.1-pro-preview-customtools`. This endpoint is better at prioritizing your custom tools (for example `view_file` or `search_code`). Note that while `gemini-3.1-pro-preview-customtools` is optimized for agentic workflows that use custom tools and bash, you may see quality fluctuations in some use cases which don't benefit from such tools. # Gemini 3 Pro preview Source: https://aistudio.google.com/docs/models/gemini-3-pro-preview Description: Learn about Gemini 3 Pro Preview from Google {% callout type="warning" %} Gemini 3 Pro Preview is [deprecated](/docs/deprecations) and was shut down on March 9, 2026. Migrate to [Gemini 4 Argon](/docs/models/gemini-4-argon) to avoid service disruption. {% /callout %} ## gemini-3-pro-preview {% id="gemini-3-pro-preview" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-3-pro-preview` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text, Image, Video, Audio, and PDF **Output** Text --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 1,048,576 **Output token limit** 65,536 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="supported" /%} {% /section %} {% section %} **Code execution** {% badge type="supported" /%} {% /section %} {% section %} **Computer use** {% badge type="not-supported" /%} {% /section %} {% section %} **File search** {% badge type="supported" /%} {% /section %} {% section %} **Function calling** {% badge type="supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="not-supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="supported" /%} {% /section %} {% section %} **Thinking** {% badge type="supported" /%} {% /section %} {% section %} **URL context** {% badge type="supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * *Shut down*: `gemini-3-pro-preview` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * November 2025 --- * {% section class="model-property" %} {% icon name="id_card" /%}Model card {% /section %} * [Model card](https://deepmind.google/models/model-cards/gemini-3-pro/) {% /table %} # Gemini 3 Pro image Source: https://aistudio.google.com/docs/models/gemini-3-pro-image Description: Learn about Gemini 3 Pro Image from Google **Nano Banana Pro** is a sophisticated reasoning-driven engine for professional-grade image editing and generation, offering studio-quality precision and advanced creative control. Nano Banana Pro is best for complex graphic design, high-fidelity product mockups, and factual data visualizations that require accurate text rendering and real-world grounding via Google Search. {% button href="https://aistudio.google.com?model=gemini-3-pro-image" variant="ais" %}Try in Google AI Studio{% /button %} ## Documentation {% id="documentation" %} Visit the [Image generation](/docs/image-generation) page for full coverage of features and capabilities. ## gemini-3-pro-image {% id="gemini-3-pro-image" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-3-pro-image` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Image and Text **Output** Image and Text --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 65,536 **Output token limit** 32,768 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="not-supported" /%} {% /section %} {% section %} **Code execution** {% badge type="not-supported" /%} {% /section %} {% section %} **File search** {% badge type="not-supported" /%} {% /section %} {% section %} **Flex inference** {% badge type="not-supported" /%} {% /section %} {% section %} **Function calling** {% badge type="not-supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="not-supported" /%} {% /section %} {% section %} **Image generation** {% badge type="supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Priority inference** {% badge type="not-supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="not-supported" /%} {% /section %} {% section %} **Thinking** {% badge type="supported" /%} {% /section %} {% section %} **URL context** {% badge type="not-supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Stable: `gemini-3-pro-image` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * November 2025 --- * {% section class="model-property" %} {% icon name="id_card" /%}Model card {% /section %} * [Model card](https://deepmind.google/models/model-cards/gemini-3-pro-image/) --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-3-pro-image) {% /table %} # Gemini 3.8 Flash Source: https://aistudio.google.com/docs/models/gemini-3.8-flash Description: Learn about Gemini 3.8 Flash from Google Gemini 3.8 Flash is our most intelligent Flash model, engineered for long-horizon software engineering, autonomous agents, and complex enterprise workflows—all with the speed and cost efficiency of Flash. {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-3.8-flash" variant="ais" %}Try in Google AI Studio{% /button %} ## Documentation {% id="documentation" %} Visit the [What's new in Gemini 3.8 Flash](/docs/whats-new-gemini-3.8) page for full coverage of features and capabilities. ## gemini-3.8-flash {% id="gemini-38-flash" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-3.8-flash` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text, Image, Video, Audio, and PDF **Output** Text --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 1,048,576 **Output token limit** 65,536 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="supported" /%} {% /section %} {% section %} **Code execution** {% badge type="supported" /%} {% /section %} {% section %} **Computer use** {% badge type="supported" /%} {% /section %} {% section %} **File search** {% badge type="supported" /%} {% /section %} {% section %} **Flex inference** {% badge type="supported" /%} {% /section %} {% section %} **Function calling** {% badge type="supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Priority inference** {% badge type="supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="supported" /%} {% /section %} {% section %} **Thinking** {% badge type="supported" label="Supported (low, medium, high)" /%} Note: `minimal` is not supported and returns an error. {% /section %} {% section %} **URL context** {% badge type="supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Stable: `gemini-3.8-flash` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * September 2026 --- * {% section class="model-property" %} {% icon name="id_card" /%}Model card {% /section %} * [Model card](https://deepmind.google/models/model-cards/gemini-3-8-flash/) --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-3.8-flash) {% /table %} # Gemini 3.8 Flash TTS Source: https://aistudio.google.com/docs/models/gemini-3.8-flash-tts Description: Learn about the Gemini 3.8 Flash TTS model from Google, including when to use it and how to migrate from earlier TTS models. Gemini 3.8 Flash TTS (`gemini-3.8-flash-tts`) is Google's flagship creative text-to-speech model, engineered for studio-grade voice fidelity, expressive acting, authentic regional accents, and rock-solid long-form multi-turn stability. {% button href="https://aistudio.google.com?model=gemini-3.8-flash-tts" variant="ais" %}Try in Google AI Studio{% /button %} ## Overview and capabilities {% id="overview-and-capabilities" %} Gemini 3.8 Flash TTS sets a new benchmark for expressive audio generation: * **High acoustic fidelity and acting nuance:** Delivers rich emotional range, natural cadence, and precise adherence to turn-level `style` directions and inline vocal events (``, ``, ``). * **Long-form multi-turn stability:** Maintains consistent voice identity, timbre, volume, and acoustic room tone across extended dialogues and multi-minute narrations without voice drift. * **Authentic regional accents and pronunciation:** Supports regional accents and minority dialects. * **Full voice ecosystem support:** Works seamlessly with prebuilt voices, the Extended Voice Library (`GET /v1beta/voices`), custom [Voice design](/docs/voice-design) personas, and [Voice replication](/docs/voice-replication) (persistent stored voices by default, plus optional stateless keys). You can also design and replicate voices interactively in [Google AI Studio](https://aistudio.google.com/generate-speech). Visit the [Text-to-speech](/docs/speech-generation) guide for full coverage of features, prompting best practices, and code examples. ## When to use which TTS model {% id="when-to-use-which-tts-model" %} Both Gemini 3.8 TTS models share the same API schema and prompting structure. Choose the model that fits your workload: | Feature / workload | Gemini 3.8 Flash TTS (`gemini-3.8-flash-tts`) | Gemini 3.8 Flash-Lite TTS (`gemini-3.8-flash-lite-tts`) | | :------------ | :----------------------- | :----------------------------- | | **Primary strength** | Maximum voice fidelity, acting nuance, and dialect coverage | High throughput, low latency, and cost efficiency | | **Best use cases** | Audiobooks, studio narration, complex multi-speaker dialogue, heavy vocal-burst acting, difficult pronunciation, regional dialects | High-volume production, real-time voice agent cascades, read-aloud features, voice replication, everyday single-speaker generation | | **Supported languages** | 130 languages | 101 languages | | **Recommended replacement for** | New flagship creative tier | `gemini-3.1-flash-tts-preview` | ## Migration guide {% id="migration-guide" %} If you are migrating from `gemini-3.1-flash-tts-preview` or earlier Gemini TTS models, update your requests for the Gemini 3.8 TTS schema: 1. **Move turn-level directions into `speech_metadata`:** Gemini 3.8 TTS treats input text strictly as a verbatim transcript. Inline text directions like `"Say cheerfully: Hello!"` or `"Speaker 1: Hello!"` may be spoken aloud. Move sustained delivery instructions (`style`) and speaker labels (`speaker`) into structured metadata: * **Interactions API:** Attach an annotation with `"type": "speech_metadata"`, `"speaker"`, and `"style"` to each text content block. * **GenerateContent API:** Attach `"speech_metadata": {"speaker": "...", "style": "..."}` to each `part`. 2. **Use angle-bracket inline tags only for point-in-time vocal events:** Keep momentary non-speech vocalizations and pauses inline in the transcript using angle brackets (such as ``, ``, ``, ``, or ``). Put delivery styles like whispering in `speech_metadata.style`. 3. **Specify `speaker` on every turn in multi-speaker requests:** Every turn in a multi-speaker request must explicitly include `speaker` inside `speech_metadata` matching one of the configured speakers. 4. **Design personas upfront with Voice design:** Replace long legacy Audio Profile / Director's Notes blocks with a custom voice created in [Voice design](/docs/voice-design), then carry that `voice_...` ID through your TTS requests with minimal or empty `style` strings. 5. **Account for default WAV (`audio/wav`) output on unary requests:** Unlike `gemini-3.1-flash-tts-preview` and earlier TTS models (which returned headerless raw PCM `audio/l16` by default), Gemini 3.8 TTS returns WAV audio (`audio/wav` / `AUDIO_WAV`) with a standard RIFF header by default for unary requests. * If your code previously wrapped raw PCM bytes in a WAV header (for example, using Python's `wave` module or `ffmpeg`), remove the manual header wrapper and write the returned bytes directly to a `.wav` file. * If your pipeline requires headerless raw PCM, mu-law, or A-law audio, explicitly set `response_format.mime_type` to `"audio/l16"`, `"audio/mulaw"`, or `"audio/alaw"` (for example, `{"response_format": {"type": "audio", "mime_type": "audio/l16"}}` in the Interactions API, or `AUDIO_L16`, `AUDIO_MULAW`, or `AUDIO_ALAW` in `generateContent`). See [Audio output formats](/docs/speech-generation#audio-output-formats). ## gemini-3.8-flash-tts {% id="gemini-38-flash-tts" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-3.8-flash-tts` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text **Output** Audio --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 8,192 **Output token limit** 16,384 (Gemini API serving limit) --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="not-supported" /%} {% /section %} {% section %} **Code execution** {% badge type="not-supported" /%} {% /section %} {% section %} **File search** {% badge type="not-supported" /%} {% /section %} {% section %} **Flex inference** {% badge type="supported" /%} {% /section %} {% section %} **Function calling** {% badge type="not-supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="not-supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Priority inference** {% badge type="supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="not-supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="not-supported" /%} {% /section %} {% section %} **Thinking** {% badge type="not-supported" /%} {% /section %} {% section %} **URL context** {% badge type="not-supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * `gemini-3.8-flash-tts` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * September 2026 --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-3.8-flash-tts) {% /table %} ## Supported languages {% id="supported-languages" %} `gemini-3.8-flash-tts` detects the input language automatically and supports **over 130 languages**: | Language | Language | Language | | :--- | :--- | :--- | | Acehnese (Arab script) | Greek | Nepali (individual language) | | Afrikaans | Guarani | Nigerian Fulfulde | | Akan | Gujarati | North Azerbaijani | | Amharic | Haitian Creole | Northern Sotho | | Armenian | Halh Mongolian | Northern Uzbek | | Assamese | Hausa | Norwegian Bokmål | | Awadhi | Hebrew | Norwegian Nynorsk | | Balinese | Hindi | Nyanja | | Bangla | Hungarian | Occitan | | Banjar (Arab script) | Icelandic | Odia (individual language) | | Banjar (Latn script) | Igbo | Pangasinan | | Bashkir | Iloko | Persian (Afghanistan) | | Basque | Indonesian | Polish | | Belarusian | Iranian Persian | Portuguese | | Bemba | Italian | Punjabi | | Bhojpuri | Japanese | Romanian | | Bosnian | Javanese | Russian | | Buginese | Kabyle | Santali | | Bulgarian | Kamba | Serbian | | Burmese | Kannada | Sindhi | | Cantonese | Kashmiri (Arab script) | Sinhala | | Catalan | Kashmiri (Deva script) | Slovak | | Cebuano | Kazakh | Slovenian | | Central Kurdish | Khmer | Somali | | Chhattisgarhi | Kikuyu | South Azerbaijani | | Chinese (Hans script) | Kinyarwanda | Southern Pashto | | Chinese (Hant script) | Kongo | Southern Sotho | | Crimean Tatar | Korean | Spanish | | Croatian | Kyrgyz | Standard Arabic (Arab script) | | Czech | Lao | Standard Arabic (Latn script) | | Danish | Latgalian | Standard Latvian | | Dutch | Lingala | Standard Malay | | Dyula | Lithuanian | Swahili (individual language) | | Dzongkha | Luxembourgish | Swati | | Egyptian Arabic | Macedonian | Swedish | | English | Magahi | Tajik | | Estonian | Maithili | Tamil | | Filipino | Malayalam | Telugu | | Finnish | Maltese | Thai | | French | Manipuri | Tigrinya | | Galician | Marathi | Tosk Albanian | | Ganda | Minangkabau (Arab script) | Turkish | | Georgian | Minangkabau (Latn script) | Uyghur | | German | Mizo | Vietnamese | # Gemini 3.8 Flash-Lite TTS Source: https://aistudio.google.com/docs/models/gemini-3.8-flash-lite-tts Description: Learn about the Gemini 3.8 Flash-Lite TTS model from Google, including when to use it and how to migrate from earlier TTS models. Gemini 3.8 Flash-Lite TTS (`gemini-3.8-flash-lite-tts`) is Google's fast, cost-efficient workhorse text-to-speech model built to replace `gemini-3.1-flash-tts-preview` for high-throughput production workloads. {% button href="https://aistudio.google.com?model=gemini-3.8-flash-lite-tts" variant="ais" %}Try in Google AI Studio{% /button %} ## Overview and capabilities {% id="overview-and-capabilities" %} Gemini 3.8 Flash-Lite TTS combines low latency with expressive, natural speech: * **High-throughput efficiency:** Optimized for bulk production, conversational voice agent cascades, read-aloud features, and everyday single-speaker speech generation across major languages. * **Drop-in schema compatibility:** Shares the exact same API schema and structured prompting format as `gemini-3.8-flash-tts`, allowing you to switch models with a single parameter change. * **Full voice ecosystem support:** Supports prebuilt voices, the Extended Voice Library (`GET /v1beta/voices`), custom [Voice design](/docs/voice-design) personas, and [Voice replication](/docs/voice-replication) (persistent stored voices by default, plus optional stateless keys). You can also design and replicate voices interactively in [Google AI Studio](https://aistudio.google.com/generate-speech). Visit the [Text-to-speech](/docs/speech-generation) guide for full coverage of features, prompting best practices, and code examples. ## When to use which TTS model {% id="when-to-use-which-tts-model" %} Both Gemini 3.8 TTS models share the same API schema and prompting structure. Choose the model that fits your workload: | Feature / workload | Gemini 3.8 Flash-Lite TTS (`gemini-3.8-flash-lite-tts`) | Gemini 3.8 Flash TTS (`gemini-3.8-flash-tts`) | | :------------ | :----------------------------- | :----------------------- | | **Primary strength** | High throughput, low latency, and cost efficiency | Maximum voice fidelity, acting nuance, and dialect coverage | | **Best use cases** | High-volume production, real-time voice agent cascades, read-aloud features, voice replication, everyday single-speaker generation | Audiobooks, studio narration, complex multi-speaker dialogue, heavy vocal-burst acting, difficult pronunciation, regional dialects | | **Supported languages** | 101 languages | 130 languages | | **Recommended replacement for** | `gemini-3.1-flash-tts-preview` | New flagship creative tier | ## Migration guide {% id="migration-guide" %} If you are upgrading from `gemini-3.1-flash-tts-preview` to `gemini-3.8-flash-lite-tts`, update your requests for the Gemini 3.8 TTS schema: 1. **Move turn-level directions into `speech_metadata`:** Gemini 3.8 TTS treats input text strictly as a verbatim transcript. Inline text directions like `"Say cheerfully: Hello!"` or `"Speaker 1: Hello!"` may be spoken aloud. Move sustained delivery instructions (`style`) and speaker labels (`speaker`) into structured metadata: * **Interactions API:** Attach an annotation with `"type": "speech_metadata"`, `"speaker"`, and `"style"` to each text content block. * **GenerateContent API:** Attach `"speech_metadata": {"speaker": "...", "style": "..."}` to each `part`. 2. **Use angle-bracket inline tags only for point-in-time vocal events:** Keep momentary non-speech vocalizations and pauses inline in the transcript using angle brackets (such as ``, ``, ``, ``, or ``). Put delivery styles like whispering in `speech_metadata.style`. 3. **Specify `speaker` on every turn in multi-speaker requests:** Every turn in a multi-speaker request must explicitly include `speaker` inside `speech_metadata` matching one of the configured speakers. 4. **Design personas upfront with Voice design:** Replace long legacy Audio Profile / Director's Notes blocks with a custom voice created in [Voice design](/docs/voice-design), then carry that `voice_...` ID through your TTS requests with minimal or empty `style` strings. 5. **Account for default WAV (`audio/wav`) output on unary requests:** Unlike `gemini-3.1-flash-tts-preview` and earlier TTS models (which returned headerless raw PCM `audio/l16` by default), Gemini 3.8 TTS returns WAV audio (`audio/wav` / `AUDIO_WAV`) with a standard RIFF header by default for unary requests. * If your code previously wrapped raw PCM bytes in a WAV header (for example, using Python's `wave` module or `ffmpeg`), remove the manual header wrapper and write the returned bytes directly to a `.wav` file. * If your pipeline requires headerless raw PCM, mu-law, or A-law audio, explicitly set `response_format.mime_type` to `"audio/l16"`, `"audio/mulaw"`, or `"audio/alaw"` (for example, `{"response_format": {"type": "audio", "mime_type": "audio/l16"}}` in the Interactions API, or `AUDIO_L16`, `AUDIO_MULAW`, or `AUDIO_ALAW` in `generateContent`). See [Audio output formats](/docs/speech-generation#audio-output-formats). ## gemini-3.8-flash-lite-tts {% id="gemini-38-flash-lite-tts" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-3.8-flash-lite-tts` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text **Output** Audio --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 8,192 **Output token limit** 16,384 (Gemini API serving limit) --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="not-supported" /%} {% /section %} {% section %} **Code execution** {% badge type="not-supported" /%} {% /section %} {% section %} **File search** {% badge type="not-supported" /%} {% /section %} {% section %} **Flex inference** {% badge type="supported" /%} {% /section %} {% section %} **Function calling** {% badge type="not-supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="not-supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Priority inference** {% badge type="supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="not-supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="not-supported" /%} {% /section %} {% section %} **Thinking** {% badge type="not-supported" /%} {% /section %} {% section %} **URL context** {% badge type="not-supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * `gemini-3.8-flash-lite-tts` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * September 2026 --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-3.8-flash-lite-tts) {% /table %} ## Supported languages {% id="supported-languages" %} `gemini-3.8-flash-lite-tts` detects the input language automatically and supports **over 100 languages**: | Language | Language | Language | | :--- | :--- | :--- | | Acehnese (Arab script) | German | Manipuri | | Afrikaans | Greek | Marathi | | Akan | Gujarati | Minangkabau (Arab script) | | Amharic | Haitian Creole | Mizo | | Armenian | Halh Mongolian | Nepali (individual language) | | Assamese | Hausa | Nigerian Fulfulde | | Awadhi | Hebrew | North Azerbaijani | | Balinese | Hindi | Northern Sotho | | Bangla | Hungarian | Northern Uzbek | | Banjar (Latn script) | Icelandic | Norwegian Bokmål | | Basque | Iloko | Norwegian Nynorsk | | Belarusian | Indonesian | Nyanja | | Bhojpuri | Iranian Persian | Odia (individual language) | | Bosnian | Italian | Persian (Afghanistan) | | Buginese | Japanese | Polish | | Bulgarian | Javanese | Portuguese | | Cantonese | Kamba | Punjabi | | Catalan | Kannada | Romanian | | Cebuano | Kashmiri (Arab script) | Russian | | Central Kurdish | Kashmiri (Deva script) | Santali | | Chhattisgarhi | Kazakh | Serbian | | Chinese (Hans script) | Khmer | Sinhala | | Chinese (Hant script) | Kikuyu | Slovak | | Croatian | Kinyarwanda | South Azerbaijani | | Czech | Kongo | Southern Pashto | | Danish | Korean | Spanish | | Dutch | Kyrgyz | Standard Arabic (Arab script) | | Egyptian Arabic | Lao | Standard Arabic (Latn script) | | English | Lingala | Standard Latvian | | Estonian | Macedonian | Standard Malay | | Filipino | Magahi | Tamil | | French | Maithili | Telugu | | Galician | Malayalam | Turkish | | Ganda | Maltese | Vietnamese | | Georgian | — | — | # Gemini 3.8 Live Source: https://aistudio.google.com/docs/models/gemini-3.8-live Description: Learn about Gemini 3.8 Live, our flagship low-latency audio-to-audio model for real-time multimodal dialogue. Gemini 3.8 Live (`gemini-3.8-live`) is the default option for low-latency, audio-to-audio voice agent experiences and real-time dialogue without reasoning-induced delays. It supports interleaved reasoning, asynchronous and synchronous function calling, full-session client content updates, and built-in proactive audio. For complex agentic tasks requiring multi-step reasoning and configurable thinking budgets, see [Gemini 3.8 Live Extended Thinking](/docs/models/gemini-3.8-live-extended-thinking). {% button href="https://aistudio.google.com/live?model=gemini-3.8-live" variant="ais" %} Try in Google AI Studio {% /button %} ## Documentation {% id="documentation" %} Visit the [Live API](/docs/live-api) guide for full coverage of features, streaming configurations, and tool integrations. ## gemini-3.8-live {% id="gemini-38-live" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-3.8-live` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text, images, audio **Output** Text and audio --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 131,072 **Output token limit** 65,536 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="supported" /%} {% /section %} {% section %} **Batch API** {% badge type="not-supported" /%} {% /section %} {% section %} **Caching** {% badge type="not-supported" /%} {% /section %} {% section %} **Code execution** {% badge type="not-supported" /%} {% /section %} {% section %} **File search** {% badge type="not-supported" /%} {% /section %} {% section %} **Function calling** {% badge type="supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="not-supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="not-supported" /%} {% /section %} {% section %} **Thinking** {% badge type="supported" label="Supported (interleaved reasoning)" /%} {% /section %} {% section %} **URL context** {% badge type="not-supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Stable: `gemini-3.8-live` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * September 2026 --- * {% section class="model-property" %} {% icon name="id_card" /%}Model card {% /section %} * [Model card](https://deepmind.google/models/model-cards/gemini-3-8-audio/) --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-3.8-live) {% /table %} ## Migrating from Gemini 3.1 Flash Live {% id="migrating" %} Gemini 3.8 Live delivers ultra-low latency audio-to-audio interactions and expands support for asynchronous workflows. When migrating from `gemini-3.1-flash-live-preview`, review the following updates: * **Model string**: Update your model string from `gemini-3.1-flash-live-preview` to `gemini-3.8-live`. * **Thinking configuration**: `thinking_level` is not supported in `gemini-3.8-live` because interleaved reasoning is built in. Omit `thinking_level` and `thinking_config` from your session setup. If your application requires configurable background reasoning (`low`, `medium`, or `high`), use [`gemini-3.8-live-extended-thinking`](/docs/models/gemini-3.8-live-extended-thinking). See [Thinking in the Live API](/docs/live-api/thinking). * **Asynchronous function calling**: Asynchronous execution (`behavior: NON_BLOCKING`) is the default function calling mode. You can still use synchronous blocking mode for backward compatibility by setting `behavior: BLOCKING` on your tool declarations. Function scheduling options (`SILENT`, `WHEN_IDLE`, and `INTERRUPTED`) are also supported. See [Asynchronous function calling](/docs/live-api/tools#async-function-calling). * **Client content updates**: `send_client_content` is supported throughout the entire session lifecycle (both initial history seeding and mid-turn context updates) with explicit roles (`user` or `model`). Setting `turn_complete=true` unconditionally interrupts active model generation. If you send content without `turn_complete`, the server waits for subsequent messages before responding. See [Incremental content updates](/docs/live-api/capabilities#incremental-updates). * **Proactive audio**: Proactive audio is permanently enabled. Setting `proactive_audio: false` returns an error, so omit `proactive_audio` if you are migrating code that disables it. * **Affective dialogue**: Affective dialogue is removed from the API. Remove any `enable_affective_dialog` configurations from your setup. * **Turn coverage**: Defaults to [`TURN_INCLUDES_AUDIO_ACTIVITY_AND_ALL_VIDEO`](/api-reference/live#RealtimeInputConfig.TurnCoverage). Video frames are sent to the model by default, so send frames only when needed to manage context and cost. * **Response modalities**: Audio is the only supported response modality (`response_modalities=["AUDIO"]`). Enable `output_audio_transcription` if your application requires a text transcript. See [Audio transcriptions](/docs/live-api/capabilities#audio-transcription). For a feature comparison across all Live API models, see the [Model comparison](/docs/live-api/capabilities#model-comparison) table in the capabilities guide. # Gemini 3.8 Live Extended Thinking Source: https://aistudio.google.com/docs/models/gemini-3.8-live-extended-thinking Description: Learn about Gemini 3.8 Live Extended Thinking, our Live API model engineered for complex reasoning and asynchronous tool orchestration. Gemini 3.8 Live Extended Thinking (`gemini-3.8-live-extended-thinking`) is our high-reasoning audio-to-audio Live API model for complex, multi-step problem solving during real-time voice interactions. It processes configurable background reasoning (`low`, `medium`, `high`), thought summaries, and asynchronous tool calls while streaming continuous audio responses. For low-latency conversational voice experiences without background reasoning delays, see [Gemini 3.8 Live](/docs/models/gemini-3.8-live). {% button href="https://aistudio.google.com/live?model=gemini-3.8-live-extended-thinking" variant="ais" %} Try in Google AI Studio {% /button %} ## Documentation {% id="documentation" %} Visit the [Live API](/docs/live-api) and [Thinking in the Live API](/docs/live-api/thinking) guides for full coverage of reasoning configurations and asynchronous tool integrations. ## gemini-3.8-live-extended-thinking {% id="gemini-38-live-extended-thinking" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-3.8-live-extended-thinking` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text, images, audio **Output** Text and audio --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 131,072 **Output token limit** 65,536 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="supported" /%} {% /section %} {% section %} **Batch API** {% badge type="not-supported" /%} {% /section %} {% section %} **Caching** {% badge type="not-supported" /%} {% /section %} {% section %} **Code execution** {% badge type="not-supported" /%} {% /section %} {% section %} **File search** {% badge type="not-supported" /%} {% /section %} {% section %} **Function calling** {% badge type="supported" label="Supported (Async only)" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="not-supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="not-supported" /%} {% /section %} {% section %} **Thinking** {% badge type="supported" /%} {% /section %} {% section %} **URL context** {% badge type="not-supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Stable: `gemini-3.8-live-extended-thinking` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * September 2026 --- * {% section class="model-property" %} {% icon name="id_card" /%}Model card {% /section %} * [Model card](https://deepmind.google/models/model-cards/gemini-3-8-audio/) --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-3.8-live) {% /table %} ## Upgrading to Gemini 3.8 Live Extended Thinking {% id="upgrading" %} Gemini 3.8 Live Extended Thinking introduces background reasoning during live audio sessions. When integrating this model, update your client state management to handle asynchronous reasoning signals: * **Asynchronous reasoning protocol**: When interacting with models that use asynchronous reasoning, `turnComplete: true` no longer signals that the model is completely idle. The server may continue processing background reasoning or tool calls. Keep your client listening for subsequent server messages (such as tool calls or audio frames) after `turnComplete: true` arrives. * **Monitoring `interaction_status`**: Check `server_content.interaction_status` on incoming [`BidiGenerateContentServerContent`](/api-reference/live#BidiGenerateContentServerContent) messages to determine the current server state before closing the session: * `IN_PROGRESS`: The server is actively processing user input, running background reasoning, or awaiting responses for asynchronous tool calls. Additional model output or tool calls may follow. * `IDLE`: The server has finished all processing, reasoning, and tool calls. The session is idle and waiting for user input. * **Function calling**: Function calling is exclusively asynchronous (`behavior: NON_BLOCKING`). Synchronous blocking mode returns an error, and function scheduling options (`SILENT`, `WHEN_IDLE`, and `INTERRUPTED`) are not supported. See [Asynchronous function calling](/docs/live-api/tools#async-function-calling). * **Thinking configuration**: Configure background reasoning using `thinking_config` in your session setup with `thinking_level` values `low`, `medium`, or `high`. Note that `MINIMAL` is not supported. See [Thinking in the Live API](/docs/live-api/thinking). * **Client content updates**: `send_client_content` is supported throughout the entire session lifecycle (both initial history seeding and mid-turn context updates) with explicit roles (`user` or `model`). Setting `turn_complete=true` immediately interrupts active generation. See [Incremental content updates](/docs/live-api/capabilities#incremental-updates). * **Proactive audio**: Permanently enabled. Setting `proactive_audio: false` returns an error. * **Affective dialogue**: Removed from the API. Remove any `enable_affective_dialog` configurations from your setup. For a feature comparison across all Live API models, see the [Model comparison](/docs/live-api/capabilities#model-comparison) table in the capabilities guide. # Gemini 3.7 Flash Source: https://aistudio.google.com/docs/models/gemini-3.7-flash Description: Learn about Gemini 3.7 Flash from Google {% callout type="caution" %} **Deprecated:** Gemini 3.7 Flash (`gemini-3.7-flash`) is deprecated and has been replaced by [Gemini 3.8 Flash (`gemini-3.8-flash`)](/docs/latest-model). It is no longer available to select in Google AI Studio, and API requests to `gemini-3.7-flash` are automatically routed to `gemini-3.8-flash`. {% /callout %} Gemini 3.7 Flash is a previous-generation model in the Gemini 3 series of natively multimodal reasoning models, now replaced by [Gemini 3.8 Flash](/docs/latest-model). ## Documentation {% id="documentation" %} Visit the [What's new in Gemini 3.7 Flash](/docs/whats-new-gemini-3.7) page for reference coverage of features and capabilities, or the [Latest model](/docs/latest-model) page for Gemini 3.8 Flash. ## gemini-3.7-flash {% id="gemini-37-flash" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-3.7-flash` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text, Image, Video, Audio, and PDF **Output** Text --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 1,048,576 **Output token limit** 65,536 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="supported" /%} {% /section %} {% section %} **Code execution** {% badge type="supported" /%} {% /section %} {% section %} **Computer use** {% badge type="supported" /%} {% /section %} {% section %} **File search** {% badge type="supported" /%} {% /section %} {% section %} **Flex inference** {% badge type="supported" /%} {% /section %} {% section %} **Function calling** {% badge type="supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Priority inference** {% badge type="supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="supported" /%} {% /section %} {% section %} **Thinking** {% badge type="supported" label="Supported (low, medium, high)" /%} Note: `minimal` is not supported and returns an error. {% /section %} {% section %} **URL context** {% badge type="supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Deprecated: `gemini-3.7-flash` (automatically routed to `gemini-3.8-flash`) --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * August 2026 --- * {% section class="model-property" %} {% icon name="id_card" /%}Model card {% /section %} * [Model card](https://deepmind.google/models/model-cards/gemini-3-7-flash/) {% /table %} # Gemini 3.6 Flash Source: https://aistudio.google.com/docs/models/gemini-3.6-flash Description: Learn about Gemini 3.6 Flash from Google {% callout type="note" %} Gemini 3.6 Flash (`gemini-3.6-flash`) is a previous-generation Flash model that remains available for production use. For our newest Flash model, see [Gemini 3.8 Flash](/docs/models/gemini-3.8-flash). {% /callout %} Gemini 3.6 Flash provides sustained frontier-level intelligence optimized for real-world tasks at a higher speed and lower cost. Designed for the agentic era, it excels at code generation, agentic execution, and spatial reasoning. This model is particularly effective for rapid agentic loops involving complex coding cycles and iterations. {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-3.6-flash" variant="ais" %}Try in Google AI Studio{% /button %} ## Documentation {% id="documentation" %} Visit the [What's new in Gemini 3.6 Flash and 3.5 Flash-Lite](/docs/whats-new-gemini-3.6) page for full coverage of features and capabilities. ## gemini-3.6-flash {% id="gemini-36-flash" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-3.6-flash` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text, Image, Video, Audio, and PDF **Output** Text --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 1,048,576 **Output token limit** 65,536 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="supported" /%} {% /section %} {% section %} **Code execution** {% badge type="supported" /%} {% /section %} {% section %} **Computer use** {% badge type="supported" /%} {% /section %} {% section %} **File search** {% badge type="supported" /%} {% /section %} {% section %} **Flex inference** {% badge type="supported" /%} {% /section %} {% section %} **Function calling** {% badge type="supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Priority inference** {% badge type="supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="supported" /%} {% /section %} {% section %} **Thinking** {% badge type="supported" /%} {% /section %} {% section %} **URL context** {% badge type="supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Stable: `gemini-3.6-flash` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * July 2026 --- * {% section class="model-property" %} {% icon name="id_card" /%}Model card {% /section %} * [Model card](https://deepmind.google/models/model-cards/gemini-3-6-flash/) --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-3.6-flash) {% /table %} # Gemini 3.5 Flash Source: https://aistudio.google.com/docs/models/gemini-3.5-flash Description: Learn about Gemini 3.5 Flash from Google {% callout type="caution" %} **Deprecated:** Gemini 3.5 Flash (`gemini-3.5-flash`) is deprecated and has been replaced by [Gemini 3.6 Flash (`gemini-3.6-flash`)](/docs/models/gemini-3.6-flash). It is no longer available to select in Google AI Studio, and API requests to `gemini-3.5-flash` are automatically routed to `gemini-3.6-flash`. Update your model string to `gemini-3.6-flash` (or [Gemini 3.8 Flash](/docs/models/gemini-3.8-flash)). {% /callout %} Gemini 3.5 Flash is a deprecated earlier-generation Flash model that provided sustained frontier-level intelligence optimized for real-world tasks at a higher speed and lower cost. ## Documentation {% id="documentation" %} Visit the [What's new in Gemini 3.5 Flash](/docs/whats-new-gemini-3.5) page for full coverage of features and capabilities. ## gemini-3.5-flash {% id="gemini-35-flash" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-3.5-flash` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text, Image, Video, Audio, and PDF **Output** Text --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 1,048,576 **Output token limit** 65,536 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="supported" /%} {% /section %} {% section %} **Code execution** {% badge type="supported" /%} {% /section %} {% section %} **Computer use** {% badge type="supported" /%} {% /section %} {% section %} **File search** {% badge type="supported" /%} {% /section %} {% section %} **Flex inference** {% badge type="supported" /%} {% /section %} {% section %} **Function calling** {% badge type="supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Priority inference** {% badge type="supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="supported" /%} {% /section %} {% section %} **Thinking** {% badge type="supported" /%} {% /section %} {% section %} **URL context** {% badge type="supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Deprecated: `gemini-3.5-flash` (automatically routed to `gemini-3.6-flash`) * Preview: `gemini-3-flash-preview` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * May 2026 --- * {% section class="model-property" %} {% icon name="id_card" /%}Model card {% /section %} * [Model card](https://deepmind.google/models/model-cards/gemini-3-5-flash/) {% /table %} # Gemini 3.5 Flash-Lite Source: https://aistudio.google.com/docs/models/gemini-3.5-flash-lite Description: Learn about Gemini 3.5 Flash-Lite from Google Gemini 3.5 Flash-Lite is a low-latency, cost-effective multimodal model optimized for high-throughput, low-cost execution for subagent tasks and document parsing. The model supports text, image, video, audio, and PDF inputs, and is designed for high-volume agentic workflows, simple data extraction, and applications where latency and API cost are the primary constraints. {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-3.5-flash-lite" variant="ais" %}Try in Google AI Studio{% /button %} ## Documentation {% id="documentation" %} Visit the [What's new in Gemini 3.6 Flash and 3.5 Flash-Lite](/docs/whats-new-gemini-3.6) page for full coverage of features and capabilities. ## gemini-3.5-flash-lite {% id="gemini-35-flash-lite" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-3.5-flash-lite` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text, Image, Video, Audio, and PDF **Output** Text --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 1,048,576 **Output token limit** 65,536 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="supported" /%} {% /section %} {% section %} **Code execution** {% badge type="supported" /%} {% /section %} {% section %} **Computer use** {% badge type="supported" /%} {% /section %} {% section %} **File search** {% badge type="supported" /%} {% /section %} {% section %} **Flex inference** {% badge type="supported" /%} {% /section %} {% section %} **Function calling** {% badge type="supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Priority inference** {% badge type="supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="supported" /%} {% /section %} {% section %} **Thinking** {% badge type="supported" /%} {% /section %} {% section %} **URL context** {% badge type="supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Stable: `gemini-3.5-flash-lite` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * July 2026 --- * {% section class="model-property" %} {% icon name="id_card" /%}Model card {% /section %} * [Model card](https://deepmind.google/models/model-cards/gemini-3-5-flash-lite/) --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-3.5-flash-lite) {% /table %} # Gemini Omni Flash Source: https://aistudio.google.com/docs/models/gemini-omni-flash Description: Learn about the Gemini Omni Flash video generation and editing model Gemini Omni Flash is a high-performance model for fast, conversational video generation and editing. It excels at turning text and images into video, lets you refine and edit generated videos through natural language conversations using the Interactions API, and supports video extension, resolution upscaling, and advanced interpolation. {% button href="https://aistudio.google.com?model=gemini-omni-1.1-flash" variant="ais" %}Try in Google AI Studio{% /button %} ## Documentation {% id="documentation" %} Visit the [Gemini Omni Flash](/docs/omni) page for full coverage of features and capabilities. ## gemini-omni-1.1-flash {% id="gemini-omni-1.1-flash" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * **Gemini API** `gemini-omni-1.1-flash` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Input** Text, Image, Video (up to 10s for editing and extension) **Output** Video --- * {% section class="model-property" %} {% icon name="token_auto" /%}Limits {% /section %} * **Context window** 1,048,576 tokens **Output video** 3s-10s (360p/720p/1080p/4K, 24 FPS) --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Stable: `gemini-omni-1.1-flash` * Shut down: `gemini-omni-flash-preview` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * August 2026 --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-omni-1.1-flash) {% /table %} # Gemini 3.5 Transcribe Source: https://aistudio.google.com/docs/models/gemini-3.5-transcribe Description: Learn about the Gemini 3.5 Transcribe model from Google Gemini 3.5 Transcribe is a speech-to-text model based on Gemini's audio understanding capabilities. It provides low-latency, accurate transcription with utterance-based language detection, speaker diarization, word-level timestamps, Smart transcription, and custom vocabulary speech biasing. {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-3.5-transcribe" variant="ais" %} Try in Google AI Studio {% /button %} ## Documentation {% id="documentation" %} Gemini 3.5 Transcribe converts speech to text from audio files. It automatically detects 85+ languages, handles multi-language code-switching, identifies individual speakers, outputs word-level timestamps, and adapts to domain-specific terms through custom vocabulary biasing. Visit the [Audio transcription](/docs/transcribe) guide for full coverage of non-streaming features. For real-time, low-latency streaming transcription over WebSockets, visit the [Live transcription](/docs/live-api/live-transcribe) guide using `gemini-3.5-transcribe-live`. For detailed pricing, see the [Pricing page](/docs/pricing#gemini-3.5-transcribe). ## gemini-3.5-transcribe {% id="gemini-35-transcribe" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-3.5-transcribe` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Audio (up to 1 hour) **Output** Text, Word annotations --- * {% section class="model-property" %} {% icon name="token_auto" /%}Audio limits {% /section %} * **Unary audio limit** Up to 1 hour per request (up to 30 minutes when speaker diarization or word-level timestamps are enabled) --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **[Audio transcription](/docs/transcribe)** {% badge type="supported" /%} {% /section %} {% section %} **[Speaker diarization](/docs/transcribe#speaker-diarization)** {% badge type="supported" /%} {% /section %} {% section %} **[Word-level timestamps](/docs/transcribe#word-timestamps)** {% badge type="supported" /%} {% /section %} {% section %} **[Custom vocabulary](/docs/transcribe#custom-vocabulary)** {% badge type="supported" /%} {% /section %} {% section %} **[Smart transcription](/docs/transcribe#transcription-modes)** {% badge type="supported" /%} {% /section %} {% section %} **[Caching](/docs/caching)** {% badge type="not-supported" /%} {% /section %} {% section %} **[Code execution](/docs/code-execution)** {% badge type="not-supported" /%} {% /section %} {% section %} **[File search](/docs/file-search)** {% badge type="not-supported" /%} {% /section %} {% section %} **[Function calling](/docs/function-calling)** {% badge type="not-supported" /%} {% /section %} {% section %} **[Image generation](/docs/image-generation)** {% badge type="not-supported" /%} {% /section %} {% section %} **[Thinking](/docs/thinking)** {% badge type="not-supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="speed" /%}Consumption options {% /section %} * {% section class="three-column-grid" %} {% section %} **[Batch API](/docs/batch-api)** {% badge type="not-supported" /%} {% /section %} {% section %} **[Flex inference](/docs/flex-inference)** {% badge type="not-supported" /%} {% /section %} {% section %} **[Priority inference](/docs/priority-inference)** {% badge type="not-supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * `gemini-3.5-transcribe` (Unary) * `gemini-3.5-transcribe-live` (Live API) --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * August 2026 --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Gemini 3.5 Transcribe](/docs/pricing#gemini-3.5-transcribe) \ [Gemini 3.5 Transcribe Live](/docs/pricing#gemini-3.5-transcribe-live) {% /table %} ## Feature support and limitations {% id="feature-support-and-limitations" %} Gemini 3.5 Transcribe supports the following features across its two endpoints: | Feature | Live Streaming (`gemini-3.5-transcribe-live`) | Audio File Processing (`gemini-3.5-transcribe`) | Notes / Limitations | | :--- | :--- | :--- | :--- | | **Language Auto-detection** | Supported (85+ languages) | Supported (85+ languages) | Includes mid-session code-mixing. | | **Word-level Timestamps** | Not Supported | Supported | Degrades transcription accuracy. Incompatible with custom vocabulary. | | **Custom Vocabulary Biasing** | Supported (up to 1,000 terms) | Supported (up to 1,000 terms) | Customers typically see best results with up to 100 terms. Incompatible with diarization and timestamps. | | **Smart Dictation & Formatting** | Supported | Supported | Includes filler word removal and intent-aware alphanumeric formatting. | | **Speaker Diarization** | Not Supported | Supported (up to 8 speakers) | Attribution for 3+ speakers is experimental. Incompatible with custom vocabulary. | | **Max Audio Duration** | 10 minutes per session. | Up to 1 hour | File processing is limited to 30 minutes when features like diarization or timestamps are enabled. | ## Supported languages {% id="supported-languages" %} The following languages and BCP-47 language codes are supported for Gemini 3.5 Transcribe: | Language | BCP-47 Code | Language | BCP-47 Code | | :--- | :--- | :--- | :--- | | Afrikaans | `af-ZA` | Japanese | `ja-JP` | | Amharic | `am-ET` | Javanese | `jv-ID` | | Arabic (Egypt) | `ar-EG` | Kabuverdianu | `kea-CV` | | Armenian | `hy-AM` | Kannada | `kn-IN` | | Assamese | `as-IN` | Kazakh | `kk-KZ` | | Azerbaijani | `az-AZ` | Korean | `ko-KR` | | Belarusian | `be-BY` | Kyrgyz | `ky-KG` | | Bengali (Bangladesh) | `bn-BD` | Latvian | `lv-LV` | | Bengali (India) | `bn-IN` | Lingala | `ln-CD` | | Bosnian | `bs-BA` | Lithuanian | `lt-LT` | | Bulgarian | `bg-BG` | Macedonian | `mk-MK` | | Bulgarian (Aromanian) | `rup-BG` | Malay | `ms-MY` | | Burmese | `my-MM` | Malayalam | `ml-IN` | | Cantonese (Traditional) | `yue-Hant-HK` | Maltese | `mt-MT` | | Catalan | `ca-ES` | Mandarin Chinese (Simplified) | `cmn-Hans-CN` | | Cebuano | `ceb` | Marathi | `mr-IN` | | Central Khmer | `km-KH` | Mongolian | `mn-MN` | | Croatian | `hr-HR` | Nepali | `ne-NP` | | Czech | `cs-CZ` | Norwegian | `nb-NO` | | Danish | `da-DK` | Oriya | `or-IN` | | Dutch | `nl-NL` | Polish | `pl-PL` | | English (Great Britain) | `en-GB` | Portuguese (Brazil) | `pt-BR` | | English (India) | `en-IN` | Portuguese (Portugal) | `pt-PT` | | English (United States) | `en-US` | Punjabi | `pa-IN` | | Estonian | `et-EE` | Punjabi (Gurmukhi script) | `pa-Guru-IN` | | Farsi | `fa-IR` | Romanian | `ro-RO` | | Filipino | `fil-PH` | Russian | `ru-RU` | | Finnish | `fi-FI` | Serbian | `sr-RS` | | French | `fr-FR` | Sindhi (Arabic script) | `sd-Arab-IN` | | Galician | `gl-ES` | Slovak | `sk-SK` | | Georgian | `ka-GE` | Slovenian | `sl-SI` | | German | `de-DE` | Spanish (Latin America) | `es-419` | | Greek | `el-GR` | Spanish (United States) | `es-US` | | Gujarati | `gu-IN` | Swahili (Kenya) | `sw-KE` | | Hausa | `ha-NG` | Swedish | `sv-SE` | | Hebrew | `he-IL` | Tajik | `tg-TJ` | | Hindi | `hi-IN` | Telugu | `te-IN` | | Hungarian | `hu-HU` | Thai | `th-TH` | | Icelandic | `is-IS` | Turkish | `tr-TR` | | Indian English | `en-IN` | Ukrainian | `uk-UA` | | Indonesian | `id-ID` | Uzbek | `uz-UZ` | | Italian | `it-IT` | Vietnamese | `vi-VN` | # Gemini 3.1 Flash Lite image Source: https://aistudio.google.com/docs/models/gemini-3.1-flash-lite-image Description: Learn about Gemini 3.1 Flash Lite Image from Google **Nano Banana 2 Lite** is designed as the efficiency specialist of the image generation family, offering ultra-low latency and cost-effective image generation and editing. By targeting a sub-2 second latency and significantly reduced TPU compute costs, this model enables high-volume interactive developer use cases and real-time consumer applications. **Key capabilities:** * **Sub-2 second end-to-end latency** * **Interleaved generation and editing** with native support for Text -> Text + Image(s) and Image + Text -> Text + Image(s). * **Optimized for lower resolutions** of 1K (1024x1024px). * Supports a discrete set of **14 aspect ratios** including standard formats. * **Fast multi-turn local edits** (swapping colors, sticker creation, background adjustments). * Maintains high character alignment matching original Nano Banana standards. * New `1:1`, `3:2`, `2:3`, `3:4`, `4:3`, `4:5`, `5:4`, `9:16`, `16:9`, `21:9` aspect ratios. * Supported `image_size` values: `1024px` (1K). *(Note: 2K and 4K are unsupported).* * **SynthID watermarking (Always On) + C2PA**. {% button href="https://aistudio.google.com?model=gemini-3.1-flash-lite-image" variant="ais" %}Try in Google AI Studio{% /button %} ## Documentation {% id="documentation" %} Visit the [Image generation](/docs/image-generation) page for full coverage of features and capabilities. ## gemini-3.1-flash-lite-image {% id="gemini-31-flash-lite-image" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-3.1-flash-lite-image` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text, Image, Video, and PDF **Output** Image and Text --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 65,536 **Output token limit** 4,096 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="not-supported" /%} {% /section %} {% section %} **Code execution** {% badge type="not-supported" /%} {% /section %} {% section %} **File search** {% badge type="not-supported" /%} {% /section %} {% section %} **Flex inference** {% badge type="not-supported" /%} {% /section %} {% section %} **Function calling** {% badge type="not-supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="not-supported" /%} {% /section %} {% section %} **Image generation** {% badge type="supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Priority inference** {% badge type="not-supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="not-supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="not-supported" /%} {% /section %} {% section %} **Thinking** {% badge type="supported" %}Supported (minimal and high){% /badge %} {% /section %} {% section %} **URL context** {% badge type="not-supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Stable: `gemini-3.1-flash-lite-image` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * June 2026 --- * {% section class="model-property" %} {% icon name="id_card" /%}Model card {% /section %} * [Model card](https://deepmind.google/models/model-cards/gemini-3-1-flash-lite-image/) --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-3.1-flash-lite-image) {% /table %} # Gemini 3.5 Live translate Source: https://aistudio.google.com/docs/models/gemini-3.5-live-translate-preview Description: Learn about the Gemini 3.5 Live Translate model from Google Gemini 3.5 Live Translate is our low-latency, audio-to-audio model optimized for real-time translation of spoken conversations. It enables seamless, bidirectional translation with high accuracy and natural voice output. {% button href="https://aistudio.google.com/live?model=gemini-3.5-live-translate-preview" variant="ais" %} Try in Google AI Studio {% /button %} ## Documentation {% id="documentation" %} Visit the [Live Translation](/docs/live-api/live-translate) guide for full coverage of features and capabilities. ## gemini-3.5-live-translate-preview {% id="gemini-35-live-translate-preview" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-3.5-live-translate-preview` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Audio (speech) **Output** Audio (translated speech) and Text (transcript) --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 131,072 **Output token limit** 65,536 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **[Audio generation](/docs/speech-generation)** {% badge type="supported" /%} {% /section %} {% section %} **[Caching](/docs/caching)** {% badge type="not-supported" /%} {% /section %} {% section %} **[Code execution](/docs/code-execution)** {% badge type="not-supported" /%} {% /section %} {% section %} **[File search](/docs/file-search)** {% badge type="not-supported" /%} {% /section %} {% section %} **[Function calling](/docs/function-calling)** {% badge type="not-supported" /%} {% /section %} {% section %} **[Grounding with Google Maps](/docs/maps-grounding)** {% badge type="not-supported" /%} {% /section %} {% section %} **[Image generation](/docs/image-generation)** {% badge type="not-supported" /%} {% /section %} {% section %} **[Live API](/docs/live-api)** {% badge type="supported" /%} {% /section %} {% section %} **[Live translation](/docs/live-api/live-translate)** {% badge type="supported" /%} {% /section %} {% section %} **[Search grounding](/docs/google-search)** {% badge type="not-supported" /%} {% /section %} {% section %} **[Structured outputs](/docs/structured-output)** {% badge type="not-supported" /%} {% /section %} {% section %} **[Thinking](/docs/thinking)** {% badge type="not-supported" /%} {% /section %} {% section %} **[URL context](/docs/url-context)** {% badge type="not-supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="speed" /%}Consumption options {% /section %} * {% section class="three-column-grid" %} {% section %} **[Batch API](/docs/batch-api)** {% badge type="not-supported" /%} {% /section %} {% section %} **[Flex inference](/docs/flex-inference)** {% badge type="not-supported" /%} {% /section %} {% section %} **[Priority inference](/docs/priority-inference)** {% badge type="not-supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Preview: `gemini-3.5-live-translate-preview` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * June 2026 --- * {% section class="model-property" %} {% icon name="id_card" /%}Model card {% /section %} * [Model card](https://deepmind.google/models/model-cards/gemini-3-5-audio/) --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-3.5-live-translate-preview) {% /table %} # Gemini 3 Flash preview Source: https://aistudio.google.com/docs/models/gemini-3-flash-preview Description: Learn about Gemini 3 Flash Preview from Google The best model in the world for multimodal understanding, and our most powerful agentic and vibe-coding model yet, delivering richer visuals and deeper interactivity, all built on a foundation of state-of-the-art reasoning. {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-3-flash-preview" variant="ais" %}Try in Google AI Studio{% /button %} ## Documentation {% id="documentation" %} Visit the [Gemini 3 Developer Guide](/docs/latest-model) page for full coverage of features and capabilities. ## gemini-3-flash-preview {% id="gemini-3-flash-preview" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-3-flash-preview` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text, Image, Video, Audio, and PDF **Output** Text --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 1,048,576 **Output token limit** 65,536 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="supported" /%} {% /section %} {% section %} **Code execution** {% badge type="supported" /%} {% /section %} {% section %} **Computer use** {% badge type="supported" /%} {% /section %} {% section %} **File search** {% badge type="supported" /%} {% /section %} {% section %} **Flex inference** {% badge type="supported" /%} {% /section %} {% section %} **Function calling** {% badge type="supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Priority inference** {% badge type="supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="supported" /%} {% /section %} {% section %} **Thinking** {% badge type="supported" /%} {% /section %} {% section %} **URL context** {% badge type="supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * `Preview: gemini-3-flash-preview` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * December 2025 --- * {% section class="model-property" %} {% icon name="id_card" /%}Model card {% /section %} * [Model card](https://deepmind.google/models/model-cards/gemini-3-flash/) --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-3-flash-preview) {% /table %} # Gemini 3.1 Flash TTS (text-to-speech) preview Source: https://aistudio.google.com/docs/models/gemini-3.1-flash-tts-preview Description: Learn about Gemini 3.1 Flash TTS Preview model from Google {% callout type="note" %} `gemini-3.1-flash-tts-preview` is a legacy preview model. For new and production workloads, migrate to [Gemini 3.8 Flash TTS](/docs/models/gemini-3.8-flash-tts) (`gemini-3.8-flash-tts`) or [Gemini 3.8 Flash-Lite TTS](/docs/models/gemini-3.8-flash-lite-tts) (`gemini-3.8-flash-lite-tts`). See the [migration guide](/docs/speech-generation#migration). {% /callout %} The Gemini 3.1 Flash TTS Preview model provides powerful, low-latency speech generation with natural outputs, steerable prompts, and expressive audio tags for precise narration control. {% button href="https://aistudio.google.com?model=gemini-3.1-flash-tts-preview" variant="ais" %}Try in Google AI Studio{% /button %} ## Documentation {% id="documentation" %} The Gemini 3.1 Flash TTS Preview model introduces expressive [audio tags](/docs/speech-generation#controllable) for controlling narration, as well as overall improvements to naturalness, controllability, and multilinguality. Visit the [Text-to-Speech](/docs/speech-generation) guide for full coverage of features and capabilities. ## gemini-3.1-flash-tts-preview {% id="gemini-31-flash-tts-preview" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-3.1-flash-tts-preview` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text **Output** Audio --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 8,192 **Output token limit** 16,384 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="not-supported" /%} {% /section %} {% section %} **Code execution** {% badge type="not-supported" /%} {% /section %} {% section %} **File search** {% badge type="not-supported" /%} {% /section %} {% section %} **Function calling** {% badge type="not-supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="not-supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="not-supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="not-supported" /%} {% /section %} {% section %} **Thinking** {% badge type="not-supported" /%} {% /section %} {% section %} **URL context** {% badge type="not-supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * `gemini-3.1-flash-tts-preview` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * April 2026 --- * {% section class="model-property" %} {% icon name="id_card" /%}Model card {% /section %} * [Model card](https://deepmind.google/models/model-cards/gemini-3-1-flash-audio/) --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-3.1-flash-tts-preview) {% /table %} # Veo 3.1 Lite preview Source: https://aistudio.google.com/docs/models/veo-3.1-lite-generate-preview Description: Learn about the Veo 3.1 video generation model from Google {% callout type="warning" %} `veo-3.1-lite-generate-preview` was [shut down](/docs/deprecations) on **October 22, 2026**; migrate to [Gemini Omni Flash](/docs/models/gemini-omni-flash) (`gemini-omni-1.1-flash`) or the GA models available through the [Gemini Enterprise Agent Platform](https://docs.cloud.google.com/gemini-enterprise-agent-platform/models/veo/3-1-generate) to avoid service interruptions. {% /callout %} Veo 3.1 Lite Preview is a high-efficiency, developer-first video model providing high-fidelity video generation, editing, and cinematic control. It leverages the state-of-the-art Veo 3.1 model to democratize professional-grade video AI by offering a scalable, programmable interface for creators and enterprises. ## Documentation {% id="documentation" %} Visit the [Video generation](/docs/video) page for full coverage of features and capabilities. Note that Veo 3.1 Lite Preview does not support [4K outputs](/docs/veo#resolution) or [Extension](/docs/veo#extending-veo-videos). ## veo-3.1-lite-generate-preview {% id="veo-31-lite-generate-preview" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * **Gemini API** `veo-3.1-lite-generate-preview` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Input** Text, Image **Output** Video with audio --- * {% section class="model-property" %} {% icon name="token_auto" /%}Limits {% /section %} * **Text input** 1,024 tokens **Output video** 1 --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * March 2026 {% /table %} # Gemini 3.1 Flash live preview Source: https://aistudio.google.com/docs/models/gemini-3.1-flash-live-preview Description: Learn about the Gemini 3.1 Flash Live Preview model from Google Gemini 3.1 Flash Live Preview is our legacy preview audio-to-audio model for real-time dialogue and voice-first AI applications. {% callout type="note" %} For new applications and production workloads, we recommend migrating to [Gemini 3.8 Live](/docs/models/gemini-3.8-live) (`gemini-3.8-live`) or [Gemini 3.8 Live Extended Thinking](/docs/models/gemini-3.8-live-extended-thinking) (`gemini-3.8-live-extended-thinking`). {% /callout %} {% button href="https://aistudio.google.com/live?model=gemini-3.1-flash-live-preview" variant="ais" %} Try in Google AI Studio {% /button %} ## Documentation {% id="documentation" %} Visit the [Live API](/docs/live-api) guide for full coverage of features and capabilities. ## gemini-3.1-flash-live-preview {% id="gemini-31-flash-live-preview" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-3.1-flash-live-preview` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text, images, audio **Output** Text and audio --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 131,072 **Output token limit** 65,536 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="supported" /%} {% /section %} {% section %} **Batch API** {% badge type="not-supported" /%} {% /section %} {% section %} **Caching** {% badge type="not-supported" /%} {% /section %} {% section %} **Code execution** {% badge type="not-supported" /%} {% /section %} {% section %} **File search** {% badge type="not-supported" /%} {% /section %} {% section %} **Function calling** {% badge type="supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="not-supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="not-supported" /%} {% /section %} {% section %} **Thinking** {% badge type="supported" /%} {% /section %} {% section %} **URL context** {% badge type="not-supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Preview: `gemini-3.1-flash-live-preview` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * March 2026 --- * {% section class="model-property" %} {% icon name="id_card" /%}Model card {% /section %} * [Model card](https://deepmind.google/models/model-cards/gemini-3-1-flash-audio/) --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-3.8-live) {% /table %} ## Migrating from Gemini 2.5 Flash Live {% id="migrating" %} Gemini 3.1 Flash Live Preview is optimized for low-latency, real-time dialogue. When migrating from `gemini-2.5-flash-native-audio-preview-12-2025`, consider the following: - **Model string**: Update your model string from `gemini-2.5-flash-native-audio-preview-12-2025` to `gemini-3.1-flash-live-preview`. - **Thinking configuration**: Gemini 3.1 uses `thinkingLevel` (with settings like `minimal`, `low`, `medium`, and `high`) instead of `thinkingBudget`. The default is `minimal` to optimize for lowest latency. See [Thinking levels and budgets](/docs/thinking?generate-content=true#levels-budgets). - **Server events**: A single [`BidiGenerateContentServerContent`](https://ai.google.dev/api/live#bidigeneratecontentservercontent) event can now contain multiple content parts simultaneously (for example, audio chunks and transcript). Update your code to process all parts in each event to avoid missing content. - **Client content**: `send_client_content` is supported for appending text or structured context turns mid-session as well as seeding initial history (setting [`initial_history_in_client_content`](https://ai.google.dev/api/live#HistoryConfig) in [`history_config`](https://ai.google.dev/api/live#BidiGenerateContentSetup)). You can also use [`send_realtime_input`](https://ai.google.dev/api/live#bidigeneratecontentrealtimeinput) to stream realtime text, audio, or video chunks. See [Incremental content updates](/docs/live-api/capabilities#incremental-updates). - **Turn coverage**: Defaults to [`TURN_INCLUDES_AUDIO_ACTIVITY_AND_ALL_VIDEO`](https://ai.google.dev/api/live#turncoverage) instead of `TURN_INCLUDES_ONLY_ACTIVITY`. The model's turn now includes detected audio activity and all video frames. If your application currently sends a constant stream of video frames, you may want to update your application to only send video frames when there is audio activity to avoid incurring additional costs. - **Async function calling**: Not yet supported. Function calling is synchronous only. The model will not start responding until you've sent the tool response. See [Async function calling](/docs/live-api/tools#async-function-calling). - **Proactive audio and affective dialogue**: These features are not yet supported in Gemini 3.1 Flash Live. Remove any configuration for these features from your code. See [Proactive audio](/docs/live-api/capabilities#proactive-audio) and [Affective dialogue](/docs/live-api/capabilities#affective-dialog). For a detailed feature comparison, see the [Model comparison](/docs/live-api/capabilities#model-comparison) table in the capabilities guide. # Gemini 3.1 Flash-Lite Source: https://aistudio.google.com/docs/models/gemini-3.1-flash-lite Description: Learn about Gemini 3.1 Flash-Lite from Google Gemini 3.1 Flash-Lite is a low-latency, cost-effective multimodal model optimized for high-frequency, lightweight tasks. The model supports text, image, video, audio, and PDF inputs, and is designed for high-volume agentic workflows, simple data extraction, and applications where latency and API cost are the primary constraints. {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-3.1-flash-lite" variant="ais" %}Try in Google AI Studio{% /button %} ## gemini-3.1-flash-lite {% id="gemini-31-flash-lite" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-3.1-flash-lite` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text, Image, Video, Audio, and PDF **Output** Text --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 1,048,576 **Output token limit** 65,536 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="supported" /%} {% /section %} {% section %} **Code execution** {% badge type="supported" /%} {% /section %} {% section %} **Computer use** {% badge type="not-supported" /%} {% /section %} {% section %} **File search** {% badge type="supported" /%} {% /section %} {% section %} **Flex inference** {% badge type="supported" /%} {% /section %} {% section %} **Function calling** {% badge type="supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Priority inference** {% badge type="supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="supported" /%} {% /section %} {% section %} **Thinking** {% badge type="supported" /%} {% /section %} {% section %} **URL context** {% badge type="supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * `Stable: gemini-3.1-flash-lite` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * May 2026 --- * {% section class="model-property" %} {% icon name="id_card" /%}Model card {% /section %} * [Model card](https://deepmind.google/models/model-cards/gemini-3-1-flash-lite/) --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-3.1-flash-lite) {% /table %} ## Developer guide {% id="developer-guide" %} Gemini 3.1 Flash-Lite is best at handling straightforward tasks at significant scale. Here are some use cases best suited for Gemini 3.1 Flash-Lite: * **Translation**: Fast, cheap, high-volume translation, such as processing chat messages, reviews, and support tickets at scale. You can use system instructions to constrain output to only the translated text with no extra commentary: ```python from google import genai client = genai.Client() text = "Hey, are you down to grab some pizza later? I'm starving!" response = client.models.generate_content( model="gemini-3.1-flash-lite", config={ "system_instruction": "Only output the translated text" }, contents=f"Translate the following text to German: {text}" ) print(response.text) ``` * **Transcription**: Process recordings, voice notes, or any audio content where you need a text transcript without spinning up a separate speech-to-text pipeline. Supports multimodal inputs, so you can pass audio files directly for transcription: ```python from google import genai client = genai.Client() uploaded_file = client.files.upload(file='sample.mp3') prompt = 'Generate a transcript of the audio.' response = client.models.generate_content( model="gemini-3.1-flash-lite", contents=[prompt, uploaded_file] ) print(response.text) ``` * **Lightweight agentic tasks and data extraction**: Entity extraction, classification, and lightweight data processing pipelines supported with structured JSON output. For example, extracting structured data from an e-commerce customer review: ```python from google import genai from pydantic import BaseModel, Field client = genai.Client() prompt = "Analyze the user review and determine the aspect, sentiment score, summary quote, and return risk" input_text = "The boots look amazing and the leather is high quality, but they run way too small. I'm sending them back." class ReviewAnalysis(BaseModel): aspect: str = Field(description="The feature mentioned (e.g., Price, Comfort, Style, Shipping)") summary_quote: str = Field(description="The specific phrase from the review about this aspect") sentiment_score: int = Field(description="1 to 5 (1=worst, 5=best)") is_return_risk: bool = Field(description="True if the user mentions returning the item") response = client.models.generate_content( model="gemini-3.1-flash-lite", contents=[prompt, input_text], config={ "response_mime_type": "application/json", "response_json_schema": ReviewAnalysis.model_json_schema(), }, ) print(response.text) ``` * **Document processing and summarization**: Parse PDFs and return concise summaries, like for building a document processing pipeline or quickly triaging incoming files: ```python from google import genai from google.genai import types import httpx client = genai.Client() doc_url = "https://storage.googleapis.com/generativeai-downloads/data/med_gemini.pdf" doc_data = httpx.get(doc_url).content prompt = "Summarize this document" response = client.models.generate_content( model="gemini-3.1-flash-lite", contents=[ types.Part.from_bytes( data=doc_data, mime_type='application/pdf', ), prompt ] ) print(response.text) ``` * **Model routing**: Use a low-latency and low-cost model as a classifier that routes queries to the appropriate model based on task complexity. This is a real pattern in production - the open-source [Gemini CLI](https://geminicli.com/docs/core/#model-fallback) uses Flash-Lite to classify task complexity and route to Flash or Pro accordingly. ```python from google import genai client = genai.Client() FLASH_MODEL = 'flash' PRO_MODEL = 'pro' CLASSIFIER_SYSTEM_PROMPT = f""" You are a specialized Task Routing AI. Your sole function is to analyze the user's request and classify its complexity. Choose between `{FLASH_MODEL}` (SIMPLE) or `{PRO_MODEL}` (COMPLEX). 1. `{FLASH_MODEL}`: A fast, efficient model for simple, well-defined tasks. 2. `{PRO_MODEL}`: A powerful, advanced model for complex, open-ended, or multi-step tasks. A task is COMPLEX if it meets ONE OR MORE of the following criteria: 1. High Operational Complexity (Est. 4+ Steps/Tool Calls) 2. Strategic Planning and Conceptual Design 3. High Ambiguity or Large Scope 4. Deep Debugging and Root Cause Analysis A task is SIMPLE if it is highly specific, bounded, and has Low Operational Complexity (Est. 1-3 tool calls). """ user_input = "I'm getting an error 'Cannot read property 'map' of undefined' when I click the save button. Can you fix it?" response_schema = { "type": "object", "properties": { "reasoning": { "type": "string", "description": "A brief, step-by-step explanation for the model choice, referencing the rubric." }, "model_choice": { "type": "string", "enum": [FLASH_MODEL, PRO_MODEL] } }, "required": ["reasoning", "model_choice"] } response = client.models.generate_content( model="gemini-3.1-flash-lite", contents=user_input, config={ "system_instruction": CLASSIFIER_SYSTEM_PROMPT, "response_mime_type": "application/json", "response_json_schema": response_schema }, ) print(response.text) ``` * **Thinking**: For better accuracy for tasks that benefit from step-by-step reasoning, configure thinking so the model spends additional compute on internal reasoning before producing the final output: ```python from google import genai from google.genai import types client = genai.Client() response = client.models.generate_content( model="gemini-3.1-flash-lite", contents="How does AI work?", config=types.GenerateContentConfig( thinking_config=types.ThinkingConfig(thinking_level="high") ), ) print(response.text) ``` # Gemini 3.1 Flash-Lite preview Source: https://aistudio.google.com/docs/models/gemini-3.1-flash-lite-preview Description: Learn about Gemini 3.1 Flash-Lite preview from Google {% callout type="warning" %} Gemini 3.1 Flash-Lite Preview is [deprecated](/docs/deprecations) and has been shut down on May 25, 2026. Migrate to [Gemini 3.1 Flash-Lite](/docs/models/gemini-3.1-flash-lite) to avoid service disruption. {% /callout %} ## gemini-3.1-flash-lite-preview {% id="gemini-31-flash-lite-preview" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-3.1-flash-lite-preview` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text, Image, Video, Audio, and PDF **Output** Text --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 1,048,576 **Output token limit** 65,536 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="supported" /%} {% /section %} {% section %} **Code execution** {% badge type="supported" /%} {% /section %} {% section %} **Computer use** {% badge type="not-supported" /%} {% /section %} {% section %} **File search** {% badge type="supported" /%} {% /section %} {% section %} **Flex inference** {% badge type="supported" /%} {% /section %} {% section %} **Function calling** {% badge type="supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Priority inference** {% badge type="supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="supported" /%} {% /section %} {% section %} **Thinking** {% badge type="supported" /%} {% /section %} {% section %} **URL context** {% badge type="supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * *Shut down*: `gemini-3.1-flash-lite-preview` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * March 2026 --- * {% section class="model-property" %} {% icon name="id_card" /%}Model card {% /section %} * [Model card](https://deepmind.google/models/model-cards/gemini-3-1-flash-lite/) {% /table %} # Gemini 2.5 Flash Source: https://aistudio.google.com/docs/models/gemini-2.5-flash Description: Learn about Gemini 2.5 Flash from Google {% callout type="caution" %} Gemini 2.5 Flash (`gemini-2.5-flash`) is [deprecated](/docs/deprecations#gemini-2.5-flash-models) and is no longer available to select in Google AI Studio (API access is limited to existing users until December 1, 2026). Effective December 1, 2026, all API requests to `gemini-2.5-flash` will automatically route to [Gemini 3.5 Flash-Lite (`gemini-3.5-flash-lite`)](/docs/models/gemini-3.5-flash-lite) and be billed at [Gemini 3.5 Flash-Lite rates](/docs/pricing#gemini-3.5-flash-lite). Before December 1, 2026, update your model string to `gemini-3.5-flash-lite` and review the [Gemini 3.5 Flash-Lite migration guide](/docs/whats-new-gemini-3.6#migrate-to-gemini-3-5-flash-lite). Breaking API changes include function calling and `thought_signature` validation, `thinking_level` replacing `thinking_budget`, and removed sampling parameters and prefilled model turns. {% /callout %} Our best model in terms of price-performance, offering well-rounded capabilities. 2.5 Flash is best for large scale processing, low-latency, high volume tasks that require thinking, and agentic use cases. ## gemini-2.5-flash {% id="gemini-25-flash" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-2.5-flash` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text, images, video, audio **Output** Text --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 1,048,576 **Output token limit** 65,536 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="supported" /%} {% /section %} {% section %} **Code execution** {% badge type="supported" /%} {% /section %} {% section %} **File search** {% badge type="supported" /%} {% /section %} {% section %} **Flex inference** {% badge type="supported" /%} {% /section %} {% section %} **Function calling** {% badge type="supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Priority inference** {% badge type="supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="supported" /%} {% /section %} {% section %} **Thinking** {% badge type="supported" /%} {% /section %} {% section %} **URL context** {% badge type="supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Deprecated: `gemini-2.5-flash` (effective December 1, 2026, automatically routed to `gemini-3.5-flash-lite`) * Shut down: [gemini-2.5-flash-preview-09-2025](/docs/models/gemini-2.5-flash-preview-09-2025) --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * June 2025 --- * {% section class="model-property" %} {% icon name="cognition_2" /%}Knowledge cutoff {% /section %} * January 2025 --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-2.5-flash) {% /table %} # Gemini 2.5 Flash preview Source: https://aistudio.google.com/docs/models/gemini-2.5-flash-preview-09-2025 Description: Learn about Gemini 2.5 Flash Preview from Google {% callout type="warning" %} This model is [shut down](/docs/deprecations) as of February 17, 2026; migrate to [Gemini 2.5 Flash](/docs/models/gemini-2.5-flash) for improved performance. {% /callout %} ## gemini-2.5-flash-preview-09-2025 {% id="gemini-25-flash-preview-09-2025" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-2.5-flash-preview-09-2025` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text, images, video, audio **Output** Text --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 1,048,576 **Output token limit** 65,536 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="supported" /%} {% /section %} {% section %} **Code execution** {% badge type="supported" /%} {% /section %} {% section %} **File search** {% badge type="supported" /%} {% /section %} {% section %} **Function calling** {% badge type="supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="not-supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="supported" /%} {% /section %} {% section %} **Thinking** {% badge type="supported" /%} {% /section %} {% section %} **URL Context** {% badge type="supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Stable: [gemini-2.5-flash](/docs/models/gemini-2.5-flash) * Shut down: `gemini-2.5-flash-preview-09-2025` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * September 2025 --- * {% section class="model-property" %} {% icon name="cognition_2" /%}Knowledge cutoff {% /section %} * January 2025 {% /table %} # Gemini 2.5 Flash image (Nano Banana) Source: https://aistudio.google.com/docs/models/gemini-2.5-flash-image Description: Learn about Gemini 2.5 Flash Image from Google Our best engine for high-velocity visual creation, offering state-of-the-art speed and efficiency. Gemini 2.5 Flash Image, also known as Nano Banana, is best for high-volume generation, conversational image editing, and low-latency creative workflows that require native multimodal understanding. {% button href="https://aistudio.google.com?model=gemini-2.5-flash-image" variant="ais" %}Try in Google AI Studio{% /button %} ## Documentation {% id="documentation" %} Visit the [Image generation](/docs/image-generation) guide for full coverage of features and capabilities. ## gemini-2.5-flash-image {% id="gemini-25-flash-image" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-2.5-flash-image` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Image and Text **Output** Image and Text --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 65,536 **Output token limit** 32,768 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="not-supported" /%} {% /section %} {% section %} **Code execution** {% badge type="not-supported" /%} {% /section %} {% section %} **File search** {% badge type="not-supported" /%} {% /section %} {% section %} **Flex inference** {% badge type="not-supported" /%} {% /section %} {% section %} **Function calling** {% badge type="not-supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="not-supported" /%} {% /section %} {% section %} **Image generation** {% badge type="supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Priority inference** {% badge type="not-supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="not-supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="not-supported" /%} {% /section %} {% section %} **Thinking** {% badge type="not-supported" /%} {% /section %} {% section %} **URL context** {% badge type="not-supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Stable: `gemini-2.5-flash-image` * Deprecated: `gemini-2.5-flash-image-preview` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * October 2025 --- * {% section class="model-property" %} {% icon name="cognition_2" /%}Knowledge cutoff {% /section %} * June 2025 --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-2.5-flash-image) {% /table %} # Gemini 2.5 Flash live preview Source: https://aistudio.google.com/docs/models/gemini-2.5-flash-native-audio-preview-12-2025 Description: Learn about Gemini 2.5 Flash Live from Google The Live API enables low-latency, real-time voice and video interactions with Gemini 2.5 Flash. It processes continuous streams of audio, video, or text to deliver immediate, human-like spoken responses, creating a natural conversational experience for your users. {% button href="https://aistudio.google.com?model=gemini-2.5-flash-native-audio-preview-12-2025" variant="ais" %}Try in Google AI Studio{% /button %} ## Documentation {% id="documentation" %} Visit the [Live API](/docs/live-api) guide for full coverage of features and capabilities. ## gemini-2.5-flash-native-audio-preview-12-2025 {% id="gemini-25-flash-native-audio-preview-12-2025" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-2.5-flash-native-audio-preview-12-2025` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Audio, video, text **Output** Audio and text --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 131,072 **Output token limit** 8,192 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="supported" /%} {% /section %} {% section %} **Batch API** {% badge type="not-supported" /%} {% /section %} {% section %} **Caching** {% badge type="not-supported" /%} {% /section %} {% section %} **Code execution** {% badge type="not-supported" /%} {% /section %} {% section %} **File search** {% badge type="not-supported" /%} {% /section %} {% section %} **Function calling** {% badge type="supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="not-supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="not-supported" /%} {% /section %} {% section %} **Thinking** {% badge type="supported" /%} {% /section %} {% section %} **URL context** {% badge type="not-supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Preview: `gemini-2.5-flash-native-audio-preview-12-2025` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * September 2025 --- * {% section class="model-property" %} {% icon name="cognition_2" /%}Knowledge cutoff {% /section %} * January 2025 --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-2.5-flash-native-audio) {% /table %} # Gemini 2.5 Flash text-to-speech Source: https://aistudio.google.com/docs/models/gemini-2.5-flash-preview-tts Description: Learn about Gemini 2.5 Flash TTS from Google Our fastest engine for high-fidelity speech synthesis, offering low-latency and cost-efficient audio generation. Gemini 2.5 Flash TTS is best for real-time assistants, high-volume narration, and conversational use cases that require fine-grained control over voice style and pacing. {% button href="https://aistudio.google.com?model=gemini-2.5-flash-preview-tts" variant="ais" %}Try in Google AI Studio{% /button %} ## Documentation {% id="documentation" %} Visit the [Text-to-Speech](/docs/speech-generation) guide for full coverage of features and capabilities. ## gemini-2.5-flash-preview-tts {% id="gemini-25-flash-preview-tts" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-2.5-flash-preview-tts` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text **Output** Audio --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 8,192 **Output token limit** 16,384 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="supported" /%} {% /section %} {% section %} **Batch API** {% badge type="not-supported" /%} {% /section %} {% section %} **Caching** {% badge type="not-supported" /%} {% /section %} {% section %} **Code execution** {% badge type="not-supported" /%} {% /section %} {% section %} **File search** {% badge type="not-supported" /%} {% /section %} {% section %} **Function calling** {% badge type="not-supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="not-supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="not-supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="not-supported" /%} {% /section %} {% section %} **Thinking** {% badge type="not-supported" /%} {% /section %} {% section %} **URL context** {% badge type="not-supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * `gemini-2.5-flash-preview-tts` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * December 2025 --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-2.5-flash-preview-tts) {% /table %} # Gemini 2.5 Flash-Lite Source: https://aistudio.google.com/docs/models/gemini-2.5-flash-lite Description: Learn about Gemini 2.5 Flash-Lite from Google {% callout type="note" %} To ensure reliable performance for everyone, we are limiting access to the 2.5 models to users who have actively used them in the past. `gemini-2.5-flash-lite` is not deprecated and will continue to be served until further notice through the API. For any new projects, use our latest models: 3.5 Flash-Lite or 3.8 Flash. This helps us maintain sufficient capacity for both ongoing legacy workflows and new applications. {% /callout %} Our most cost-efficient multimodal model, offering the fastest performance for high-frequency, lightweight tasks. Gemini 2.5 Flash-Lite is best for high-volume classification, simple data extraction, and extremely low-latency applications where budget and speed are the primary constraints. {% button href="https://aistudio.google.com?model=gemini-2.5-flash-lite" variant="ais" %}Try in Google AI Studio{% /button %} ## gemini-2.5-flash-lite {% id="gemini-25-flash-lite" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-2.5-flash-lite` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text, image, video, audio, PDF **Output** Text --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 1,048,576 **Output token limit** 65,536 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="supported" /%} {% /section %} {% section %} **Code execution** {% badge type="supported" /%} {% /section %} {% section %} **File search** {% badge type="supported" /%} {% /section %} {% section %} **Flex inference** {% badge type="supported" /%} {% /section %} {% section %} **Function calling** {% badge type="supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Priority inference** {% badge type="supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="supported" /%} {% /section %} {% section %} **Thinking** {% badge type="supported" /%} {% /section %} {% section %} **URL context** {% badge type="supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Stable: `gemini-2.5-flash-lite` * Shut down: [gemini-2.5-flash-lite-preview-09-2025](/docs/models/gemini-2.5-flash-lite-preview-09-2025) --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * July 2025 --- * {% section class="model-property" %} {% icon name="cognition_2" /%}Knowledge cutoff {% /section %} * January 2025 --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-2.5-flash-lite) {% /table %} # Gemini 2.5 Flash-Lite preview Source: https://aistudio.google.com/docs/models/gemini-2.5-flash-lite-preview-09-2025 Description: Learn about Gemini 2.5 Flash-Lite Preview from Google {% callout type="warning" %} This model is [shut down](/docs/deprecations) as of March 31, 2026. Migrate to [Gemini 3.1 Flash-Lite](/docs/models/gemini-3.1-flash-lite) to avoid service disruption. {% /callout %} ## gemini-2.5-flash-lite-preview-09-2025 {% id="gemini-25-flash-lite-preview-09-2025" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-2.5-flash-lite-preview-09-2025` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text, image, video, audio, PDF **Output** Text --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 1,048,576 **Output token limit** 65,536 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="supported" /%} {% /section %} {% section %} **Code execution** {% badge type="supported" /%} {% /section %} {% section %} **File search** {% badge type="supported" /%} {% /section %} {% section %} **Function calling** {% badge type="supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="not-supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="supported" /%} {% /section %} {% section %} **Thinking** {% badge type="supported" /%} {% /section %} {% section %} **URL context** {% badge type="supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Stable: [gemini-2.5-flash-lite](/docs/models/gemini-2.5-flash-lite) * Shut down: `gemini-2.5-flash-lite-preview-09-2025` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * September 2025 --- * {% section class="model-property" %} {% icon name="cognition_2" /%}Knowledge cutoff {% /section %} * January 2025 {% /table %} # Gemini 2.5 Pro Source: https://aistudio.google.com/docs/models/gemini-2.5-pro Description: Learn about Gemini 2.5 Pro from Google {% callout type="caution" %} Gemini 2.5 Pro (`gemini-2.5-pro`) is [deprecated](/docs/deprecations#gemini-2.5-pro-models) and is no longer available to select in Google AI Studio (API access is limited to existing users until December 1, 2026). Effective December 1, 2026, all API requests to `gemini-2.5-pro` will automatically route to [Gemini 3.8 Flash (`gemini-3.8-flash`)](/docs/models/gemini-3.8-flash) and be billed at [Gemini 3.8 Flash rates](/docs/pricing#gemini-3.8-flash). Before December 1, 2026, update your model string to `gemini-3.8-flash` and review the [Gemini 3.8 Flash migration guide](/docs/whats-new-gemini-3.8#migrate-to-gemini-3-8-flash). Breaking API changes include function calling and `thought_signature` validation, `thinking_level` replacing `thinking_budget`, and removed sampling parameters and prefilled model turns. {% /callout %} Our state-of-the-art thinking model, capable of reasoning over complex problems in code, math, and STEM, as well as analyzing large datasets, codebases, and documents using long context. ## gemini-2.5-pro {% id="gemini-25-pro" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-2.5-pro` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Audio, images, video, text, and PDF **Output** Text --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 1,048,576 **Output token limit** 65,536 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="supported" /%} {% /section %} {% section %} **Code execution** {% badge type="supported" /%} {% /section %} {% section %} **File search** {% badge type="supported" /%} {% /section %} {% section %} **Flex inference** {% badge type="supported" /%} {% /section %} {% section %} **Function calling** {% badge type="supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Priority inference** {% badge type="supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="supported" /%} {% /section %} {% section %} **Thinking** {% badge type="supported" /%} {% /section %} {% section %} **URL context** {% badge type="supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Deprecated: `gemini-2.5-pro` (effective December 1, 2026, automatically routed to `gemini-3.8-flash`) --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * June 2025 --- * {% section class="model-property" %} {% icon name="cognition_2" /%}Knowledge cutoff {% /section %} * January 2025 --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-2.5-pro) {% /table %} # Gemini 2.5 Pro text-to-speech Source: https://aistudio.google.com/docs/models/gemini-2.5-pro-preview-tts Description: Learn about Gemini 2.5 Pro TTS from Google Our premium engine for studio-quality speech synthesis, offering high-fidelity and sophisticated audio generation. Gemini 2.5 Pro TTS is best for long-form content, professional narrations, and complex creative workflows that require the highest level of vocal clarity and natural prosody. {% button href="https://aistudio.google.com?model=gemini-2.5-pro-preview-tts" variant="ais" %}Try in Google AI Studio{% /button %} ## Documentation {% id="documentation" %} Visit the [Text-to-Speech](/docs/speech-generation) guide for full coverage of features and capabilities. ## gemini-2.5-pro-preview-tts {% id="gemini-25-pro-preview-tts" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-2.5-pro-preview-tts` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text **Output** Audio --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 8,192 **Output token limit** 16,384 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="not-supported" /%} {% /section %} {% section %} **Code execution** {% badge type="not-supported" /%} {% /section %} {% section %} **File search** {% badge type="not-supported" /%} {% /section %} {% section %} **Function calling** {% badge type="not-supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="not-supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="not-supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="not-supported" /%} {% /section %} {% section %} **Thinking** {% badge type="not-supported" /%} {% /section %} {% section %} **URL context** {% badge type="not-supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * `gemini-2.5-pro-preview-tts` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * December 2025 --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-2.5-pro-preview-tts) {% /table %} # Gemini 2.5 computer use model Source: https://aistudio.google.com/docs/models/gemini-2.5-computer-use-preview-10-2025 Description: Learn about the Gemini Computer Use model from Google {% callout type="warning" %} This model was [shut down](/docs/deprecations) on **July 28, 2026**; migrate to [Gemini 3.8 Flash](/docs/models/gemini-3.8-flash) or other [Gemini 3](/docs/models#gemini-3) models with built-in [computer use](/docs/computer-use) support to avoid service interruptions. {% /callout %} An agentic capability model designed for direct interface interaction, allowing Gemini to perceive and navigate digital environments. Gemini 2.5 Computer Use is best for browser automation, multi-step software tasks, and UI testing that requires visual reasoning and precise cursor control. ## Documentation {% id="documentation" %} Visit the [Computer use](/docs/computer-use) page for full coverage of features and capabilities. ## gemini-2.5-computer-use-preview-10-2025 {% id="gemini-25-computer-use-preview-10-2025" %} {% partial file="googledevai/en/gemini-api/docs/models/_includes/_computer-use.md" /%} # Gemini 2.0 Flash Source: https://aistudio.google.com/docs/models/gemini-2.0-flash Description: Learn about Gemini 2.0 Flash from Google {% callout type="warning" %} Gemini 2.0 Flash is [deprecated](/docs/deprecations) and has been shut down June 1, 2026. Migrate to [Gemini 3.8 Flash](/docs/models/gemini-3.8-flash) to avoid service disruption. {% /callout %} ## gemini-2.0-flash {% id="gemini-20-flash" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-2.0-flash` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Audio, images, video, and text **Output** Text --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 1,048,576 **Output token limit** 8,192 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="supported" /%} {% /section %} {% section %} **Code execution** {% badge type="supported" /%} {% /section %} {% section %} **File search** {% badge type="not-supported" /%} {% /section %} {% section %} **Function calling** {% badge type="supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="supported" /%} {% /section %} {% section %} **Thinking** Experimental {% /section %} {% section %} **URL context** {% badge type="not-supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * *Shut down*: `gemini-2.0-flash` * *Shut down*: `gemini-2.0-flash-001` * *Shut down*: `gemini-2.0-flash-exp` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * February 2025 --- * {% section class="model-property" %} {% icon name="cognition_2" /%}Knowledge cutoff {% /section %} * August 2024 {% /table %} # Gemini 2.0 Flash-Lite Source: https://aistudio.google.com/docs/models/gemini-2.0-flash-lite Description: Learn about Gemini 2.0 Flash-Lite from Google {% callout type="warning" %} Gemini 2.0 Flash-Lite is [deprecated](/docs/deprecations) and has been shut down June 1, 2026. Migrate to [Gemini 3.1 Flash-Lite](/docs/models/gemini-3.1-flash-lite) to avoid service disruption. {% /callout %} ## gemini-2.0-flash-lite {% id="gemini-20-flash-lite" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `gemini-2.0-flash-lite` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Audio, images, video, and text **Output** Text --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 1,048,576 **Output token limit** 8,192 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Batch API** {% badge type="supported" /%} {% /section %} {% section %} **Caching** {% badge type="supported" /%} {% /section %} {% section %} **Code execution** {% badge type="not-supported" /%} {% /section %} {% section %} **File search** {% badge type="not-supported" /%} {% /section %} {% section %} **Function calling** {% badge type="supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="not-supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="not-supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="supported" /%} {% /section %} {% section %} **Thinking** {% badge type="not-supported" /%} {% /section %} {% section %} **URL context** {% badge type="not-supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * *Shut down*: `gemini-2.0-flash-lite` * *Shut down*: `gemini-2.0-flash-lite-001` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * February 2025 --- * {% section class="model-property" %} {% icon name="cognition_2" /%}Knowledge cutoff {% /section %} * August 2024 {% /table %} # Imagen 4 Source: https://aistudio.google.com/docs/models/imagen Description: Learn about Imagen 4 from Google {% callout type="warning" %} The Imagen 4 standard, ultra, and fast endpoints are [deprecated](/docs/deprecations) and will be shut down on **August 17, 2026**; migrate to [Gemini 3.1 Flash Image](/docs/models/gemini-3.1-flash-image) to avoid service interruptions. {% /callout %} A high-performance engine for advanced visual synthesis, offering sophisticated creative control and photorealistic output. Use Imagen 4 for professional branding, intricate scene composition, and high-fidelity design tasks that require precise text rendering and complex lighting. {% button href="https://aistudio.google.com?model=imagen-4.0-generate-001" variant="ais" %}Try in Google AI Studio{% /button %} ## Documentation {% id="documentation" %} Visit the [Imagen](/docs/image-generation) page for full coverage of features and capabilities. ## imagen-4.0-generate-001 {% id="imagen-40-generate-001" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * **Gemini API** `imagen-4.0-generate-001` `imagen-4.0-ultra-generate-001` `imagen-4.0-fast-generate-001` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Input** Text **Output** Images --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 480 tokens (text) **Output images** 1 to 4 (Ultra/Standard/Fast) --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * June 2025 {% /table %} # Veo 3.1 Source: https://aistudio.google.com/docs/models/veo-3.1-generate-preview Description: Learn about the Veo 3.1 video generation model from Google {% callout type="warning" %} `veo-3.1-generate-preview` and `veo-3.1-fast-generate-preview` were [shut down](/docs/deprecations) on **October 22, 2026**; migrate to [Gemini Omni Flash](/docs/models/gemini-omni-flash) (`gemini-omni-1.1-flash`) or the GA models available through the [Gemini Enterprise Agent Platform](https://docs.cloud.google.com/gemini-enterprise-agent-platform/models/veo/3-1-generate) to avoid service interruptions. {% /callout %} A state-of-the-art cinematic engine designed for high-end creative storytelling and experimental video production. Veo 3.1 is best for professional-grade 4K output, natively synchronized audio generation, and complex camera movements that require the highest level of temporal consistency and artistic control. ## Documentation {% id="documentation" %} Visit the [Video generation](/docs/video) page for full coverage of features and capabilities. ## veo-3.1-generate-preview {% id="veo-31-generate-preview" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * **Gemini API** `veo-3.1-generate-preview` `veo-3.1-fast-generate-preview` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Input** Text, Image **Output** Video with audio --- * {% section class="model-property" %} {% icon name="token_auto" /%}Limits {% /section %} * **Text input** 1,024 tokens **Output video** 1 --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * January 2026 {% /table %} # Veo 2.0 Source: https://aistudio.google.com/docs/models/veo-2.0-generate-001 Description: Learn about the Veo 2.0 video generation model from Google {% callout type="warning" %} This model was [shut down](/docs/deprecations) on **June 30, 2026**; migrate to [Gemini Omni Flash](/docs/models/gemini-omni-flash) (`gemini-omni-1.1-flash`) or the GA models available through the [Gemini Enterprise Agent Platform](https://docs.cloud.google.com/gemini-enterprise-agent-platform/models/veo/3-1-generate) to avoid service interruptions. {% /callout %} Our robust and reliable stable video generation model, providing consistent performance for production-ready workflows. Veo 2.0 is best for standard 1080p content creation, social media assets, and high-volume video tasks that prioritize reliable character consistency and predictable sub-second generation speeds. ## Documentation {% id="documentation" %} Visit the [Video generation](/docs/video) page for full coverage of features and capabilities. ## veo-2.0-generate-001 {% id="veo-20-generate-001" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * **Gemini API** `veo-2.0-generate-001` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Input** Text, image **Output** Video --- * {% section class="model-property" %} {% icon name="token_auto" /%}Limits {% /section %} * **Text input** N/A **Image input** Any image resolution and aspect ratio up to 20MB file size **Output video** Up to 2 --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * April 2025 {% /table %} # Gemini Embedding model Source: https://aistudio.google.com/docs/models/gemini-embedding-001 Description: Learn about the Gemini Embedding model from Google A specialized engine for high-dimensional vector representation, providing efficient numerical mapping of text and images. The Gemini Embedding model is best for semantic search, document retrieval, and recommendation systems that require fast, scalable similarity calculations across large datasets. ## Documentation {% id="documentation" %} Visit the [Embeddings](/docs/embeddings) page for full coverage of features and capabilities. ## gemini-embedding-001 {% id="gemini-embedding-001" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * **Gemini API** `gemini-embedding-001` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Input** Text **Output** Text embeddings --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 2,048 **Output dimension size** Flexible, supports: 128 - 3072, Recommended: 768, 1536, 3072 --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Stable: `gemini-embedding-001` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * June 2025 --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-embedding) {% /table %} # Gemini Embedding 2 model Source: https://aistudio.google.com/docs/models/gemini-embedding-2 Description: Learn about the Gemini Embedding 2 model from Google Our first multimodal embedding model, providing efficient numerical mapping of text, images, video, audio, and PDFs into a single unified embedding space. The Gemini Embedding 2 model is best for cross-modal semantic search, document retrieval, and recommendation systems that require fast, scalable similarity calculations across large multimodal datasets. ## Documentation {% id="documentation" %} Visit the [Embeddings](/docs/embeddings) page for full coverage of features and capabilities. ## gemini-embedding-2 {% id="gemini-embedding-2" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * **Gemini API** `gemini-embedding-2` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Input** Text, image, video, audio, PDF **Output** Text embeddings --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 8,192 **Output dimension size** Flexible, supports: 128 - 3072, Recommended: 768, 1536, 3072 --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Stable: `gemini-embedding-2` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * April 2026 --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#gemini-embedding-2) {% /table %} # Gemini Embedding 2 preview model Source: https://aistudio.google.com/docs/models/gemini-embedding-2-preview Description: Learn about the Gemini Embedding 2 model from Google Our first multimodal embedding model, providing efficient numerical mapping of text, images, video, audio, and PDFs into a single unified embedding space. The Gemini Embedding 2 model is best for cross-modal semantic search, document retrieval, and recommendation systems that require fast, scalable similarity calculations across large multimodal datasets. ## Documentation {% id="documentation" %} Visit the [Embeddings](/docs/embeddings) page for full coverage of features and capabilities. ## gemini-embedding-2-preview {% id="gemini-embedding-2-preview" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * **Gemini API** `gemini-embedding-2-preview` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Input** Text, image, video, audio, PDF **Output** Text embeddings --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 8,192 **Output dimension size** Flexible, supports: 128 - 3072, Recommended: 768, 1536, 3072 --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Preview: `gemini-embedding-2-preview` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * March 2026 {% /table %} # Gemini Robotics ER 2 Source: https://aistudio.google.com/docs/models/gemini-robotics-er-2-preview Description: Learn about Gemini Robotics ER 2 from Google Gemini Robotics ER 2 is a vision-language model (VLM) for robotics that accepts text, image, video, and audio input. It supports spatial reasoning, video understanding, agentic code execution, multi-step tool orchestration, and multi-robot coordination. {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-robotics-er-2-preview" variant="ais" %}Try in Google AI Studio{% /button %} ## Documentation Visit the [Robotics](/docs/robotics-overview) page for full coverage of features and capabilities. ## gemini-robotics-er-2-preview {% id="gemini-robotics-er-2-preview" %} {% partial file="googledevai/en/gemini-api/docs/models/_includes/_robotics-er.md" /%} # Gemini Robotics ER 2 streaming Source: https://aistudio.google.com/docs/models/gemini-robotics-er-2-streaming-preview Description: Learn about Gemini Robotics ER 2 Streaming from Google Gemini Robotics ER 2 Streaming is a vision-language model (VLM) for robotics optimized for real-time text streaming using the Live API. It accepts text, image, video, and audio input and supports bidirectional streaming with function calling. {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-robotics-er-2-streaming-preview" variant="ais" %}Try in Google AI Studio{% /button %} ## Documentation Visit the [Live API for robotics](/docs/robotics-streaming) page for full coverage of features and capabilities. ## gemini-robotics-er-2-streaming-preview {% id="gemini-robotics-er-2-streaming-preview" %} {% partial file="googledevai/en/gemini-api/docs/models/_includes/_robotics-er.md" /%} # Gemini Robotics ER 1.5 Source: https://aistudio.google.com/docs/models/gemini-robotics-er-1.5-preview Description: Learn about Gemini Robotics Preview model from Google {% callout type="note" %} Note: This version is planned for [deprecation soon](/docs/deprecations). See the [models](/docs/models) page for the latest model version. {% /callout %} Gemini Robotics ER 1.5 is a vision-language model (VLM) that brings Gemini's agentic capabilities to robotics. It's designed for advanced reasoning in the physical world, allowing robots to interpret complex visual data, perform spatial reasoning, and plan actions from natural language commands. {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-robotics-er-1.5-preview" variant="ais" %}Try in Google AI Studio{% /button %} ## Documentation {% id="documentation" %} Visit the [Robotics](/docs/robotics-overview) page for full coverage of features and capabilities. ## gemini-robotics-er-1.5-preview {% id="gemini-robotics-er-15-preview" %} {% partial file="googledevai/en/gemini-api/docs/models/_includes/_1.5-robotics-er.md" /%} # Gemini Robotics ER 1.6 Source: https://aistudio.google.com/docs/models/gemini-robotics-er-1.6-preview Description: Learn about Gemini Robotics Preview model from Google {% callout type="note" %} This version is deprecated. Migrate to [Gemini Robotics ER 2](/docs/models/gemini-robotics-er-2-preview) (`gemini-robotics-er-2-preview`). See the [deprecations](/docs/deprecations) page for details. {% /callout %} Gemini Robotics ER 1.6 is a vision-language model (VLM) that brings Gemini's agentic capabilities to robotics. It's designed for advanced reasoning in the physical world, allowing robots to interpret complex visual data, perform spatial reasoning, and plan actions from natural language commands. ## Documentation {% id="documentation" %} Visit the [Robotics](/docs/robotics-overview) page for full coverage of features and capabilities. ## gemini-robotics-er-1.6-preview {% id="gemini-robotics-er-16-preview" %} {% partial file="googledevai/en/gemini-api/docs/models/_includes/_1.6-robotics-er.md" /%} # Deep Research Pro preview Source: https://aistudio.google.com/docs/models/deep-research-pro-preview-12-2025 Description: Learn about Gemini Deep Research Pro preview model from Google {% callout type="warning" %} `deep-research-pro-preview-12-2025` is [deprecated](/docs/deprecations#managed-agents) and will be shut down on October 23, 2026. Migrate to [`deep-research-preview-04-2026`](/docs/models/deep-research-preview-04-2026) or [`deep-research-max-preview-04-2026`](/docs/models/deep-research-max-preview-04-2026). {% /callout %} A powerful agentic researcher designed for autonomous, multi-step investigations that synthesize complex information into comprehensive, cited reports. Powered by Gemini 3.1 Pro, this model is optimized for long-running tasks and accuracy-critical analysis across hundreds of public web sources and private workspace data like Gmail and Drive. ## Documentation {% id="documentation" %} Visit the [Deep Research](/docs/deep-research) page for full coverage of features and capabilities. ## deep-research-pro-preview-12-2025 {% id="deep-research-pro-preview-12-2025" %} {% partial file="googledevai/en/gemini-api/docs/models/_includes/_deep-research-pro-preview.md" /%} # Deep Research preview Source: https://aistudio.google.com/docs/models/deep-research-preview-04-2026 Description: Learn about Gemini Deep Research preview model from Google A powerful agentic researcher designed for autonomous, multi-step investigations that synthesize complex information into comprehensive, cited reports. This model supports collaborative planning, visualization, MCP servers, and File Search. It comes in two versions: Deep Research for speed and efficiency, and Deep Research Max for maximum comprehensiveness. ## Documentation {% id="documentation" %} Visit the [Deep Research](/docs/deep-research) page for full coverage of features and capabilities. ## deep-research-preview-04-2026 {% id="deep-research-preview-04-2026" %} {% partial file="googledevai/en/gemini-api/docs/models/_includes/_deep-research-preview.md" /%} # Deep Research Max preview Source: https://aistudio.google.com/docs/models/deep-research-max-preview-04-2026 Description: Learn about Gemini Deep Research Max preview model from Google Maximum comprehensiveness for automated context gathering and synthesis. Deep Research Max is optimized for long-running, accuracy-critical investigations that synthesize complex information from hundreds of public web sources and private workspace data into comprehensive, cited reports. It supports collaborative planning, visualization, MCP servers, and File Search. ## Documentation {% id="documentation" %} Visit the [Deep Research](/docs/deep-research) page for full coverage of features and capabilities. ## deep-research-max-preview-04-2026 {% id="deep-research-max-preview-04-2026" %} {% partial file="googledevai/en/gemini-api/docs/models/_includes/_deep-research-max-preview.md" /%} # Antigravity preview Source: https://aistudio.google.com/docs/models/antigravity-preview-05-2026 Description: Learn about Antigravity Agent preview model from Google {% callout type="warning" %} `antigravity-preview-05-2026` is [deprecated](/docs/deprecations#managed-agents) and will be shut down on October 5, 2026. Migrate to [`antigravity-preview-09-2026`](/docs/models/antigravity-preview-09-2026). {% /callout %} A powerful general-purpose managed agent designed for autonomous, multi-step workflows. This model plans, reasons, runs code, manages files, and searches the web inside a secure, isolated Linux sandbox hosted by Google. ## Documentation {% id="documentation" %} Visit the [Antigravity Agent](/docs/antigravity-agent) page for full coverage of features, capabilities, and code samples. ## antigravity-preview-05-2026 {% id="antigravity-preview-05-2026" %} {% partial file="googledevai/en/gemini-api/docs/models/_includes/_antigravity-preview.md" /%} # Antigravity preview Source: https://aistudio.google.com/docs/models/antigravity-preview-09-2026 Description: Learn about Antigravity Agent preview model from Google A powerful general-purpose managed agent designed for autonomous, multi-step workflows. This model plans, reasons, runs code, manages files, and searches the web inside a secure, isolated Linux sandbox hosted by Google. The September 2026 release (`antigravity-preview-09-2026`) upgrades the runtime harness with improved prompt caching, native code search tools, and efficient line-range file editing. ## Documentation {% id="documentation" %} Visit the [Antigravity Agent](/docs/antigravity-agent) page for full coverage of features, capabilities, and code samples. ## antigravity-preview-09-2026 {% id="antigravity-preview-09-2026" %} {% partial file="googledevai/en/gemini-api/docs/models/_includes/_antigravity-preview-09-2026.md" /%} # Lyria RealTime experimental Source: https://aistudio.google.com/docs/models/lyria-realtime-exp Description: Learn about the Lyria RealTime experimental music generation model from Google An experimental engine for high-fidelity musical synthesis, offering innovative capabilities for generating and transforming audio content. Lyria RealTime is best for AI-assisted songwriting, unique instrumental generation, and creative audio workflows that require deep control over melody and rhythm, with no vocals. {% button href="https://deepmind.google/models/lyria/lyria-realtime/" variant="primary" %}Try Lyria RealTime{% /button %} ## Documentation {% id="documentation" %} Visit the [Realtime music generation](/docs/realtime-music-generation) page for full coverage of features and capabilities. ## lyria-realtime-exp {% id="lyria-realtime-exp" %} {% partial file="googledevai/en/gemini-api/docs/models/_includes/_lyria-exp.md" /%} # Lyria 3.5 Source: https://aistudio.google.com/docs/models/lyria-3.5 Description: Learn about Lyria 3.5 from Google DeepMind Lyria 3.5 is Google's flagship music generation model. It is optimized for generating full-length songs with complex structural coherence, including multiple verses, choruses, and bridges. It generates high-quality, 44.1 kHz stereo audio from text prompts or image inputs. {% button href="https://aistudio.google.com/prompts/new_chat?model=lyria-3.5" variant="ais" %}Try in Google AI Studio{% /button %} ## Documentation {% id="documentation" %} Visit the [Music Generation](/docs/music-generation) guide for full coverage of features and capabilities. ## lyria-3.5 {% id="lyria-35" %} {% table variant="model" %} * Property * Description --- * {% section class="model-property" %} {% icon name="id_card" /%}Model code {% /section %} * `lyria-3.5` --- * {% section class="model-property" %} {% icon name="save" /%}Supported data types {% /section %} * **Inputs** Text and Image **Output** Audio (MP3), Text (Lyrics) --- * {% section class="model-property" %} {% icon name="token_auto" /%}Token limits{% sup %}[[*]](/docs/tokens){% /sup %} {% /section %} * **Input token limit** 131,072 --- * {% section class="model-property" %} {% icon name="handyman" /%}Capabilities {% /section %} * {% section class="three-column-grid" %} {% section %} **Audio generation** {% badge type="supported" /%} {% /section %} {% section %} **Batch API** {% badge type="not-supported" /%} {% /section %} {% section %} **Caching** {% badge type="not-supported" /%} {% /section %} {% section %} **Code execution** {% badge type="not-supported" /%} {% /section %} {% section %} **File search** {% badge type="not-supported" /%} {% /section %} {% section %} **Flex inference** {% badge type="not-supported" /%} {% /section %} {% section %} **Function calling** {% badge type="not-supported" /%} {% /section %} {% section %} **Grounding with Google Maps** {% badge type="not-supported" /%} {% /section %} {% section %} **Image generation** {% badge type="not-supported" /%} {% /section %} {% section %} **Live API** {% badge type="not-supported" /%} {% /section %} {% section %} **Priority inference** {% badge type="not-supported" /%} {% /section %} {% section %} **Search grounding** {% badge type="not-supported" /%} {% /section %} {% section %} **Structured outputs** {% badge type="not-supported" /%} {% /section %} {% section %} **Thinking** {% badge type="not-supported" /%} {% /section %} {% section %} **URL context** {% badge type="not-supported" /%} {% /section %} {% /section %} --- * {% section class="model-property" %} {% icon name="123" /%}Versions {% /section %} * Read the [model version patterns](/docs/models#model-versions) for more details. * Stable: `lyria-3.5` --- * {% section class="model-property" %} {% icon name="calendar_month" /%}Latest update {% /section %} * September 2026 --- * {% section class="model-property" %} {% icon name="paid" /%}Pricing {% /section %} * [Pricing](/docs/pricing#lyria-3-5) {% /table %} # Lyria 3 Clip preview Source: https://aistudio.google.com/docs/models/lyria-3-clip-preview Description: Learn about Lyria 3 Clip Preview from Google DeepMind Lyria 3 Clip Preview is Google's model optimized for generating short musical clips, loops, and previews. It generates 30-second high-quality, 48kHz stereo audio from text prompts or image inputs. {% button href="https://aistudio.google.com/prompts/new_chat?model=lyria-3-clip-preview" variant="ais" %}Try in Google AI Studio{% /button %} ## Documentation {% id="documentation" %} Visit the [Music Generation](/docs/music-generation) guide for full coverage of features and capabilities. ## lyria-3-clip-preview {% id="lyria-3-clip-preview" %} {% partial file="googledevai/en/gemini-api/docs/models/_includes/_lyria-3.md" /%} # Lyria 3 Pro preview Source: https://aistudio.google.com/docs/models/lyria-3-pro-preview Description: Learn about Lyria 3 Pro Preview from Google DeepMind Lyria 3 Pro Preview is Google's flagship music generation model. It is optimized for generating full-length songs with complex structural coherence, including multiple verses, choruses, and bridges. It generates high-quality, 48kHz stereo audio from text prompts or image inputs. {% button href="https://aistudio.google.com/prompts/new_chat?model=lyria-3-pro-preview" variant="ais" %}Try in Google AI Studio{% /button %} ## Documentation {% id="documentation" %} Visit the [Music Generation](/docs/music-generation) guide for full coverage of features and capabilities. ## lyria-3-pro-preview {% id="lyria-3-pro-preview" %} {% partial file="googledevai/en/gemini-api/docs/models/_includes/_lyria-3.md" /%} # What's new in Gemini 4 Argon Source: https://aistudio.google.com/docs/latest-model Description: Learn what's new in Gemini 4 Argon (gemini-4-argon), Google's new Gemini 4 model with a 1M shared context window, long decode, pricing, and API migration guide. Gemini 4 Argon (`gemini-4-argon`) is our latest, most capable model. It can reason longer on hard problems for better results on complex coding, agentic, math, and science tasks. Gemini 4 Argon is available through the Gemini API and in Google AI Studio. Gemini 4 Argon supports a unified 1M-token context window, long decode up to 1M tokens, and tunable thinking levels (`low`, `medium`, `high`). {% card-grid %} {% card href="https://aistudio.google.com/apps?model=gemini-4-argon" icon="experiment" title="Try it in AI Studio" description="Build apps from scratch with Gemini 4 Argon and AI Studio." /%} {% card href="https://aistudio.google.com/learn/gemini-4-argon-showcase" icon="smart_toy" title="App Gallery" description="Play and remix apps, built with Gemini 4 Argon." /%} {% card href="https://aistudio.google.com/learn/gemini-4-argon" icon="rocket_launch" title="Get started" description="Get started with Gemini 4 Argon with starter prompts." /%} {% /card-grid %} This guide explains what's new in Gemini 4 Argon, API changes, code examples, and migration guidance. ## New model {% id="new-model" %} | Model | Model ID | Default thinking level | Pricing | Description | | :---- | :---- | :---: | :---- | :---- | | Gemini 4 Argon | `gemini-4-argon` | `medium` | Available through Nov 30, 2026 at an introductory price of $2/1M input tokens and $10/1M output tokens ($4/1M input and $20/1M output thereafter). See [pricing](/docs/pricing) for more details. | Our most capable model, built to solve the hardest problems with depth and precision across real-world software engineering and knowledge work tasks. | For complete details, see the [Gemini 4 Argon model page](/docs/models/gemini-4-argon). For introductory pricing details, see the [pricing section](/docs/latest-model#pricing) later on this page or the [pricing page](/docs/pricing#gemini-4-argon). ## Quickstart {% id="quickstart" %} Use the following example to send a request to `gemini-4-argon` with the recommended default `thinking_level` (`medium`) and a 64K output token limit: {% tabs %} {% tab label="Python" %} ```python from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-4-argon", input="Write a three.js script that renders a realistic 3D black hole with gravitational lensing." ) print(interaction.output_text) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; const client = new GoogleGenAI({}); const interaction = await client.interactions.create({ model: "gemini-4-argon", input: "Write a three.js script that renders a realistic 3D black hole with gravitational lensing.", }); console.log(interaction.output_text); ``` {% /tab %} {% tab label="REST" %} ```bash curl "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d '{ "model": "gemini-4-argon", "input": "Write a three.js script that renders a realistic 3D black hole with gravitational lensing." }' ``` {% /tab %} {% /tabs %} ## What's new in Gemini 4 Argon {% id="whats-new-gemini-4-argon" %} * **Unified 1M input-output token limit:** Input, thinking, and output share one window of 1,048,576 tokens. * **Long decode:** A single response can now go past 64K tokens, up to 1M tokens minus your input. See [Long decode](/docs/long-decode). * **Agentic video understanding:** [Agentic video understanding](/docs/video-understanding#agentic-video-understanding) is now generally available. * **Supported in Managed Agents:** The [Antigravity agent](/docs/antigravity-agent) in Gemini Managed Agents now supports Gemini 4 Argon. For more details, see the [Gemini 4 Argon model page](/docs/models/gemini-4-argon). For pricing details, see the [pricing page](/docs/pricing#gemini-4-argon). ## Larger output and long decode {% id="long-decode" %} Gemini 4 Argon can think longer on hard math, science, and coding problems. * **Use `thinking_level` to control reasoning depth:** The thinking level decides how deeply the model reasons before it answers. `max_output_tokens` is a hard limit: the response stops once thinking and output together reach it, so set it high enough that it doesn't cut the answer short. * **Generate up to 1M tokens with background execution:** Use background execution with `max_output_tokens` greater than 65,536 to let a single response go past 64K tokens, up to 1M tokens. The model generates long responses in hops of up to 64K tokens, and each hop continues from where the previous one stopped. With background execution, our servers run these continuation hops for you. Because each hop adds a `model_output` step to `interaction.steps`, join the text across all `model_output` steps when the interaction completes. {% tabs %} {% tab label="Python" %} ```python import time from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-4-argon", input="Write a complete, rigorous proof of the prime number theorem.", background=True, generation_config={ "max_output_tokens": 262144, "thinking_level": "high", }, ) while interaction.status in ("in_progress", "queued"): time.sleep(5) interaction = client.interactions.get(id=interaction.id) # Each hop adds a model_output step, so join the text of all of them. text = "".join( content.text for step in interaction.steps if step.type == "model_output" for content in step.content if content.type == "text" ) print(text) print("Status:", interaction.status) print("Usage:", interaction.usage) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; const client = new GoogleGenAI({}); let interaction = await client.interactions.create({ model: "gemini-4-argon", input: "Write a complete, rigorous proof of the prime number theorem.", background: true, generation_config: { max_output_tokens: 262144, thinking_level: "high", }, }); while (interaction.status === "in_progress" || interaction.status === "queued") { await new Promise((resolve) => setTimeout(resolve, 5000)); interaction = await client.interactions.get(interaction.id); } // Each hop adds a model_output step, so join the text of all of them. const text = interaction.steps .filter((step) => step.type === "model_output") .flatMap((step) => step.content ?? []) .filter((content) => content.type === "text") .map((content) => content.text) .join(""); console.log(text); console.log("Status:", interaction.status); console.log("Usage:", interaction.usage); ``` {% /tab %} {% tab label="REST" %} ```bash ID=$(curl -s -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gemini-4-argon", "input": "Write a complete, rigorous proof of the prime number theorem.", "background": true, "generation_config": { "max_output_tokens": 262144, "thinking_level": "high" } }' | jq -r '.id') while true; do RESP=$(curl -s "https://generativelanguage.googleapis.com/v1beta/interactions/$ID" \ -H "x-goog-api-key: $GEMINI_API_KEY") STATUS=$(echo "$RESP" | jq -r '.status') if [[ "$STATUS" != "in_progress" && "$STATUS" != "queued" ]]; then echo "$RESP" | jq -r '[.steps[]? | select(.type == "model_output") | .content[]? | select(.type == "text") | .text] | join("")' break fi sleep 5 done ``` {% /tab %} {% /tabs %} {% callout type="note" %} If you set `background: true` without defining `max_output_tokens`, the server stops after 64K tokens. {% /callout %} Background execution is the recommended way to run long decode. It runs the continuation loop server-side until the model finishes or reaches `max_output_tokens`. If you need finer-grained control over retries, backoff, and error handling (or don't want your interactions stored), you can use client-side continuation in the [Interactions API](/docs/long-decode#client-side-continuation) or the [GenerateContent API](/docs/long-decode?generate-content=true). For streaming, reconnection, token counting, and when to use long decode, see the [long decode guide](/docs/long-decode). ### Setting output token limits {% id="setting-output-token-limits" %} `max_output_tokens` sets the total thinking and output tokens for a response. Set it high enough that thinking doesn't cut the answer short, and low enough to limit spend when a hard prompt uses all of it. Use these values as a starting point: * **Standard tasks:** Keep the default of 65,536 or don't set any value. * **Existing apps with a limit lower than 32K:** Raise `max_output_tokens` to at least 32,768. Gemini 4 Argon can spend more of the limit on thinking than earlier models. To use fewer tokens, lower the thinking level instead. * **Complex reasoning and coding:** Set `background: true` and set `max_output_tokens` to 131,072 or 262,144, up to 1,048,576 minus your input tokens. ## Understanding thinking levels {% id="understanding-thinking-levels" %} The [thinking level](/docs/thinking) is your main control over quality, latency, and token use in Gemini 4 Argon: | Thinking level | Token use | When to use | | :---- | :---- | :---- | | `low` | Fewest tokens, lowest latency | Simpler tasks and cost-sensitive work. Also works for analysis and writing tasks that need light thinking. Quality can drop on hard tasks. | | `medium` (default) | Balanced | Recommended for most tasks, including complex code and agentic use cases. | | `high` | Most tokens, slowest first token | Complex reasoning, hard math and science, and the most difficult code or agent tasks. Pairs well with long decode for long outputs. | Run your evaluations at all three levels, then pick the lowest level that meets your quality bar. To learn more, see the [thinking guide](/docs/thinking). {% tabs %} {% tab label="Python" %} ```python from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-4-argon", input="Analyze this payment processing pipeline for race conditions during retry attempts and rewrite the transaction locks safely.", generation_config={ "thinking_level": "medium" # Balanced reasoning effort for complex tasks } ) print(interaction.output_text) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; const client = new GoogleGenAI({}); const interaction = await client.interactions.create({ model: "gemini-4-argon", input: "Analyze this payment processing pipeline for race conditions during retry attempts and rewrite the transaction locks safely.", generation_config: { thinking_level: "medium", // Balanced reasoning effort for complex tasks }, }); console.log(interaction.output_text); ``` {% /tab %} {% tab label="REST" %} ```bash curl "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d '{ "model": "gemini-4-argon", "input": "Analyze this payment processing pipeline for race conditions during retry attempts and rewrite the transaction locks safely.", "generation_config": { "thinking_level": "medium" } }' ``` {% /tab %} {% /tabs %} ## Gemini 4 Argon in Managed Agents {% id="managed-agents" %} The [Antigravity agent](/docs/antigravity-agent) in Gemini Managed Agents supports Gemini 4 Argon. To use it, set the model in `agent_config`: {% tabs %} {% tab label="Python" %} ```python from google import genai client = genai.Client() interaction = client.interactions.create( agent="antigravity-preview-09-2026", input=( "Audit https://web.dev for performance, Core Web Vitals, and SEO. " "Query Google's PageSpeed Insights API for both Mobile and Desktop strategies. " "Check search indexing with Google Search for site:web.dev. " "Format the output as a side-by-side scorecard table with prioritized fixes." ), environment="remote", agent_config={ "type": "antigravity", "model": "gemini-4-argon", }, ) print(interaction.output_text) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; const client = new GoogleGenAI({}); const interaction = await client.interactions.create({ agent: "antigravity-preview-09-2026", input: "Audit https://web.dev for performance, Core Web Vitals, and SEO. " + "Query Google's PageSpeed Insights API for both Mobile and Desktop strategies. " + "Check search indexing with Google Search for site:web.dev. " + "Format the output as a side-by-side scorecard table with prioritized fixes.", environment: "remote", agent_config: { type: "antigravity", model: "gemini-4-argon", }, }, { timeout: 300000 }); console.log(interaction.output_text); ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "Content-Type: application/json" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -d '{ "agent": "antigravity-preview-09-2026", "input": "Audit https://web.dev for performance, Core Web Vitals, and SEO. Query Google'\''s PageSpeed Insights API for both Mobile and Desktop strategies. Check search indexing with Google Search for site:web.dev. Format the output as a side-by-side scorecard table with prioritized fixes.", "environment": "remote", "agent_config": { "type": "antigravity", "model": "gemini-4-argon" } }' ``` {% /tab %} {% /tabs %} For more options, see [model selection](/docs/antigravity-agent#model-selection) in the Antigravity agent guide. ## Migration checklist {% id="migration-checklist" %} {% callout type="note" %} **Automate this migration with a coding agent.** If you use a coding agent that supports skills (like Antigravity), install the [gemini-api-dev skill](/docs/coding-agents#gemini-api-dev) and run: ```none /gemini-api-dev migrate my app to Gemini 4 Argon ``` {% /callout %} ### Migrate to gemini-4-argon {% id="migrate-to-gemini-4-argon" %} * **Update model ID:** Change your target model string to `gemini-4-argon`. * **Review `max_output_tokens`:** If you set it explicitly today, consider raising it. We recommend at least 32,768, since Gemini 4 Argon can spend more of the limit on thinking. * **Configure thinking level:** Choose `low`, `medium` (default), or `high`, and test your workload at all three. * **Move off explicit context caching:** Explicit caching (`cachedContents` / `caches.create`) is not supported on Gemini 4 Argon. Remove calls that create or reference `cached_content` from your requests. [Implicit caching](/docs/caching) is enabled by default for prompts of at least 4,096 tokens and discounts cached input tokens by 95% on cache hits. * **Remove sampling parameters:** Remove `temperature`, `top_p`, and `top_k` from your requests. If provided, they are ignored. * **Use background execution for long outputs:** For tasks that need more than 64K tokens, set `background` to true and `max_output_tokens` greater than 65,536. * **Increase client timeouts:** Hard prompts can take several minutes. Use background execution, or set HTTP client timeouts to at least 15 minutes. * **Keep conversation state on the server:** Use `previous_interaction_id` for multi-turn and function calling conversations. * **Review your cost estimates:** Every token the model processes is billed, including internal tool system instructions and function declarations when using grounding (see [Pricing](/docs/latest-model#pricing)). ## Pricing {% id="pricing" %} Gemini 4 Argon is available at introductory pricing through November 30, 2026: * **Input tokens:** $2.00 per 1M tokens ($4.00 starting December 1, 2026) * **Cached input tokens:** Implicit caching discounts cached input by 95%, to $0.10 per 1M tokens ($0.20 starting December 1, 2026). * **Output tokens, including thinking tokens:** $10.00 per 1M tokens ($20.00 starting December 1, 2026) Every token the model processes is counted and billed, including thinking tokens and internal tool system instructions and function declarations when using grounding. Grounding with Google Search also remains billed per query. Gemini 4 Argon is not available on the Free tier. For complete pricing tiers, see the [pricing page](/docs/pricing#gemini-4-argon). ## Other models {% id="other-models" %} * [Gemini 3.8 Flash](/docs/whats-new-gemini-3.8) * [Gemini 3.6 Flash and 3.5 Flash-Lite](/docs/whats-new-gemini-3.6) * [See all models](/docs/models) ## What's next {% id="whats-next" %} * Read the [long decode guide](/docs/long-decode) for streaming, reconnection, and token counting. * Learn how thinking levels and thought summaries work in the [thinking guide](/docs/thinking). * Learn about long-running jobs in the [background execution guide](/docs/background-execution). * Test and refine prompts in [Google AI Studio](https://aistudio.google.com/prompts/new_chat?model=gemini-4-argon). # What's new in Gemini 3.8 Flash Source: https://aistudio.google.com/docs/whats-new-gemini-3.8 Description: Learn about what's new in Gemini 3.8 Flash, including model capabilities, API changes, and migration guidance. {% button href="/docs/latest-model" variant="ais" %}Latest model{% /button %} {% button href="/docs/whats-new-gemini-3.8#other-models" variant="ais" %}Other models{% /button %} Gemini 3.8 Flash (`gemini-3.8-flash`) is our most intelligent Flash model, engineered for long-horizon software engineering, autonomous agents, and complex enterprise workflows. This guide explains what's new in Gemini 3.8 Flash, API changes, code examples, and migration guidance. ## New model {% id="new-model" %} | Model | Model ID | Default thinking level | Pricing | Description | | :---- | :---- | :---: | ----- | :---- | | Gemini 3.8 Flash | `gemini-3.8-flash` | `medium` | 3.8 Flash is available through the end of year at an introductory price of $0.75/1M input tokens and $3.75/1M output tokens; see [pricing](/docs/pricing) for more details. | Our most intelligent Flash model, engineered for long-horizon software engineering, autonomous agents, and complex enterprise workflows. | Gemini 3.8 Flash supports a 1M token context window, 64k max output tokens, tunable thinking levels (`low`, `medium`, `high`), and the same suite of built-in tools. For complete specs, see the [Gemini 3.8 Flash model page](/docs/models/gemini-3.8-flash). For introductory pricing details, see the [pricing section](/docs/whats-new-gemini-3.8#pricing) later on this page or the [pricing page](/docs/pricing#gemini-3.8-flash). ## Quickstart {% id="quickstart" %} {% tabs %} {% tab label="Python" %} ```python from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-3.8-flash", input="Write a three.js script that renders a realistic 3D black hole." ) print(interaction.output_text) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; const client = new GoogleGenAI({}); const interaction = await client.interactions.create({ model: "gemini-3.8-flash", input: "Write a three.js script that renders a realistic 3D black hole.", }); console.log(interaction.output_text); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-3.8-flash")) .input( InteractionsInput.of( "Write a three.js script that renders a realistic 3D black hole.")) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); System.out.println(interaction.outputText().orElse("")); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.8-flash"), Input: interactions.NewInteractionsInput("Write a three.js script that renders a realistic 3D black hole."), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputText != nil { fmt.Println(*res.Interaction.OutputText) } } ``` {% /tab %} {% tab label="REST" %} ```bash curl "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d '{ "model": "gemini-3.8-flash", "input": "Write a three.js script that renders a realistic 3D black hole." }' ``` {% /tab %} {% /tabs %} ## What's new in Gemini 3.8 Flash {% id="whats-new-gemini-3-8-flash" %} * **Long-horizon software engineering:** Delivers strong results on real-world coding benchmarks, complex multi-file refactoring, and deterministic tool execution. See the [evaluation methodology](https://deepmind.google/models/evals-methodology/gemini-3-8-flash/) for details. * **Autonomous agents:** Lets you build resilient multi-step planning and tool orchestration workflows, substantially reducing failed loops and errors. * **Complex enterprise workflows:** Delivers superior accuracy, deep reasoning, and high factual rigor across demanding domain tasks and large-scale data pipelines. * **Default model for Managed Agents:** The default agent for managed agents: the [Antigravity agent](/docs/antigravity-agent), now uses Gemini 3.8 Flash. The [Antigravity SDK](https://antigravity.google/docs/sdk/overview/) also uses Gemini 3.8 Flash by default. * **Introductory pricing:** Gemini 3.8 Flash is available at an introductory rate of $0.75/1M input tokens and $3.75/1M output tokens through December 31, 2026. Standard pricing of $1.50/1M input tokens and $7.50/1M output tokens takes effect January 1, 2027. Gemini 3.8 Flash can use more tokens on longer running and complex tasks, by design. To deliver higher-quality results on difficult, multi-step goals, the model takes smaller reasoning steps, calls tools iteratively, and verifies its work along the way. Not every workflow needs this level of verification. For everyday tasks, you can lower the [reasoning](/docs/whats-new-gemini-3.8#understanding-reasoning-levels) effort to reduce token consumption. Alternatively, Gemini 3.6 Flash remains supported. ## Understanding reasoning levels {% id="understanding-reasoning-levels" %} Gemini 3.8 Flash gives you flexible control over latency and intelligence by adjusting the model's thinking level: * **Low thinking effort**: Reduces time-to-answer for latency-critical tasks like incident response pipelines, real-time chat, writing drafts, and fast data analysis. * **Medium (default):** Best quality for most tasks. Recommended for complex code and agentic use cases, providing higher first-pass accuracy. * **High thinking effort**: Maximizes the model's reasoning and tool orchestration capabilities. Best for deep reasoning, mathematics, and difficult multi-step tasks. Note: `minimal` thinking level is not supported for Gemini 3.8 Flash and will return an error. The following example sets `thinking_level` to `medium` for a complex code analysis request: {% tabs %} {% tab label="Python" %} ```python from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-3.8-flash", input="Analyze this payment processing pipeline for race conditions during retry attempts and rewrite the transaction locks safely.", generation_config={ "thinking_level": "medium" # Balanced reasoning effort for complex tasks } ) print(interaction.output_text) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; const client = new GoogleGenAI({}); const interaction = await client.interactions.create({ model: "gemini-3.8-flash", input: "Analyze this payment processing pipeline for race conditions during retry attempts and rewrite the transaction locks safely.", generation_config: { thinking_level: "medium" } }); console.log(interaction.output_text); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.GenerationConfig; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ThinkingLevel; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-3.8-flash")) .input( InteractionsInput.of( "Analyze this payment processing pipeline for race conditions during retry attempts and rewrite the transaction locks safely.")) .generationConfig( GenerationConfig.builder() .thinkingLevel(ThinkingLevel.MEDIUM) // Balanced reasoning effort for complex tasks .build()) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); System.out.println(interaction.outputText().orElse("")); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.8-flash"), Input: interactions.NewInteractionsInput("Analyze this payment processing pipeline for race conditions during retry attempts and rewrite the transaction locks safely."), GenerationConfig: &interactions.GenerationConfig{ ThinkingLevel: interactions.ThinkingLevelMedium.ToPointer(), // Balanced reasoning effort for complex tasks }, }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputText != nil { fmt.Println(*res.Interaction.OutputText) } } ``` {% /tab %} {% tab label="REST" %} ```bash curl "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d '{ "model": "gemini-3.8-flash", "input": "Analyze this payment processing pipeline for race conditions during retry attempts and rewrite the transaction locks safely.", "generation_config": { "thinking_level": "medium" } }' ``` {% /tab %} {% /tabs %} ## Updated Antigravity agent {% id="updated-antigravity-agent" %} Due to its improved performance and reasoning, the [Antigravity agent](/docs/antigravity-agent) in Gemini Managed Agents is now built with Gemini 3.8 Flash by default. {% tabs %} {% tab label="Python" %} ```python from google import genai client = genai.Client() interaction = client.interactions.create( agent="antigravity-preview-09-2026", input=( "Audit https://web.dev for performance, Core Web Vitals, and SEO. " "Query Google's PageSpeed Insights API for both Mobile and Desktop strategies. " "Check search indexing with Google Search for site:web.dev. " "Format the output as a side-by-side scorecard table with prioritized fixes." ), environment="remote", ) print(interaction.output_text) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; const client = new GoogleGenAI({}); const interaction = await client.interactions.create({ agent: "antigravity-preview-09-2026", input: "Audit https://web.dev for performance, Core Web Vitals, and SEO. Query Google's PageSpeed Insights API for both Mobile and Desktop strategies. Check search indexing with Google Search for site:web.dev. Format the output as a side-by-side scorecard table with prioritized fixes.", environment: "remote", }, { timeout: 300000 }); console.log(interaction.output_text); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.AgentOption; import com.google.genai.gaos.models.interactions.CreateAgentInteraction; import com.google.genai.gaos.models.interactions.CreateAgentInteractionEnvironment; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; Client client = new Client(); CreateAgentInteraction params = CreateAgentInteraction.builder() .agent(AgentOption.of("antigravity-preview-09-2026")) .input( InteractionsInput.of( "Audit https://web.dev for performance, Core Web Vitals, and SEO. " + "Query Google's PageSpeed Insights API for both Mobile and Desktop strategies. " + "Check search indexing with Google Search for site:web.dev. " + "Format the output as a side-by-side scorecard table with prioritized fixes.")) .environment(CreateAgentInteractionEnvironment.of("remote")) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); System.out.println(interaction.outputText().orElse("")); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateAgentInteraction{ Agent: interactions.AgentOption("antigravity-preview-09-2026"), Input: interactions.NewInteractionsInput( "Audit https://web.dev for performance, Core Web Vitals, and SEO. " + "Query Google's PageSpeed Insights API for both Mobile and Desktop strategies. " + "Check search indexing with Google Search for site:web.dev. " + "Format the output as a side-by-side scorecard table with prioritized fixes.", ), Environment: genai.Ptr(interactions.NewCreateAgentInteractionEnvironment("remote")), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputText != nil { fmt.Println(*res.Interaction.OutputText) } } ``` {% /tab %} {% tab label="REST" %} ```shell curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "Content-Type: application/json" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -d '{ "agent": "antigravity-preview-09-2026", "input": "Audit https://web.dev for performance, Core Web Vitals, and SEO. Query Google'\''s PageSpeed Insights API for both Mobile and Desktop strategies. Check search indexing with Google Search for site:web.dev. Format the output as a side-by-side scorecard table with prioritized fixes.", "environment": "remote" }' ``` {% /tab %} {% /tabs %} The underlying Gemini model [can be configured](/docs/antigravity-agent#model-selection) using `agent_config`. ## Migration checklist {% id="migration-checklist" %} {% callout type="note" %} **Automate this migration with a coding agent.** If you use a coding agent that supports skills (like Antigravity), install the [gemini-api-dev skill](/docs/coding-agents#gemini-api-dev) and run: `/gemini-api-dev migrate my app to Gemini 3.8 Flash` {% /callout %} ### Migrate to gemini-3.8-flash {% id="migrate-to-gemini-3-8-flash" %} * **Update Model ID:** Change your target model string to `gemini-3.8-flash`. * **Configure thinking level:** Replace `thinking_budget` with the string enum `thinking_level`. Note that `minimal` is not supported on Gemini 3.8 Flash; choose `low`, `medium` (default), or `high`. * **Apply Gemini 3 API parameter changes:** Remove deprecated sampling parameters (`temperature`, `top_p`, `top_k`), `candidate_count` (unsupported in Gemini 3 and later), and prefilled model turns. See [Gemini 3.6 API changes and parameter updates](/docs/whats-new-gemini-3.6#api-changes-and-parameter-updates). * **Enforce turn validation rules:** Standardize multi-turn conversations on server-side `previous_interaction_id` and remove prefilled model turns. * **Audit function calling:** * Place multimodal assets inside the response payload. * Format inline instructions using `\n\n`. * If you see `Malformed_Function_Call` errors tied to pre-tool text, see [Workarounds for pre-tool text requirements](/docs/function-calling#workarounds-for-pre-tool-text-requirements). * Only if using generateContent API: Ensure all `FunctionResponse` objects include `call_id` and `name`. * **Baseline Gemini 3 requirements:** For SDK updates and thought signature preservation, see [Thought signatures](/docs/thinking#signatures). ## Pricing {% id="pricing" %} Take advantage of introductory pricing across Google AI Studio and Gemini Enterprise Agent Platform through December 31, 2026 for Gemini 3.8 Flash and Gemini 3.6 Flash. Standard pricing takes effect January 1, 2027. For complete pricing tiers, see the [pricing page](/docs/pricing#gemini-3.8-flash). ## Other models {% id="other-models" %} * [Gemini 4 Argon (Latest)](/docs/latest-model) * [Gemini 3.6 Flash and 3.5 Flash-Lite](/docs/whats-new-gemini-3.6) * [See all models](/docs/models) ## What's next {% id="whats-next" %} * Review API specs on the [Models Overview](/docs/models). * Explore multi-agent orchestration in the [Interactions API Overview](/docs/interactions-overview). * Test and refine prompts in [Google AI Studio](https://aistudio.google.com/prompts/new_chat?model=gemini-3.8-flash). # What's new in Gemini 3.7 Flash Source: https://aistudio.google.com/docs/whats-new-gemini-3.7 Description: Learn about what's new in Gemini 3.7 Flash, including model capabilities, API changes, and migration guidance. {% button href="/docs/latest-model" variant="ais" %}Latest model{% /button %} {% button href="/docs/whats-new-gemini-3.7#other-models" variant="ais" %}Other models{% /button %} {% callout type="caution" %} **Deprecated:** Gemini 3.7 Flash (`gemini-3.7-flash`) is deprecated and has been replaced by [Gemini 3.8 Flash (`gemini-3.8-flash`)](/docs/whats-new-gemini-3.8). It is no longer available to select in Google AI Studio, and API requests to `gemini-3.7-flash` are automatically routed to `gemini-3.8-flash`. Update your model string to `gemini-3.8-flash` and review the [Gemini 3.8 Flash guide](/docs/whats-new-gemini-3.8). {% /callout %} Gemini 3.7 Flash (`gemini-3.7-flash`) is a previous-generation Flash model in the Gemini 3 series, now deprecated and automatically routed to [Gemini 3.8 Flash](/docs/whats-new-gemini-3.8). This guide is preserved for reference and documents the capabilities and changes introduced in Gemini 3.7 Flash. ## Model overview {% id="new-model" %} | Model | Model ID | Default thinking level | Description | | :---- | :---- | :---: | :---- | | Gemini 3.7 Flash (Deprecated) | `gemini-3.7-flash` | `medium` | Previous-generation Flash model built for coding, agentic workflows, and multi-step execution. Replaced by [Gemini 3.8 Flash](/docs/whats-new-gemini-3.8). | Gemini 3.7 Flash supports a 1M token context window, 64k max output tokens, tunable thinking levels (`low`, `medium`, `high`), and the same suite of built-in tools as 3.6 Flash. For complete specs, see the [Gemini 3.7 Flash model page](/docs/models/gemini-3.7-flash). ## Quickstart {% id="quickstart" %} {% tabs %} {% tab label="Python" %} ```python from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-3.7-flash", input="Write a responsive navigation component in React with smooth animations and dark mode toggle." ) print(interaction.output_text) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; const client = new GoogleGenAI({}); const interaction = await client.interactions.create({ model: "gemini-3.7-flash", input: "Write a responsive navigation component in React with smooth animations and dark mode toggle.", }); console.log(interaction.output_text); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; Client client = new Client(); CreateModelInteraction req = CreateModelInteraction.builder() .model(Model.of("gemini-3.7-flash")) .input(InteractionsInput.of("Write a responsive navigation component in React with smooth animations and dark mode toggle.")) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(req)).interaction().get(); System.out.println(interaction.outputText().orElse("")); ``` {% /tab %} {% tab label="REST" %} ```bash curl "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d '{ "model": "gemini-3.7-flash", "input": "Write a responsive navigation component in React with smooth animations and dark mode toggle." }' ``` {% /tab %} {% /tabs %} ## What's new in Gemini 3.7 Flash {% id="whats-new-gemini-3-7-flash" %} * **Coding and agentic tasks:** Significantly higher quality on real-world software engineering and agentic benchmarks, improving issue resolution and reducing failed agent loops. * **Web development and stronger design parity:** Generates higher-fidelity desktop and web application code directly from design mocks, with strong gains in design adherence and in auditing existing codebases against mocks to verify 1:1 design parity. ## Understanding reasoning levels {% id="understanding-reasoning-levels" %} Gemini 3.7 Flash gives developers flexible control over latency and intelligence by adjusting the model's thinking level: * **Low thinking effort**: Reduces time-to-answer for latency-critical tasks like incident response pipelines, real-time chat, writing drafts, and fast data analysis. * **Medium (default):** Best quality for most tasks. Recommended for complex code and agentic use cases, with higher first-pass accuracy. * **High thinking effort**: Maximizes the model's ability to think and use tools. Best for complex reasoning, hard math, and difficult coding and agent tasks. Allows extended thoughts and function calls, with higher token consumption and cost. To configure thinking levels in Gemini 3.7 Flash: ```python from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-3.7-flash", input="Analyze this payment processing pipeline for race conditions during retry attempts and rewrite the transaction locks safely.", generation_config={ "thinking_level": "medium" # Balanced reasoning effort for complex tasks } ) print(interaction.output_text) ``` For multi-language code examples (JavaScript, Java, Go, REST) and in-depth reasoning concepts, see [Understanding reasoning levels in Gemini 3.8 Flash](/docs/whats-new-gemini-3.8#understanding-reasoning-levels). ## Antigravity agent support {% id="updated-antigravity-agent" %} Gemini 3.7 Flash introduced support for powering the [Antigravity agent](/docs/antigravity-agent) in Gemini Managed Agents and the [Google Antigravity SDK](https://antigravity.google/docs/sdk/overview/). For current code samples and the latest default agent configuration, see the [Antigravity agent guide](/docs/antigravity-agent) and the [Gemini 3.8 Flash guide](/docs/whats-new-gemini-3.8#updated-antigravity-agent). ## Other models {% id="other-models" %} * [Gemini 4 Argon (Latest)](/docs/latest-model) * [Gemini 3.8 Flash](/docs/whats-new-gemini-3.8) * [Gemini 3.6 Flash and 3.5 Flash-Lite](/docs/whats-new-gemini-3.6) * [See all models](/docs/models) ## What's next {% id="whats-next" %} * Review API specs on the [Models Overview](/docs/models). * Explore multi-agent orchestration in the [Interactions API Guide](/docs/interactions-overview). * Test and refine prompts in [Google AI Studio](https://aistudio.google.com/). # What's new in Gemini 3.6 Flash and 3.5 Flash-Lite Source: https://aistudio.google.com/docs/whats-new-gemini-3.6 Description: Learn about what's new in Gemini 3.6 Flash and Gemini 3.5 Flash-Lite, including model capabilities, API changes, and migration guidance. {% button href="/docs/latest-model" variant="ais" %}Latest model{% /button %} {% button href="/docs/whats-new-gemini-3.6#other-models" variant="ais" %}Other models{% /button %} Gemini 3.6 Flash (`gemini-3.6-flash`) and Gemini 3.5 Flash-Lite (`gemini-3.5-flash-lite`) are previous-generation releases in the Gemini 3 series and remain available for production use. For our newest Flash model, see [Gemini 3.8 Flash](/docs/whats-new-gemini-3.8). * **Gemini 3.6 Flash**: Stronger performance on complex agentic and multimodal tasks while reducing token usage, at a lower price point than 3.5 Flash. * **Gemini 3.5 Flash-Lite**: The fastest, lowest-cost model in the 3.5 family. Outperforms prior Flash-Lite generations for high-throughput execution. This guide explains what was introduced in each model, what API changes affect your code, and how to migrate. {% callout type="note" %} You can automate this migration with a coding agent that supports [skills](/docs/coding-agents#gemini-api-dev) (like Antigravity). {% /callout %} {% tabs %} {% tab title="Gemini 3.6 Flash" %} 1. Install the skill: ```bash npx skills add google-gemini/gemini-skills --skill gemini-interactions-api --global ``` 2. Apply the skill: ```bash /gemini-interactions-api migrate my app to Gemini 3.6 Flash ``` {% /tab %} {% tab title="Gemini 3.5 Flash-Lite" %} 1. Install the skill: ```bash npx skills add google-gemini/gemini-skills --skill gemini-interactions-api --global ``` 2. Apply the skill: ```bash /gemini-interactions-api migrate my app to Gemini 3.5 Flash-Lite ``` {% /tab %} {% /tabs %} ## New models {% id="new-models" %} | Model | Model ID | Default thinking level | Pricing | Description | | :---- | :---- | :---: | ----- | :---- | | Gemini 3.6 Flash | `gemini-3.6-flash` | `medium` | $1.50/1M input tokens and $7.50/1M output tokens | Balances speed with intelligence for agentic and multimodal tasks. | | Gemini 3.5 Flash-Lite | `gemini-3.5-flash-lite` | `minimal` | $0.30/1M input tokens and $2.50/1M output tokens | The fastest, lowest-cost 3.5 model for high-throughput execution. | Both models support the 1M token context window, 64k max output tokens, thinking, and the full suite of built-in tools including [Computer Use](/docs/computer-use). For complete specs, see the model pages: * [Gemini 3.6 Flash model page](/docs/models/gemini-3.6-flash) * [Gemini 3.5 Flash-Lite model page](/docs/models/gemini-3.5-flash-lite) For detailed pricing, see the [pricing page](/docs/pricing). ## Quickstart {% id="quickstart" %} {% tabs %} {% tab label="Python" %} ```python from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-3.6-flash", input="Write a three.js script that renders an interactive 3D robot." ) print(interaction.output_text) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); async function main() { const interaction = await ai.interactions.create({ model: "gemini-3.6-flash", input: "Write a three.js script that renders an interactive 3D robot.", }); console.log(interaction.output_text); } await main(); ``` {% /tab %} {% tab label="REST" %} ```bash curl "https://generativelanguage.googleapis.com/v1beta/interactions" -H "x-goog-api-key: $GEMINI_API_KEY" -H 'Content-Type: application/json' -X POST -d '{ "model": "gemini-3.6-flash", "input": { "parts": [{"text": "Write a three.js script that renders an interactive 3D robot."}] } }' ``` {% /tab %} {% /tabs %} ## What's new in Gemini 3.6 Flash {% id="whats-new-gemini-3-6-flash" %} * **Token and turn reduction:** Completes multi-step workflows with fewer reasoning steps, conversational turns, and tool calls than Gemini 3.5. It also reduces execution loop spiraling. * **Improved code generation:** Produces higher quality production-ready code with fewer unwanted edits and fewer debugging loops. * **Better instruction following**: Reduces unwanted file changes during diagnostic tasks. * **Strong multimodal and spatial reasoning:** Improved performance on chart interpretation, visual blueprint conversion, and multi-element web layout generation. * **Upfront programmatic inspection:** Prefers running diagnostic code scripts before making changes more frequently than Gemini 3.5 Flash. This improves accuracy on complex tasks, but can add extra exploratory steps on routine frontend work. * **Computer Use support:** Supported as a built-in tool for agentic UI automation. * **UI styling preference**: Better at creating functional code, though human evaluators preferred earlier models for visual layout and styling. You can mitigate this by providing explicit design guidelines. * **Default thinking effort (medium):** Uses the same `medium` default thinking level as Gemini 3.5 Flash. * **Reduced pricing**: Lower output token costs ($7.50/1M versus $9.00/1M for 3.5 Flash). Input tokens remain at $1.50/1M. ## What's new in Gemini 3.5 Flash-Lite {% id="whats-new-gemini-3-5-flash-lite" %} * **Reduced task execution latency:** Highest throughput in the 3.5 family for high-volume data parsing and document extraction. * **Enhanced reasoning and multimodal performance:** Strong migration path from Gemini 2.5 Flash, with higher scores on reasoning tasks like HLE (18.0% versus 11.0%) and multimodal benchmarks like CharXIV (74.5% versus 63.7%). * **Subagent orchestration and tool reliability:** Improves tool execution reliability for code execution, search, and MCP workflows. Increase the thinking level for autonomous planning and complex subagent tasks. * **Improved document understanding:** Improves accuracy on document parsing and structured data extraction. Experiment with both minimal and high thinking levels depending on document complexity. * **Interactive web coding and tabular data processing:** Performs strongly on frontend JavaScript and tabular data processing by planning using lightweight code execution. * **Chatbot and persona persistence:** Stronger multi-turn instruction following and persona consistency over Gemini 3.1 Flash-Lite. * **Computer Use support:** Supported as a built-in tool for agentic UI automation. ## Choosing the right Flash or Flash-Lite model {% id="choosing-the-right-flash-model" %} Use this table to select the right model and migration path for your workloads. Both models require removing deprecated sampling parameters (`temperature`, `top_p`, `top_k`) and prefilled model turns. See [API changes](/docs/whats-new-gemini-3.6#api-changes-and-parameter-updates) for details. | Model | Primary use cases | Recommended migration target | | :---- | :---- | :---- | | **Gemini 3.6 Flash** (`gemini-3.6-flash`) | Code generation, spatial/multimodal reasoning, multi-step agentic workflows | **Gemini 3.5 Flash**, **Gemini 3 Flash (Preview)**, or **Gemini 3.1 Pro** | | **Gemini 3.5 Flash-Lite** (`gemini-3.5-flash-lite`) | Autonomous subagent execution, high-volume data analysis and document extraction, structured JSON parsing | **Gemini 3.1 Flash-Lite** or **Gemini 2.5 Flash** | ## Antigravity agent support {% id="updated-antigravity-agent" %} Gemini 3.6 Flash introduced support for the [Antigravity agent](/docs/antigravity-agent) in Gemini Managed Agents. For current code samples and the latest default agent configuration, see the [Antigravity agent guide](/docs/antigravity-agent) and the [Gemini 3.8 Flash guide](/docs/whats-new-gemini-3.8#updated-antigravity-agent). ## API changes and parameter updates {% id="api-changes-and-parameter-updates" %} Starting with Gemini 3.6 Flash and Gemini 3.5 Flash-Lite, the following API changes apply to these models and all future Gemini model releases. * **Sampling parameter deprecation**: `temperature`, `top_p`, and `top_k` are deprecated. The API ignores these parameters and returns an error in future model generations. * **Prefilled model turn validation**: Prefilling model turns is no longer supported. If the last non-empty turn in the request is a `model` turn, the API returns a `400` error. The following sections provide detailed explanations and code samples for each API change. ### 1. Sampling parameter deprecation (temperature, top_p, top_k) {% id="sampling-parameter-deprecation" %} `temperature`, `top_p`, and `top_k` are deprecated and ignored. In future model generations, supplying these parameters returns an HTTP 400 error. **Remove these parameters from all requests.** ```python # ⚠️ Remove these parameters (deprecated) generation_config = { "temperature": 0.7, "top_p": 0.9, "top_k": 40, } ``` To improve determinism, define a system instruction with explicit rules for your specific use case. ### 2. Prefilled model turn validation {% id="prefilled-model-turn-validation" %} API requests ending with a non-empty model role turn are disallowed and return an **HTTP 400 Error**. #### ⚠️ Avoid {% id="prefill-avoid" %} In legacy `generateContent` or raw REST payloads, ending with a model role turn is now disallowed: ```json /* ❌ DO NOT: End payload contents with a 'model' role turn */ { "contents": [ {"role": "user", "parts": [{"text": "Translate 'Hello world' to Spanish."}]}, {"role": "model", "parts": [{"text": "Translation:"}]} /* ❌ Returns error */ ] } ``` #### ✅ Recommended Migration (Interactions API) {% id="prefill-recommended-migration" %} In the Interactions API, model turns are not manually prefilled. If your application previously prefilled a model turn to suppress preambles or force JSON formatting, use system_instruction or [Structured outputs](/docs/structured-output) instead. ```python # ✅ RECOMMENDED: Use system_instruction in the Interactions API to specify output format interaction = client.interactions.create( model="gemini-3.6-flash", input="Translate 'Hello world' to Spanish.", system_instruction="Output only the translation without introductory text.", ) ``` ## Migration checklist {% id="migration-checklist" %} {% callout type="note" %} You can automate this migration with a coding agent that supports [skills](/docs/coding-agents#gemini-api-dev) (like Antigravity). {% /callout %} {% tabs %} {% tab title="Gemini 3.6 Flash" %} 1. Install the skill: ```bash npx skills add google-gemini/gemini-skills --skill gemini-interactions-api --global ``` 2. Apply the skill: ```bash /gemini-interactions-api migrate my app to Gemini 3.6 Flash ``` {% /tab %} {% tab title="Gemini 3.5 Flash-Lite" %} 1. Install the skill: ```bash npx skills add google-gemini/gemini-skills --skill gemini-interactions-api --global ``` 2. Apply the skill: ```bash /gemini-interactions-api migrate my app to Gemini 3.5 Flash-Lite ``` {% /tab %} {% /tabs %} ### Migrate to gemini-3.6-flash {% id="migrate-to-gemini-3-6-flash" %} * **Update Model ID:** Change your target model string to `gemini-3.6-flash`. * **Apply parameter updates:** Remove deprecated sampling parameters (`temperature`, `top_p`, `top_k`), `candidate_count` (unsupported in Gemini 3 and later), and prefilled model turns as detailed in [API changes and parameter updates](/docs/whats-new-gemini-3.6#api-changes-and-parameter-updates). * **Configure thinking level:** Replace `thinking_budget` with `thinking_level` (`"medium"` or `"high"`). * **Audit function calling:** * Place multimodal assets inside the response payload. * Format inline instructions using `\n\n`. * If you see `Malformed_Function_Call` errors tied to pre-tool text, see [Workarounds for pre-tool text requirements](/docs/function-calling#workarounds-for-pre-tool-text-requirements). * **Baseline Gemini 3.x requirements:** For SDK updates and thought signature preservation, see [Thought signatures](/docs/thinking#signatures). ### Migrate to gemini-3.5-flash-lite {% id="migrate-to-gemini-3-5-flash-lite" %} * **Update Model ID:** Change your target model string to `gemini-3.5-flash-lite`. * **Configure thinking effort level:** * For high-volume extraction, routing, or classification: leave `thinking_level` at `"minimal"` (default) for maximum throughput. * For autonomous subagents with tool calls, code execution, or multi-step reasoning: set `thinking_level` to `"medium"` or `"high"` to prevent premature tool termination. * **Remove deprecated parameters and validate function calling:** Apply the [same rules as 3.6 Flash](/docs/whats-new-gemini-3.6#migrate-to-gemini-3-6-flash). * **Baseline Gemini 3.x requirements:** Refer to [Thought signatures](/docs/thinking#signatures). ## Other models {% id="other-models" %} * [Gemini 4 Argon (Latest)](/docs/latest-model) * [Gemini 3.8 Flash](/docs/whats-new-gemini-3.8) * [See all models](/docs/models) ## What's next {% id="whats-next" %} * Review API specs on the [Models Overview](/docs/models). * Explore multi-agent orchestration in the [Interactions API Guide](/docs/interactions-overview). * Test and refine prompts in [Google AI Studio](https://aistudio.google.com/). # What's new in Gemini 3.5 Flash Source: https://aistudio.google.com/docs/whats-new-gemini-3.5 Description: Learn about the new features and migration guidance for Gemini 3.5 Flash. {% button href="/docs/latest-model" variant="ais" %}Latest model{% /button %} {% button href="/docs/whats-new-gemini-3.5#other-models" variant="ais" %}Other models{% /button %} {% callout type="caution" %} **Deprecated:** Gemini 3.5 Flash (`gemini-3.5-flash`) is deprecated and has been replaced by [Gemini 3.6 Flash (`gemini-3.6-flash`)](/docs/whats-new-gemini-3.6). It is no longer available to select in Google AI Studio, and API requests to `gemini-3.5-flash` are automatically routed to `gemini-3.6-flash`. Update your model string to `gemini-3.6-flash` (or [Gemini 3.8 Flash](/docs/latest-model)) and review the [Gemini 3.6 Flash guide](/docs/whats-new-gemini-3.6). {% /callout %} Gemini 3.5 Flash (`gemini-3.5-flash`) is an earlier-generation Flash model in the Gemini 3 series, now deprecated and automatically routed to [Gemini 3.6 Flash](/docs/whats-new-gemini-3.6). This guide is preserved for reference and documents the capabilities and baseline Gemini 3.x parameter updates introduced in Gemini 3.5 Flash. ## Model overview {% id="new-model" %} | Model | Model ID | Description | | :---- | :---- | :---- | | Gemini 3.5 Flash (Deprecated) | `gemini-3.5-flash` | Earlier-generation Flash model for agentic and coding tasks. Replaced by [Gemini 3.6 Flash](/docs/whats-new-gemini-3.6). | Gemini 3.5 Flash supports the 1M token context window, 65k max output tokens, thinking, and the same set of tools and platform features as Gemini 3 Flash, including [Computer Use](/docs/computer-use). For complete specs, see the [models overview](/docs/models/gemini-3.5-flash). ## Quickstart {% id="quickstart" %} All examples in this guide use the Interactions API. The GenerateContent API is also supported; the same configuration options and recommendations apply. {% tabs %} {% tab label="Python" filename="quickstart.py" %} ```python from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-3.6-flash", input="Explain how parallel agentic execution works in three sentences." ) print(interaction.output_text) ``` {% /tab %} {% tab label="JavaScript" filename="quickstart.js" %} ```javascript import { GoogleGenAI } from "@google/genai"; const client = new GoogleGenAI({}); async function main() { const interaction = await client.interactions.create({ model: "gemini-3.6-flash", input: "Explain how parallel agentic execution works in three sentences.", }); console.log(interaction.output_text); } await main(); ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-3.6-flash", "input": "Explain how parallel agentic execution works in three sentences." }' ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-3.5-flash")) .input( InteractionsInput.of( "Explain how parallel agentic execution works in three sentences.")) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); System.out.println(interaction.outputText().orElse("")); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.5-flash"), Input: interactions.NewInteractionsInput("Explain how parallel agentic execution works in three sentences."), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputText != nil { fmt.Println(*res.Interaction.OutputText) } } ``` {% /tab %} {% /tabs %} ## What's new {% id="whats-new" %} * **Sustained frontier performance:** Our most intelligent Flash model, optimized for agentic and coding tasks at scale. * **Agentic execution:** Sub-agent deployment, problem solving, and rapid agentic loops at scale. * **Coding:** Iterative coding cycles, rapid exploration, and prototyping to test alternate paths and dynamically explore solutions. * **Long horizon:** Multi-step workflows and tool use at scale. * **Thought preservation:** The model maintains intermediate reasoning across multi-turn conversations automatically. No API changes needed. * **New default effort level:** Default thinking effort changed from `high` to `medium`. See [New default effort level](/docs/whats-new-gemini-3.5#default-effort-level) for details. * **Improved `low` thinking:** `low` is now significantly improved for code and agentic tasks that require fewer steps, offering strong quality at lower latency and cost. * **GA release:** Stable model for scaled production use. ### Choosing the right Flash model {% id="choose-model" %} Gemini 3.5 Flash is deprecated and automatically routed to [Gemini 3.6 Flash](/docs/whats-new-gemini-3.6). Depending on your cost, latency, and capability requirements, we recommend the following models: * **Gemini 3.8 Flash**: Our latest and most intelligent Flash model for complex coding and agentic workflows. See the [Gemini 3.8 Flash guide](/docs/latest-model). * **Gemini 3.6 Flash**: Direct replacement for Gemini 3.5 Flash with reduced token usage and lower output pricing. See the [Gemini 3.6 Flash and 3.5 Flash-Lite guide](/docs/whats-new-gemini-3.6). * **Gemini 3.5 Flash-Lite / Gemini 3.1 Flash-Lite**: For low-cost, high-volume tasks that don't require full Flash reasoning depth, use [Gemini 3.5 Flash-Lite](/docs/models/gemini-3.5-flash-lite) or [Gemini 3.1 Flash-Lite](/docs/models/gemini-3.1-flash-lite). ## Behavioral changes {% id="behavioral-changes" %} ### New default effort level: `medium` {% id="default-effort-level" %} The default thinking effort is now **`medium`**, changed from `high` in Gemini 3 Flash Preview. `medium` yields very good results across a wide range of tasks while being faster and more cost-efficient. For complex problems, `high` encourages the model to think more deeply. | Effort level | When to use | | :---- | :---- | | `minimal` | Optimized for response speed. Chat-like use cases, quick factual answers, simpler tool calls. | | `low` | Code and agentic tasks that require lower latency and fewer steps. Also works well for analysis and writing tasks that require some thinking. | | **`medium` (default)** | **Best quality for most tasks. Recommended for complex code and agentic use cases.** | | `high` | Maximizes the model's ability to think and use tools. Best for complex reasoning, hard math, and the most difficult code or agent tasks. Allows extended thoughts and function calls. | To override the default, set `thinking_level` in your config: {% tabs %} {% tab label="Python" filename="thinking_level.py" %} ```python from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-3.6-flash", input="Prove that the square root of 2 is irrational.", generation_config={"thinking_level": "high"}, ) print(interaction.output_text) ``` {% /tab %} {% tab label="JavaScript" filename="thinking_level.js" %} ```javascript import { GoogleGenAI } from "@google/genai"; const client = new GoogleGenAI({}); async function main() { const interaction = await client.interactions.create({ model: "gemini-3.6-flash", input: "Prove that the square root of 2 is irrational.", generation_config: { thinking_level: "high" }, }); console.log(interaction.output_text); } await main(); ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-3.6-flash", "input": "Prove that the square root of 2 is irrational.", "generation_config": {"thinking_level": "high"} }' ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.GenerationConfig; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ThinkingLevel; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-3.5-flash")) .input(InteractionsInput.of("Prove that the square root of 2 is irrational.")) .generationConfig(GenerationConfig.builder().thinkingLevel(ThinkingLevel.HIGH).build()) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); System.out.println(interaction.outputText().orElse("")); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.5-flash"), Input: interactions.NewInteractionsInput("Prove that the square root of 2 is irrational."), GenerationConfig: &interactions.GenerationConfig{ ThinkingLevel: interactions.ThinkingLevelHigh.ToPointer(), }, }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputText != nil { fmt.Println(*res.Interaction.OutputText) } } ``` {% /tab %} {% /tabs %} {% callout type="note" %} Start with `medium`, it provides the best quality for the vast majority of tasks. Try `low` for a faster, cheaper experience with strong quality. Switch to `high` for complex reasoning, hard math, or difficult coding challenges. Use `minimal` to optimize for speed in simple queries. {% /callout %} The following table shows which thinking levels are supported per model: {% table %} * Thinking Level * Gemini 3.5 Flash * Gemini 3.1 Pro * Gemini 3.1 Flash-Lite * Gemini 3 Flash * Description --- * **`minimal`** * Supported * Not supported * Supported (Default) * Supported * Matches the "no thinking" setting for most queries. Note, `minimal` does not guarantee that thinking is off, the model may reason very minimally for complex tasks. --- * **`low`** * Supported * Supported * Supported * Supported * Minimizes latency and cost. --- * **`medium`** * Supported (Default) * Supported * Supported * Supported * Balanced thinking for most tasks. --- * **`high`** * Supported (Dynamic) * Supported (Default, Dynamic) * Supported (Dynamic) * Supported (Default, Dynamic) * Maximizes reasoning depth. {% /table %} {% callout type="caution" %} You cannot use both `thinking_level` and the legacy `thinking_budget` parameter in the same request. Doing so will return a 400 error. {% /callout %} ### Thought preservation {% id="thought-preservation" %} The model maintains intermediate reasoning across multi-turn conversations automatically. When present in the conversation history, reasoning context carries forward, which improves performance on complex multi-step tasks like iterative debugging and code refactoring. No API changes needed: * **Interactions API**: Thoughts are already preserved automatically. No change in behavior. * **GenerateContent API**: Beginning with Gemini 3.5 Flash, the model uses reasoning context from all previous turns when thought signatures are present in the conversation history. To enable this, pass the full, unmodified conversation history (including [thought signatures](/docs/thinking#signatures)) in `contents`. The SDKs handle this automatically. ## Parameter updates and best practices in Gemini 3.x {% id="parameter-updates" %} The following apply to **all Gemini 3.x models**, including Gemini 3.5 Flash. * **`temperature`, `top_p`, `top_k`**: we strongly recommend not changing the default values. Gemini 3's reasoning capabilities are optimized for the default settings. * Use `thinking_level` instead of `thinking_budget`. * **Function calling response matching**: `id`, `name`, and response count must match the preceding calls. * **Multimodal function responses**: include multimodal content inside the function response, not outside it. * **Inline instructions in function responses**: append to the function response text, not as separate parts. * **Reduce unnecessary tool calls**: Use lower thinking levels or experiment with system instructions to reduce tool calls in agentic workflows. See the sections below for how to update your code. ### Sampling parameters (no longer recommended) {% id="sampling-parameters" %} `temperature`, `top_p`, and `top_k` are no longer recommended for all Gemini 3.x models. Gemini 3's reasoning capabilities are optimized for the default settings. **Remove these parameters from all requests.** ```python # ⚠️ Remove these parameters (not recommended) generation_config = { "temperature": 0.7, "top_p": 0.9, "top_k": 40, } ``` To ensure determinism, we recommend defining a system instruction with explicit rules for your specific use case. ### `thinking_budget` (no longer recommended) {% id="thinking-budget" %} The raw numeric `thinking_budget` parameter is no longer recommended across all Gemini 3.x models. Use the `thinking_level` string enum instead. ```python # ⚠️ Before (not recommended) generation_config = { "thinking": {"thinking_budget": 7500}, } # ✅ After generation_config = { "thinking": {"thinking_level": "medium"}, } ``` Available values: `minimal`, `low`, `medium` (default), and `high`. ### Function calling: strict response matching {% id="function-calling" %} The Interactions API already errors on mismatched function responses. The GenerateContent API does not yet error, but mismatched responses cause the model to return empty responses with `finish_reason: STOP` in most cases. Always follow these conventions: | Requirement | Details | | :---- | :---- | | Include `id` | Every `FunctionResponse` must include the `id` from the corresponding `FunctionCall` | | Match `name` | The `name` in the response must match the `name` in the call | | Match counts | Return exactly one `FunctionResponse` for each `FunctionCall` received | {% tabs %} {% tab label="Python" filename="function_calling_match.py" %} ```python # ✅ Include matching call_id and name in the function_result final_interaction = client.interactions.create( model="gemini-3.6-flash", previous_interaction_id=interaction.id, tools=[my_tool], input=[{ "type": "function_result", "name": fc_step.name, "call_id": fc_step.id, "result": [{"type": "text", "text": json.dumps(result)}], }], ) ``` {% /tab %} {% tab label="JavaScript" filename="function_calling_match.js" %} ```javascript // ✅ Include matching call_id and name in the function_result const finalInteraction = await client.interactions.create({ model: "gemini-3.6-flash", previousInteractionId: interaction.id, tools: [myTool], input: [{ type: "function_result", name: fcStep.name, call_id: fcStep.id, result: [{ type: "text", text: JSON.stringify(result) }], }], }); ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-3.6-flash", "previous_interaction_id": "", "tools": [...], "input": [{ "type": "function_result", "name": "my_function", "call_id": "", "result": [{"type": "text", "text": "..."}] }] }' ``` {% /tab %} {% tab label="Java" %} ```java import java.util.Arrays; import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Function; import com.google.genai.gaos.models.interactions.FunctionResultStep; import com.google.genai.gaos.models.interactions.FunctionResultStepResultUnion; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.util.List; Client client = new Client(); // Assumes interactionId, callId, functionName, myTool, and resultJson from previous step String interactionId = "interaction-id-123"; String callId = "call-id-123"; String functionName = "get_weather"; Function myTool = Function.builder().name(functionName).build(); String resultJson = "{\"temperature\": \"72F\"}"; // ✅ Include matching callId and name in the FunctionResultStep FunctionResultStep functionResult = FunctionResultStep.builder() .name(functionName) .callId(callId) .result( FunctionResultStepResultUnion.of( Arrays.asList(TextContent.builder().text(resultJson).build()))) .build(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-3.5-flash")) .previousInteractionId(interactionId) .tools(Arrays.asList(myTool)) .input(InteractionsInput.ofStep(Arrays.asList(functionResult))) .build(); Interaction finalInteraction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } // Assumes interactionID, callID, functionName, myTool, and resultJSON from previous step interactionID := "interaction-id-123" callID := "call-id-123" functionName := "get_weather" myTool := interactions.NewTool(interactions.Function{Name: genai.Ptr(functionName)}) resultJSON := `{"temperature": "72F"}` // ✅ Include matching CallID and Name in the FunctionResultStep functionResult := interactions.NewStep(interactions.FunctionResultStep{ Name: genai.Ptr(functionName), CallID: callID, Result: interactions.NewFunctionResultStepResultUnion([]interactions.FunctionResultSubcontent{ interactions.NewFunctionResultSubcontent(interactions.TextContent{Text: resultJSON}), }), }) finalRes, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.5-flash"), PreviousInteractionID: genai.Ptr(interactionID), Tools: []interactions.Tool{myTool}, Input: interactions.NewInteractionsInput([]interactions.Step{functionResult}), }), }) if err != nil { log.Fatal(err) } _ = finalRes } ``` {% /tab %} {% /tabs %} ### Multimodal function responses {% id="multimodal-function-responses" %} We often see clients provide images outside function response. This can lead to unexpected model behavior (e.g. thought leakage) and result in lower quality outputs. Follow the recommendation in [Multimodal Function Responses API docs](/docs/function-calling?example=meeting#multimodal) instead and include multimodal content in the function response parts that you send to the model. The model can process this multimodal content in its next turn to produce a more informed response. {% tabs %} {% tab label="Python" filename="multimodal_function.py" %} ```python # ✅ Include multimodal content in the function response final_interaction = client.interactions.create( model="gemini-3.6-flash", previous_interaction_id=interaction.id, input=[ { "type": "function_result", "name": tool_call.name, "call_id": tool_call.id, "result": [ {"type": "text", "text": "instrument.jpg"}, { "type": "image", "mime_type": "image/jpeg", "data": base64_image_data, }, ], } ], ) ``` {% /tab %} {% tab label="JavaScript" filename="multimodal_function.js" %} ```javascript // ✅ Include multimodal content in the function response const finalInteraction = await client.interactions.create({ model: "gemini-3.6-flash", previousInteractionId: interaction.id, input: [{ type: "function_result", name: toolCall.name, call_id: toolCall.id, result: [ { type: "text", text: "instrument.jpg" }, { type: "image", mime_type: "image/jpeg", data: base64ImageData, }, ], }], }); ``` {% /tab %} {% tab label="Java" %} ```java import java.util.Arrays; import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.FunctionResultStep; import com.google.genai.gaos.models.interactions.FunctionResultStepResultUnion; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.ImageContentMimeType; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.util.List; Client client = new Client(); // Assumes interactionId, callId, functionName, and base64ImageData from previous step String interactionId = "interaction-id-123"; String callId = "call-id-123"; String functionName = "get_instrument_image"; String base64ImageData = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII="; // ✅ Include multimodal content in the function response FunctionResultStep functionResult = FunctionResultStep.builder() .name(functionName) .callId(callId) .result( FunctionResultStepResultUnion.of( Arrays.asList( TextContent.builder().text("instrument.jpg").build(), ImageContent.builder() .mimeType(ImageContentMimeType.IMAGE_JPEG) .data(base64ImageData) .build()))) .build(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-3.5-flash")) .previousInteractionId(interactionId) .input(InteractionsInput.ofStep(Arrays.asList(functionResult))) .build(); Interaction finalInteraction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } // Assumes interactionID, callID, functionName, and base64ImageData from previous step interactionID := "interaction-id-123" callID := "call-id-123" functionName := "get_instrument_image" base64ImageData := "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=" // ✅ Include multimodal content in the function response functionResult := interactions.NewStep(interactions.FunctionResultStep{ Name: genai.Ptr(functionName), CallID: callID, Result: interactions.NewFunctionResultStepResultUnion([]interactions.FunctionResultSubcontent{ interactions.NewFunctionResultSubcontent(interactions.TextContent{ Text: "instrument.jpg", }), interactions.NewFunctionResultSubcontent(interactions.ImageContent{ MimeType: interactions.ImageContentMimeType("image/jpeg").ToPointer(), Data: genai.Ptr(base64ImageData), }), }), }) finalRes, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.5-flash"), PreviousInteractionID: genai.Ptr(interactionID), Input: interactions.NewInteractionsInput([]interactions.Step{functionResult}), }), }) if err != nil { log.Fatal(err) } _ = finalRes } ``` {% /tab %} {% /tabs %} ### Inline instructions in function responses {% id="inline-instructions" %} We often see clients provide additional instructions along with function responses as subsequent `Parts`. This can lead to unexpected model behavior (e.g. thought leakage) and result in lower quality outputs. Instead, append any extra instructions to the end of the function response text separated by two newlines. {% tabs %} {% tab label="Python" filename="inline_instructions.py" %} ```python # ✅ Append inline instructions to the end of the function response separated by two newlines result_text = f"{json.dumps(result)}\n\n" final_interaction = client.interactions.create( model="gemini-3.6-flash", previous_interaction_id=interaction.id, tools=[my_tool], input=[{ "type": "function_result", "name": fc_step.name, "call_id": fc_step.id, "result": [{"type": "text", "text": result_text}], }], ) ``` {% /tab %} {% tab label="JavaScript" filename="inline_instructions.js" %} ```javascript // ✅ Append inline instructions to the end of the function response separated by two newlines const resultText = `${JSON.stringify(result)}\n\n`; const finalInteraction = await client.interactions.create({ model: "gemini-3.6-flash", previousInteractionId: interaction.id, tools: [myTool], input: [{ type: "function_result", name: fcStep.name, call_id: fcStep.id, result: [{ type: "text", text: resultText }], }], }); ``` {% /tab %} {% tab label="Java" %} ```java import java.util.Arrays; import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Function; import com.google.genai.gaos.models.interactions.FunctionResultStep; import com.google.genai.gaos.models.interactions.FunctionResultStepResultUnion; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.util.List; Client client = new Client(); // Assumes interactionId, callId, functionName, myTool, and resultJson from previous step String interactionId = "interaction-id-123"; String callId = "call-id-123"; String functionName = "get_weather"; Function myTool = Function.builder().name(functionName).build(); String resultJson = "{\"temperature\": \"72F\"}"; // ✅ Append inline instructions to the end of the function response separated by two newlines String resultText = resultJson + "\n\n"; FunctionResultStep functionResult = FunctionResultStep.builder() .name(functionName) .callId(callId) .result( FunctionResultStepResultUnion.of( Arrays.asList(TextContent.builder().text(resultText).build()))) .build(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-3.5-flash")) .previousInteractionId(interactionId) .tools(Arrays.asList(myTool)) .input(InteractionsInput.ofStep(Arrays.asList(functionResult))) .build(); Interaction finalInteraction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } // Assumes interactionID, callID, functionName, myTool, and resultJSON from previous step interactionID := "interaction-id-123" callID := "call-id-123" functionName := "get_weather" myTool := interactions.NewTool(interactions.Function{Name: genai.Ptr(functionName)}) resultJSON := `{"temperature": "72F"}` // ✅ Append inline instructions to the end of the function response separated by two newlines resultText := resultJSON + "\n\n" functionResult := interactions.NewStep(interactions.FunctionResultStep{ Name: genai.Ptr(functionName), CallID: callID, Result: interactions.NewFunctionResultStepResultUnion([]interactions.FunctionResultSubcontent{ interactions.NewFunctionResultSubcontent(interactions.TextContent{Text: resultText}), }), }) finalRes, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.5-flash"), PreviousInteractionID: genai.Ptr(interactionID), Tools: []interactions.Tool{myTool}, Input: interactions.NewInteractionsInput([]interactions.Step{functionResult}), }), }) if err != nil { log.Fatal(err) } _ = finalRes } ``` {% /tab %} {% /tabs %} ### Reducing unnecessary tool calls {% id="reducing-tool-calls" %} If you experience an overuse of tool calls, two techniques help minimize them: 1. **Start by reducing the thinking level** (`medium`, `low`, or `minimal`): Higher thinking levels encourage the model to use more tools to explore and verify, so lowering the level can reduce tool calls. 2. **Add a system instruction:** If overuse persists after adjusting the thinking level, consider a prompt that restricts tool usage. For example: ```text You have a limited action budget of tool calls. Use them efficiently. ``` {% callout type="caution" %} **We strongly recommend updating to `google-genai` SDK v2.0.0 or later.** This version introduces breaking changes to the Interactions API. See the [breaking changes migration guide](/docs/interactions-breaking-changes-may-2026) for details. {% /callout %} ## Gemini 3 family features {% id="gemini-3-features" %} Gemini 3.5 Flash inherits all Gemini 3 family capabilities, including Computer Use. Features introduced in Gemini 3 that carry forward: * [**Thinking**](/docs/thinking)**:** Encrypted reasoning context preserved across API calls. Automatic in the Interactions API; implicit in GenerateContent. * [**Structured outputs with tools**](/docs/structured-output)**:** Combine JSON mode with built-in tools (Search, URL context, code execution, function calling). * [**Multimodal function responses**](/docs/function-calling#multimodal)**:** Return images, audio, and other media in function call results. * [**Code execution with images**](/docs/code-execution#images)**:** Execute code that processes and generates images. * [**Combined tool use**](/docs/tool-combination)**:** Use built-in tools and custom function calling in the same request. * [**Media resolution**](/docs/media-resolution)**:** Fine-grained control over token allocation for image, video, and PDF inputs. Gemini 3 models support per-content-item resolution settings (`low`, `medium`, `high`, `ultra_high`) for mixed-fidelity prompts. * [**Thought signatures**](/docs/thinking#signatures)**:** Encrypted representations of the model's internal reasoning. Required for multi-turn function calling in stateless mode; managed automatically by the Interactions API and the official SDKs. ## Prompting best practices {% id="prompting-best-practices" %} Gemini 3.x models are reasoning models, which changes how you should prompt. * **Precise instructions:** Be concise. Gemini 3.x responds best to direct, clear instructions. Verbose or complex prompt engineering techniques designed for older models may cause the model to over-analyze. * **Output verbosity:** By default, Gemini 3 and 3.1 is less verbose and prefers direct, efficient answers. If your use case requires a conversational tone, steer the model explicitly in your prompt (for example, "Explain this as a friendly, talkative assistant"). * **Context management:** When working with large datasets (such as entire books, codebases, or long videos), place your specific instructions or questions at the end of the prompt, after the data context. Anchor the model's reasoning by starting your question with a phrase like, "Based on the preceding information...". Learn more about prompt design strategies in the [prompt engineering guide](/docs/prompting-strategies). ## Limitations {% id="limitations" %} * Image segmentation is not supported in Gemini 3.x. For segmentation workloads, continue using Gemini 2.5 Flash with thinking off, or [Gemini Robotics-ER 1.6](/docs/robotics-overview). ## FAQ {% id="faq" %} 1. **What is the knowledge cutoff for Gemini 3.5 Flash?** Gemini 3.5 Flash has a knowledge cutoff of January 2025. For more recent information, use the [Search Grounding](/docs/google-search) tool. 2. **What are the context window limits?** Gemini 3.5 Flash supports a 1 million token input context window and up to 65k output tokens. 3. **Will my old `thinking_budget` code still work?** Yes, `thinking_budget` is still supported for backward compatibility, but we recommend migrating to `thinking_level` for more predictable performance. Don't use both in the same request. 4. **Does Gemini 3.5 Flash support the Batch API?** Yes. See the [Batch API](/docs/batch-api) guide for details. 5. **Is Context Caching supported?** Yes, [Context Caching](/docs/caching) is supported. 6. **Which tools are supported?** Gemini 3.5 Flash supports [Google Search](/docs/google-search), [Grounding with Google Maps](/docs/maps-grounding), [File Search](/docs/file-search), [Code Execution](/docs/code-execution), [URL Context](/docs/url-context), and standard [Function Calling](/docs/function-calling), including [combined tool use](/docs/tool-combination), and [Computer Use](/docs/computer-use). ## Other models {% id="other-models" %} * [Gemini 3.8 Flash (Latest)](/docs/latest-model) * [Gemini 3.6 Flash and 3.5 Flash-Lite](/docs/whats-new-gemini-3.6) * [See all models](/docs/models) ## What's next {% id="whats-next" %} * Learn more about prompt design strategies in the [prompt engineering guide](/docs/prompting-strategies). * Get started with the [Gemini 3 Cookbook](https://github.com/google-gemini/cookbook) * Learn about [Gemini API optimization and inference](/docs/optimization) # Nano Banana image generation Source: https://aistudio.google.com/docs/image-generation Description: Get started generating images with the Gemini API using Nano Banana and Nano Banana Pro {% button href="https://aistudio.google.com" variant="ais" %}Try in Google AI Studio{% /button %} **Nano Banana** is the name for Gemini's native image generation capabilities. Gemini can generate and process images conversationally with text, images, video, or a combination. This lets you create, edit, and iterate on visuals with unprecedented control. ## Model selection {% id="model-selection" %} Nano Banana refers to the following models available in the Gemini API: * **Nano Banana 2.1**: The [Gemini Nano Banana 2.1](/docs/models/gemini-nano-banana-2.1) model (`gemini-nano-banana-2.1`). An update to Nano Banana 2, serving as the primary high-efficiency workhorse model for image generation and conversational editing. It maintains Flash-level speed and cost efficiency while delivering improved visual quality, text rendering, multi-turn consistency, and Google Search grounding across 1K, 2K, and 4K resolutions. * **Nano Banana 2 Lite**: The [Gemini 3.1 Flash Lite Image](/docs/models/gemini-3.1-flash-lite-image) model (`gemini-3.1-flash-lite-image`). The fastest and cheapest Gemini image model, engineered for velocity and scale where speed and cost are primary constraints. Not optimized for multiple reference inputs or multi-turn sequential editing. * **Nano Banana 2**: The [Gemini 3.1 Flash Image](/docs/models/gemini-3.1-flash-image) model (`gemini-3.1-flash-image`). The previous-generation high-efficiency workhorse model, optimized for speed, 4K generation, and multiple reference image consistency. Recommended for all new projects to use Nano Banana 2.1. * **Nano Banana Pro**: The [Gemini 3 Pro Image](/docs/models/gemini-3-pro-image) model (`gemini-3-pro-image`). The premium choice for complex visual tasks, utilizing advanced reasoning ("Thinking") to follow complex instructions, maintain brand consistency, and render high-fidelity text. * **Nano Banana**: The [Gemini 2.5 Flash Image](/docs/models/gemini-2.5-flash-image) model (`gemini-2.5-flash-image`). The legacy model of the Nano Banana series. Recommended migration path is Nano Banana 2 Lite for higher quality, faster speeds, and lower pricing. All generated images include a [SynthID watermark](https://ai.google.dev/responsible/docs/safeguards/synthid). ## Image generation (text-to-image) {% id="image-generation-text-to-image" %} {% tabs %} {% tab label="Python" %} ```python from google import genai from PIL import Image import base64 client = genai.Client() interaction = client.interactions.create( model="gemini-nano-banana-2.1", input="Create a picture of a nano banana dish in a fancy restaurant with a Gemini theme", ) with open("generated_image.png", "wb") as f: f.write(base64.b64decode(interaction.output_image.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const prompt = "Create a picture of a nano banana dish in a fancy restaurant with a Gemini theme"; const interaction = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: prompt, }); const generatedImage = interaction.output_image; if (generatedImage) { if (generatedImage && generatedImage.data) { const buffer = Buffer.from(generatedImage.data, "base64"); fs.writeFileSync("gemini-native-image.png", buffer); } console.log("Image saved as gemini-native-image.png"); } } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Base64; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input( InteractionsInput.of( "Create a picture of a nano banana dish in a fancy restaurant with a Gemini theme")) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.outputImage().isPresent() && interaction.outputImage().get().data().isPresent()) { byte[] imageBytes = Base64.getDecoder().decode(interaction.outputImage().get().data().get()); Files.write(Paths.get("generated_image.png"), imageBytes); } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput("Create a picture of a nano banana dish in a fancy restaurant with a Gemini theme"), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputImage != nil && res.Interaction.OutputImage.Data != nil { imageBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputImage.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("generated_image.png", imageBytes, 0644); err != nil { log.Fatal(err) } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-nano-banana-2.1", "input": [ {"type": "text", "text": "Create a picture of a nano banana dish in a fancy restaurant with a Gemini theme"} ] }' ``` {% /tab %} {% /tabs %} You can retrieve generated image data by using the `interaction.output_image` property, which returns the last generated image block. {% callout type="note" %} Note: For complex, interleaved text-and-image outputs (such as stories containing illustrations), convenience properties will not capture all parts. You must manually iterate over the steps instead-see [Interleaved text and images](/docs/image-generation#interleaved-output) for an example. {% /callout %} ## Image editing (text-and-image-to-image) {% id="gemini-image-editing" %} **Reminder**: Make sure you have the necessary rights to any images you upload. Don't generate content that infringe on others' rights, including videos or images that deceive, harass, or harm. Your use of this generative AI service is subject to our [Prohibited Use Policy](https://policies.google.com/terms/generative-ai/use-policy). Provide an image and use text prompts to add, remove, or modify elements, change the style, or adjust the color grading. The following example demonstrates uploading `base64` encoded images. For multiple images, larger payloads, and supported MIME types, check the [Image understanding](/docs/image-understanding) page. {% tabs %} {% tab label="Python" %} ```python from google import genai from PIL import Image import base64 client = genai.Client() with open("/path/to/cat_image.png", "rb") as f: image_bytes = f.read() interaction = client.interactions.create( model="gemini-nano-banana-2.1", input=[ { "type": "text", "text": "Create a picture of a nano banana dish in a fancy restaurant with a Gemini theme" }, { "type": "image", "data": base64.b64encode(image_bytes).decode('utf-8'), "mime_type": "image/png" } ], ) with open("generated_image.png", "wb") as f: f.write(base64.b64decode(interaction.output_image.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const imagePath = "path/to/cat_image.png"; const imageData = fs.readFileSync(imagePath); const base64Image = imageData.toString("base64"); const interaction = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: [ { type: "text", text: "Create a picture of my cat eating a nano-banana in a" + "fancy restaurant under the Gemini constellation" }, { type: "image", mime_type: "image/png", data: base64Image }, ], }); const generatedImage = interaction.output_image; if (generatedImage) { if (generatedImage && generatedImage.data) { const buffer = Buffer.from(generatedImage.data, "base64"); fs.writeFileSync("gemini-native-image.png", buffer); } console.log("Image saved as gemini-native-image.png"); } } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.ImageContentMimeType; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; import java.util.List; Client client = new Client(); byte[] inputBytes = Files.readAllBytes(Paths.get("/path/to/cat_image.png")); String base64Image = Base64.getEncoder().encodeToString(inputBytes); Content textContent = TextContent.builder() .text("Create a picture of a nano banana dish in a fancy restaurant with a Gemini theme") .build(); Content imageContent = ImageContent.builder() .data(base64Image) .mimeType(ImageContentMimeType.IMAGE_PNG) .build(); List contents = Arrays.asList(textContent, imageContent); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input(InteractionsInput.ofContent(contents)) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.outputImage().isPresent() && interaction.outputImage().get().data().isPresent()) { byte[] outputBytes = Base64.getDecoder().decode(interaction.outputImage().get().data().get()); Files.write(Paths.get("generated_image.png"), outputBytes); } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } inputBytes, err := os.ReadFile("/path/to/cat_image.png") if err != nil { log.Fatal(err) } base64Image := base64.StdEncoding.EncodeToString(inputBytes) res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput([]interactions.Content{ interactions.NewContent(interactions.TextContent{ Text: "Create a picture of a nano banana dish in a fancy restaurant with a Gemini theme", }), interactions.NewContent(interactions.ImageContent{ Data: genai.Ptr(base64Image), MimeType: interactions.ImageContentMimeTypeImagePng.ToPointer(), }), }), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputImage != nil && res.Interaction.OutputImage.Data != nil { outputBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputImage.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("generated_image.png", outputBytes, 0644); err != nil { log.Fatal(err) } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ -d "{ \"model\": \"gemini-nano-banana-2.1\", \"input\": [ {\"type\": \"text\", \"text\": \"Create a picture of my cat eating a nano-banana in a fancy restaurant under the Gemini constellation\"}, { \"type\": \"image\", \"mime_type\": \"image/jpeg\", \"data\": \"[BASE64_IMAGE_DATA]\" } ] }" ``` {% /tab %} {% /tabs %} ### Multi-turn image editing {% id="multi-turn-image-editing" %} Keep generating and editing images conversationally. Multi-turn conversation is the recommended way to iterate on images. The following example shows a prompt to generate an infographic about photosynthesis. {% tabs %} {% tab label="Python" %} ```python from google import genai import base64 client = genai.Client() interaction = client.interactions.create( model="gemini-nano-banana-2.1", input="Create a vibrant infographic that explains photosynthesis as if it were a recipe for a plant's favorite food. Show the \"ingredients\" (sunlight, water, CO2) and the \"finished dish\" (sugar/energy). The style should be like a page from a colorful kids' cookbook, suitable for a 4th grader.", tools=[{"type": "google_search"}], ) with open("photosynthesis.png", "wb") as f: f.write(base64.b64decode(interaction.output_image.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; const ai = new GoogleGenAI({}); async function main() { const interaction = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: "Create a vibrant infographic that explains photosynthesis as if it were a recipe for a plant's favorite food. Show the \"ingredients\" (sunlight, water, CO2) and the \"finished dish\" (sugar/energy). The style should be like a page from a colorful kids' cookbook, suitable for a 4th grader.", tools: [{"type": "google_search"}], }); const generatedImage = interaction.output_image; if (generatedImage) { if (generatedImage && generatedImage.data) { const buffer = Buffer.from(generatedImage.data, "base64"); fs.writeFileSync("photosynthesis.png", buffer); } console.log("Image saved as photosynthesis.png"); } } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.GoogleSearch; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input( InteractionsInput.of( "Create a vibrant infographic that explains photosynthesis as if it were a recipe for a plant's favorite food. Show the \"ingredients\" (sunlight, water, CO2) and the \"finished dish\" (sugar/energy). The style should be like a page from a colorful kids' cookbook, suitable for a 4th grader.")) .tools(Arrays.asList(new GoogleSearch())) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.outputImage().isPresent() && interaction.outputImage().get().data().isPresent()) { byte[] imageBytes = Base64.getDecoder().decode(interaction.outputImage().get().data().get()); Files.write(Paths.get("photosynthesis.png"), imageBytes); } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput(`Create a vibrant infographic that explains photosynthesis as if it were a recipe for a plant's favorite food. Show the "ingredients" (sunlight, water, CO2) and the "finished dish" (sugar/energy). The style should be like a page from a colorful kids' cookbook, suitable for a 4th grader.`), Tools: []interactions.Tool{ interactions.NewTool(interactions.GoogleSearch{}), }, }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputImage != nil && res.Interaction.OutputImage.Data != nil { imageBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputImage.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("photosynthesis.png", imageBytes, 0644); err != nil { log.Fatal(err) } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-nano-banana-2.1", "input": [ {"type": "text", "text": "Create a vibrant infographic that explains photosynthesis as if it were a recipe for a plants favorite food. Show the \"ingredients\" (sunlight, water, CO2) and the \"finished dish\" (sugar/energy). The style should be like a page from a colorful kids cookbook, suitable for a 4th grader."} ], "tools": [{"type": "google_search"}] }' ``` {% /tab %} {% /tabs %} {% image src="/googledevai/static/gemini-api/docs/images/infographic-eng.png" alt="AI-generated infographic about photosynthesis" caption="AI-generated infographic about photosynthesis" variant="screenshot" /%} You can then use the `previous_interaction_id` to change the language on the graphic to Spanish. {% tabs %} {% tab label="Python" %} ```python interaction_2 = client.interactions.create( model="gemini-nano-banana-2.1", input="Update this infographic to be in Spanish. Do not change any other elements of the image.", previous_interaction_id=interaction.id, response_format={ "type": "image", "mime_type": "image/jpeg", "aspect_ratio": "16:9", "image_size": "2K" }, ) generated_image = interaction_2.output_image if generated_image: with open("photosynthesis_spanish.png", "wb") as f: f.write(base64.b64decode(generated_image.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript const interaction2 = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: "Update this infographic to be in Spanish. Do not change any other elements of the image.", previous_interaction_id: interaction.id, response_format: { type: "image", mime_type: "image/png", aspect_ratio: "16:9", image_size: "2K" }, }); const generatedImage = interaction2.output_image; if (generatedImage) { if (generatedImage && generatedImage.data) { const buffer = Buffer.from(generatedImage.data, "base64"); fs.writeFileSync("photosynthesis_spanish.png", buffer); } } ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.CreateModelInteractionResponseFormat; import com.google.genai.gaos.models.interactions.GoogleSearch; import com.google.genai.gaos.models.interactions.ImageResponseFormat; import com.google.genai.gaos.models.interactions.ImageResponseFormatAspectRatio; import com.google.genai.gaos.models.interactions.ImageResponseFormatImageSize; import com.google.genai.gaos.models.interactions.ImageResponseFormatMimeType; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ResponseFormat; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; Client client = new Client(); CreateModelInteraction turn1Params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input( InteractionsInput.of( "Create a vibrant infographic that explains photosynthesis as if it were a recipe for a plant's favorite food.")) .tools(Arrays.asList(new GoogleSearch())) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(turn1Params)).interaction().get(); CreateModelInteractionResponseFormat format = CreateModelInteractionResponseFormat.of( ResponseFormat.of( ImageResponseFormat.builder() .mimeType(ImageResponseFormatMimeType.IMAGE_JPEG) .aspectRatio(ImageResponseFormatAspectRatio.of("16:9")) .imageSize(ImageResponseFormatImageSize.TWO_K) .build())); CreateModelInteraction turn2Params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input( InteractionsInput.of( "Update this infographic to be in Spanish. Do not change any other elements of the image.")) .previousInteractionId(interaction.id().orElse("")) .responseFormat(format) .build(); Interaction interaction2 = client.interactions.create(CreateInteractionRequestBody.of(turn2Params)).interaction().get(); if (interaction2.outputImage().isPresent() && interaction2.outputImage().get().data().isPresent()) { byte[] imageBytes = Base64.getDecoder().decode(interaction2.outputImage().get().data().get()); Files.write(Paths.get("photosynthesis_spanish.png"), imageBytes); } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res1, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput("Create a vibrant infographic that explains photosynthesis as if it were a recipe for a plant's favorite food."), Tools: []interactions.Tool{ interactions.NewTool(interactions.GoogleSearch{}), }, }), }) if err != nil { log.Fatal(err) } format := interactions.NewCreateModelInteractionResponseFormat( interactions.NewResponseFormat(interactions.ImageResponseFormat{ MimeType: interactions.ImageResponseFormatMimeTypeImageJpeg.ToPointer(), AspectRatio: interactions.ImageResponseFormatAspectRatio("16:9").ToPointer(), ImageSize: interactions.ImageResponseFormatImageSizeTwoK.ToPointer(), }), ) res2, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput("Update this infographic to be in Spanish. Do not change any other elements of the image."), PreviousInteractionID: res1.Interaction.ID, ResponseFormat: genai.Ptr(format), }), }) if err != nil { log.Fatal(err) } if res2.Interaction.OutputImage != nil && res2.Interaction.OutputImage.Data != nil { imageBytes, err := base64.StdEncoding.DecodeString(*res2.Interaction.OutputImage.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("photosynthesis_spanish.png", imageBytes, 0644); err != nil { log.Fatal(err) } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-nano-banana-2.1", "input": "Update this infographic to be in Spanish. Do not change any other elements of the image.", "previous_interaction_id": "[PREVIOUS_INTERACTION_ID]", "response_format": { "type": "image", "mime_type": "image/jpeg", "aspect_ratio": "16:9", "image_size": "2K" } }' ``` {% /tab %} {% /tabs %} {% image src="/googledevai/static/gemini-api/docs/images/infographic-spanish.png" alt="AI-generated infographic of photosynthesis in Spanish" caption="AI-generated infographic of photosynthesis in Spanish" variant="screenshot" /%} ## Features of Nano Banana {% id="gemini-3-capabilities" %} Nano Banana models offer state-of-the-art image generation and editing. Gemini Nano Banana 2.1 and Gemini 3.1 Flash Image are optimized for speed and high-volume use-cases, and Gemini 3 Pro Image is optimized for professional asset production. Designed to tackle the most challenging workflows through advanced reasoning, they excel at complex, multi-turn creation and modification tasks. - **High-resolution output**: Built-in generation capabilities for 1K, 2K, and 4K visuals. - **Gemini 3.1 Flash Image** adds the smaller 512px (0.5K) resolution (not supported on Gemini Nano Banana 2.1). - **Advanced text rendering**: Capable of generating legible, stylized text for infographics, menus, diagrams, and marketing assets. - **Grounding with Google Search**: The model can use Google Search as a tool to verify facts and generate imagery based on real-time data (e.g., current weather maps, stock charts, recent events). - **Gemini Nano Banana 2.1 and Gemini 3.1 Flash Image** add the integration of Google Image Search Grounding alongside Web Search. - **Thinking mode**: The model utilizes a "thinking" process to reason through complex prompts. It generates interim "thought images" (visible in the backend but not charged) to refine the composition before producing the final high-quality output. - **Up to 14 reference images**: Mix up to 14 reference images to produce the final image. - **New aspect ratios**: Gemini Nano Banana 2.1 and Gemini 3.1 Flash Image add 1:4, 4:1, 1:8, and 8:1 [aspect ratios](/docs/image-generation#aspect-ratios-and-image-size). ### Use up to 14 reference images {% id="use-14-images" %} Nano Banana models allow you to mix up to 14 reference images. These 14 images can include the following: | Gemini Nano Banana 2.1 & Gemini 3.1 Flash Image | Gemini 3 Pro Image | | :---- | :---- | | Up to 10 images of objects with high-fidelity to include in the final image | Up to 6 images of objects with high-fidelity to include in the final image | | Up to 4 images of characters to maintain character consistency | Up to 5 images of characters to maintain character consistency | | N/A | Up to 3 images to be used as style references | {% tabs %} {% tab label="Python" %} ```python from google import genai from google.genai import types from PIL import Image import base64 prompt = "An office group photo of these people, they are making funny faces." client = genai.Client() interaction = client.interactions.create( model="gemini-nano-banana-2.1", input=[ { "type": "text", "text": prompt, }, { "type": "image", "data": base64.b64encode(image_bytes).decode('utf-8'), "mime_type": "image/png" }, { "type": "image", "data": base64.b64encode(image_bytes).decode('utf-8'), "mime_type": "image/png" }, { "type": "image", "data": base64.b64encode(image_bytes).decode('utf-8'), "mime_type": "image/png" }, { "type": "image", "data": base64.b64encode(image_bytes).decode('utf-8'), "mime_type": "image/png" }, { "type": "image", "data": base64.b64encode(image_bytes).decode('utf-8'), "mime_type": "image/png" }, ], response_format={ "type": "image", "aspect_ratio": "5:4", "image_size": "2K" }, ) with open("office.png", "wb") as f: f.write(base64.b64decode(interaction.output_image.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: [ { type: "text", text: "An office group photo of these people, they are making funny faces.", }, { type: "image", mime_type: "image/jpeg", data: base64ImageFile1 }, { type: "image", mime_type: "image/jpeg", data: base64ImageFile2 }, { type: "image", mime_type: "image/jpeg", data: base64ImageFile3 }, { type: "image", mime_type: "image/jpeg", data: base64ImageFile4 }, { type: "image", mime_type: "image/jpeg", data: base64ImageFile5 }, ], response_format: { type: "image", aspect_ratio: "5:4", image_size: "2K", }, }); if (interaction.output_image && interaction.output_image.data) { const buffer = Buffer.from(interaction.output_image.data, 'base64'); fs.writeFileSync('office.png', buffer); } } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.CreateModelInteractionResponseFormat; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.ImageContentMimeType; import com.google.genai.gaos.models.interactions.ImageResponseFormat; import com.google.genai.gaos.models.interactions.ImageResponseFormatAspectRatio; import com.google.genai.gaos.models.interactions.ImageResponseFormatImageSize; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ResponseFormat; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; import java.util.List; String prompt = "An office group photo of these people, they are making funny faces."; byte[] imageBytes = Files.readAllBytes(Paths.get("/path/to/person.png")); String base64Image = Base64.getEncoder().encodeToString(imageBytes); Content textContent = TextContent.builder().text(prompt).build(); Content imageContent = ImageContent.builder() .data(base64Image) .mimeType(ImageContentMimeType.IMAGE_PNG) .build(); List contents = Arrays.asList( textContent, imageContent, imageContent, imageContent, imageContent, imageContent); CreateModelInteractionResponseFormat format = CreateModelInteractionResponseFormat.of( ResponseFormat.of( ImageResponseFormat.builder() .aspectRatio(ImageResponseFormatAspectRatio.of("5:4")) .imageSize(ImageResponseFormatImageSize.TWO_K) .build())); Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input(InteractionsInput.ofContent(contents)) .responseFormat(format) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.outputImage().isPresent() && interaction.outputImage().get().data().isPresent()) { byte[] outBytes = Base64.getDecoder().decode(interaction.outputImage().get().data().get()); Files.write(Paths.get("office.png"), outBytes); } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } prompt := "An office group photo of these people, they are making funny faces." imageBytes, err := os.ReadFile("/path/to/person.png") if err != nil { log.Fatal(err) } base64Image := base64.StdEncoding.EncodeToString(imageBytes) textContent := interactions.NewContent(interactions.TextContent{ Text: prompt, }) imageContent := interactions.NewContent(interactions.ImageContent{ Data: genai.Ptr(base64Image), MimeType: interactions.ImageContentMimeTypeImagePng.ToPointer(), }) contents := []interactions.Content{ textContent, imageContent, imageContent, imageContent, imageContent, imageContent, } format := interactions.NewCreateModelInteractionResponseFormat( interactions.NewResponseFormat(interactions.ImageResponseFormat{ AspectRatio: interactions.ImageResponseFormatAspectRatio("5:4").ToPointer(), ImageSize: interactions.ImageResponseFormatImageSizeTwoK.ToPointer(), }), ) res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput(contents), ResponseFormat: genai.Ptr(format), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputImage != nil && res.Interaction.OutputImage.Data != nil { outBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputImage.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("office.png", outBytes, 0644); err != nil { log.Fatal(err) } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ -d "{ \"model\": \"gemini-nano-banana-2.1\", \"input\": [ {\"type\": \"text\", \"text\": \"An office group photo of these people, they are making funny faces.\"}, {\"type\": \"image\", \"mime_type\": \"image/png\", \"data\": \"[BASE64_DATA_IMG_1]\"}, {\"type\": \"image\", \"mime_type\": \"image/png\", \"data\": \"[BASE64_DATA_IMG_2]\"}, {\"type\": \"image\", \"mime_type\": \"image/png\", \"data\": \"[BASE64_DATA_IMG_3]\"}, {\"type\": \"image\", \"mime_type\": \"image/png\", \"data\": \"[BASE64_DATA_IMG_4]\"}, {\"type\": \"image\", \"mime_type\": \"image/png\", \"data\": \"[BASE64_DATA_IMG_5]\"} ], \"response_format\": { \"type\": \"image\", \"aspect_ratio\": \"5:4\", \"image_size\": \"2K\" } }" ``` {% /tab %} {% /tabs %} {% image src="/googledevai/static/gemini-api/docs/images/office-group-photo.jpeg" alt="AI-generated office group photo" caption="AI-generated office group photo" variant="screenshot" /%} ### Grounding with Google Search {% id="use-with-grounding" %} Use the [Google Search tool](/docs/google-search) to generate images based on real-time information, such as weather forecasts, stock charts, or recent events. Note that when using Grounding with Google Search with image generation, image-based search results are not passed to the generation model and are excluded from the response (see [Grounding with Google Image Search](/docs/image-generation#image-search)). {% callout type="note" %} Grounding with Google Search is not supported by the `gemini-3.1-flash-lite-image` model. {% /callout %} {% tabs %} {% tab label="Python" %} ```python from google import genai from google.genai import types import base64 prompt = "Visualize the current weather forecast for the next 5 days in San Francisco as a clean, modern weather chart. Add a visual on what I should wear each day" client = genai.Client() interaction = client.interactions.create( model="gemini-nano-banana-2.1", input=prompt, tools=[{"type": "google_search"}], response_format={ "type": "image", "mime_type": "image/jpeg", "aspect_ratio": "16:9" }, ) with open("weather.png", "wb") as f: f.write(base64.b64decode(interaction.output_image.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: "Visualize the current weather forecast for the next 5 days in San Francisco as a clean, modern weather chart. Add a visual on what I should wear each day", tools: [{"type": "google_search"}], response_format: { type: "image", mime_type: "image/png", aspect_ratio: "16:9", image_size: "2K" }, }); if (interaction.output_image && interaction.output_image.data) { const buffer = Buffer.from(interaction.output_image.data, 'base64'); fs.writeFileSync('weather.png', buffer); } } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.CreateModelInteractionResponseFormat; import com.google.genai.gaos.models.interactions.GoogleSearch; import com.google.genai.gaos.models.interactions.ImageResponseFormat; import com.google.genai.gaos.models.interactions.ImageResponseFormatAspectRatio; import com.google.genai.gaos.models.interactions.ImageResponseFormatMimeType; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ResponseFormat; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; String prompt = "Visualize the current weather forecast for the next 5 days in San Francisco as a clean, modern weather chart. Add a visual on what I should wear each day"; Client client = new Client(); CreateModelInteractionResponseFormat format = CreateModelInteractionResponseFormat.of( ResponseFormat.of( ImageResponseFormat.builder() .mimeType(ImageResponseFormatMimeType.IMAGE_JPEG) .aspectRatio(ImageResponseFormatAspectRatio.of("16:9")) .build())); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input(InteractionsInput.of(prompt)) .tools(Arrays.asList(new GoogleSearch())) .responseFormat(format) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.outputImage().isPresent() && interaction.outputImage().get().data().isPresent()) { byte[] imageBytes = Base64.getDecoder().decode(interaction.outputImage().get().data().get()); Files.write(Paths.get("weather.png"), imageBytes); } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } prompt := "Visualize the current weather forecast for the next 5 days in San Francisco as a clean, modern weather chart. Add a visual on what I should wear each day" format := interactions.NewCreateModelInteractionResponseFormat( interactions.NewResponseFormat(interactions.ImageResponseFormat{ MimeType: interactions.ImageResponseFormatMimeTypeImageJpeg.ToPointer(), AspectRatio: interactions.ImageResponseFormatAspectRatio("16:9").ToPointer(), }), ) res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput(prompt), Tools: []interactions.Tool{ interactions.NewTool(interactions.GoogleSearch{}), }, ResponseFormat: genai.Ptr(format), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputImage != nil && res.Interaction.OutputImage.Data != nil { imageBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputImage.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("weather.png", imageBytes, 0644); err != nil { log.Fatal(err) } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-nano-banana-2.1", "input": [ {"type": "text", "text": "Visualize the current weather forecast for the next 5 days in San Francisco as a clean, modern weather chart. Add a visual on what I should wear each day"} ], "tools": [{"type": "google_search"}], "response_format": { "type": "image", "mime_type": "image/jpeg", "aspect_ratio": "16:9" } }' ``` {% /tab %} {% /tabs %} {% image src="/googledevai/static/gemini-api/docs/images/weather-forecast.png" alt="AI-generated five day weather chart for San Francisco" caption="AI-generated five day weather chart for San Francisco" variant="screenshot" /%} The response includes `google_search_call` and `google_search_result` steps, along with inline `url_citation` annotations on the text step: - **`google_search_result`**: Contains `search_suggestions`, an HTML snippet for rendering search suggestions in your UI. - **`url_citation` annotations**: Inline citations on the text step linking parts of the response to their web sources. ### Grounding with Google Search for Images (Nano Banana 2.1 and 3.1 Flash) {% id="image-search" %} {% callout type="note" %} Note: This feature is only available for the Gemini Nano Banana 2.1 and Gemini 3.1 Flash Image models. {% /callout %} Grounding with Google Image Search allows models to use web images retrieved via Google Image Search as visual context for image generation. Image Search is a new search type within the existing Grounding with Google Search tool, functioning alongside standard [Web Search](/docs/image-generation#use-with-grounding). To enable Image Search, configure the `google_search` tool in your API request and specify `image_search` within the `search_types` array. Image Search can be used independently or together with Web Search. {% tabs %} {% tab label="Python" %} ```python from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-nano-banana-2.1", input="A detailed painting of a Timareta butterfly resting on a flower", tools=[{ "type": "google_search", "search_types": ["web_search", "image_search"] }] ) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; async function main() { const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: "A detailed painting of a Timareta butterfly resting on a flower", tools: [{ "type": "google_search", "search_types": ["web_search", "image_search"] }] }); } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.GoogleSearch; import com.google.genai.gaos.models.interactions.GoogleSearchSearchType; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.util.Arrays; Client client = new Client(); GoogleSearch searchTool = GoogleSearch.builder() .searchTypes( Arrays.asList( GoogleSearchSearchType.WEB_SEARCH, GoogleSearchSearchType.IMAGE_SEARCH)) .build(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input( InteractionsInput.of( "A detailed painting of a Timareta butterfly resting on a flower")) .tools(Arrays.asList(searchTool)) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } searchTool := interactions.GoogleSearch{ SearchTypes: []interactions.GoogleSearchSearchType{ interactions.GoogleSearchSearchTypeWebSearch, interactions.GoogleSearchSearchTypeImageSearch, }, } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput("A detailed painting of a Timareta butterfly resting on a flower"), Tools: []interactions.Tool{ interactions.NewTool(searchTool), }, }), }) if err != nil { log.Fatal(err) } _ = res } ``` {% /tab %} {% tab label="REST" %} ```shell curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-nano-banana-2.1", "input": "A detailed painting of a Timareta butterfly resting on a flower", "tools": [{"type": "google_search", "search_types": ["web_search", "image_search"]}] }' ``` {% /tab %} {% /tabs %} **Display requirements** When you use Image Search within Grounding with Google Search, you must display the `search_suggestions` from the `google_search_result` step. Full usage requirements are detailed in the [Terms of Service](/docs/terms#grounding-with-google-search). **Response** For grounded responses using image search, the API returns inline citations and attribution metadata as part of the response steps: * **`url_citation` annotations**: Inline citations on the text content block within `model_output`, linking the generated content to its source. * **`google_search_result`**: Contains `search_suggestions`, an HTML snippet for rendering search suggestions in your UI. ### Video-to-image generation (Nano Banana 2.1, 3.1 Flash, and 3.1 Flash Lite) {% id="video-to-image" %} {% callout type="note" %} Note: This feature is only available for the Gemini Nano Banana 2.1, Gemini 3.1 Flash Image, and Gemini 3.1 Flash Lite Image models. {% /callout %} Video-to-image generation allows you to generate new images using a video's context as a multimodal reference. This is useful for creating high-quality video thumbnails, cinematic posters, summary infographics, or new artwork inspired by a video scene. During generation, the model analyzes the video frames in context to extract visual themes and key events, then uses them alongside your text prompt to synthesize the output image. You can pass public [YouTube URLs](/docs/video-understanding#youtube) directly in your API request or upload local video files using the [Files API](/docs/files). {% tabs %} {% tab label="Python" %} ```python from google import genai from google.genai import types import base64 client = genai.Client() interaction = client.interactions.create( model="gemini-nano-banana-2.1", input=[ { "type": "video", "uri": "https://www.youtube.com/watch?v=UTdfxFyOQTI", "mime_type": "video/mp4" }, {"type": "text", "text": "Generate a poster image that captures the key themes of this video."} ], response_format={"type": "image", "aspect_ratio": "16:9"} ) for step in interaction.steps: if step.type == "model_output": for content_block in step.content: if content_block.type == "text": print(content_block.text) elif content_block.type == "image": with open("video_poster.png", "wb") as f: f.write(base64.b64decode(content_block.data)) print("Image saved as video_poster.png") ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: [ { type: "video", uri: "https://www.youtube.com/watch?v=UTdfxFyOQTI", mime_type: "video/mp4" }, { type: "text", text: "Generate a poster image that captures the key themes of this video." } ], response_format: { type: "image", aspect_ratio: "16:9" } }); for (const step of interaction.steps) { if (step.type === "model_output") { for (const contentBlock of step.content || []) { if (contentBlock.type === "text") { console.log(contentBlock.text); } else if (contentBlock.type === "image") { if (contentBlock.data) { const buffer = Buffer.from(contentBlock.data, "base64"); fs.writeFileSync("video_poster.png", buffer); } console.log("Image saved as video_poster.png"); } } } } } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.CreateModelInteractionResponseFormat; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.ImageResponseFormat; import com.google.genai.gaos.models.interactions.ImageResponseFormatAspectRatio; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ModelOutputStep; import com.google.genai.gaos.models.interactions.ResponseFormat; import com.google.genai.gaos.models.interactions.Step; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.interactions.VideoContent; import com.google.genai.gaos.models.interactions.VideoContentMimeType; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; import java.util.List; Client client = new Client(); Content videoContent = VideoContent.builder() .uri("https://www.youtube.com/watch?v=UTdfxFyOQTI") .mimeType(VideoContentMimeType.VIDEO_MP4) .build(); Content textContent = TextContent.builder() .text("Generate a poster image that captures the key themes of this video.") .build(); List contents = Arrays.asList(videoContent, textContent); CreateModelInteractionResponseFormat format = CreateModelInteractionResponseFormat.of( ResponseFormat.of( ImageResponseFormat.builder() .aspectRatio(ImageResponseFormatAspectRatio.of("16:9")) .build())); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input(InteractionsInput.ofContent(contents)) .responseFormat(format) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.steps().isPresent()) { for (Step step : interaction.steps().get()) { if (step instanceof ModelOutputStep) { ModelOutputStep outputStep = (ModelOutputStep) step; if (outputStep.content().isPresent()) { for (Content block : outputStep.content().get()) { if (block instanceof TextContent) { System.out.println(((TextContent) block).text().orElse("")); } else if (block instanceof ImageContent) { ImageContent img = (ImageContent) block; if (img.data().isPresent()) { byte[] imgBytes = Base64.getDecoder().decode(img.data().get()); Files.write(Paths.get("video_poster.png"), imgBytes); System.out.println("Image saved as video_poster.png"); } } } } } } } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "fmt" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } contents := []interactions.Content{ interactions.NewContent(interactions.VideoContent{ URI: genai.Ptr("https://www.youtube.com/watch?v=UTdfxFyOQTI"), MimeType: interactions.VideoContentMimeTypeVideoMp4.ToPointer(), }), interactions.NewContent(interactions.TextContent{ Text: "Generate a poster image that captures the key themes of this video.", }), } format := interactions.NewCreateModelInteractionResponseFormat( interactions.NewResponseFormat(interactions.ImageResponseFormat{ AspectRatio: interactions.ImageResponseFormatAspectRatio("16:9").ToPointer(), }), ) res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput(contents), ResponseFormat: genai.Ptr(format), }), }) if err != nil { log.Fatal(err) } for _, step := range res.Interaction.Steps { if step.ModelOutputStep != nil { for _, block := range step.ModelOutputStep.Content { if block.TextContent != nil { fmt.Println(block.TextContent.Text) } else if block.ImageContent != nil && block.ImageContent.Data != nil { imgBytes, err := base64.StdEncoding.DecodeString(*block.ImageContent.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("video_poster.png", imgBytes, 0644); err != nil { log.Fatal(err) } fmt.Println("Image saved as video_poster.png") } } } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-nano-banana-2.1", "input": [ { "type": "video", "uri": "https://www.youtube.com/watch?v=UTdfxFyOQTI", "mime_type": "video/mp4" }, { "type": "text", "text": "Generate a poster image that captures the key themes of this video." } ], "response_format": { "type": "image", "aspect_ratio": "16:9" } }' ``` {% /tab %} {% /tabs %} {% image src="/googledevai/static/gemini-api/docs/images/youtube_infographics.jpg" alt="AI-generated infographic from a youtube video" caption="AI-generated infographic from a youtube video" variant="screenshot" /%} ### Generate images up to 4K resolution {% id="generate-4k-images" %} Gemini 3 image models generate 1K images by default but can also output 2K, 4K, and 512px (05.K) (Gemini 3.1 Flash Image only) images. To generate higher resolution assets, specify the `image_size` in the `response_format`. You must use an uppercase 'K' (e.g. 512px (05.K), 1K, 2K, 4K). Lowercase parameters (e.g., 1k) will be rejected. {% tabs %} {% tab label="Python" %} ```python from google import genai from google.genai import types import base64 prompt = "Da Vinci style anatomical sketch of a dissected Monarch butterfly. Detailed drawings of the head, wings, and legs on textured parchment with notes in English." client = genai.Client() interaction = client.interactions.create( model="gemini-nano-banana-2.1", input=prompt, response_format={ "type": "image", "mime_type": "image/jpeg", "aspect_ratio": "1:1", "image_size": "1K" }, ) print(interaction.output_text) with open("butterfly.png", "wb") as f: f.write(base64.b64decode(interaction.output_image.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: "Da Vinci style anatomical sketch of a dissected Monarch butterfly. Detailed drawings of the head, wings, and legs on textured parchment with notes in English.", response_format: { type: "image", mime_type: "image/png", aspect_ratio: "1:1", image_size: "1K", }, }); console.log(interaction.output_text); if (interaction.output_image && interaction.output_image.data) { const buffer = Buffer.from(interaction.output_image.data, 'base64'); fs.writeFileSync('butterfly.png', buffer); } } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.CreateModelInteractionResponseFormat; import com.google.genai.gaos.models.interactions.ImageResponseFormat; import com.google.genai.gaos.models.interactions.ImageResponseFormatAspectRatio; import com.google.genai.gaos.models.interactions.ImageResponseFormatImageSize; import com.google.genai.gaos.models.interactions.ImageResponseFormatMimeType; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ResponseFormat; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Base64; String prompt = "Da Vinci style anatomical sketch of a dissected Monarch butterfly. Detailed drawings of the head, wings, and legs on textured parchment with notes in English."; Client client = new Client(); CreateModelInteractionResponseFormat format = CreateModelInteractionResponseFormat.of( ResponseFormat.of( ImageResponseFormat.builder() .mimeType(ImageResponseFormatMimeType.IMAGE_JPEG) .aspectRatio(ImageResponseFormatAspectRatio.of("1:1")) .imageSize(ImageResponseFormatImageSize.ONE_K) .build())); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input(InteractionsInput.of(prompt)) .responseFormat(format) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); System.out.println(interaction.outputText().orElse("")); if (interaction.outputImage().isPresent() && interaction.outputImage().get().data().isPresent()) { byte[] imageBytes = Base64.getDecoder().decode(interaction.outputImage().get().data().get()); Files.write(Paths.get("butterfly.png"), imageBytes); } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "fmt" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } prompt := "Da Vinci style anatomical sketch of a dissected Monarch butterfly. Detailed drawings of the head, wings, and legs on textured parchment with notes in English." format := interactions.NewCreateModelInteractionResponseFormat( interactions.NewResponseFormat(interactions.ImageResponseFormat{ MimeType: interactions.ImageResponseFormatMimeTypeImageJpeg.ToPointer(), AspectRatio: interactions.ImageResponseFormatAspectRatio("1:1").ToPointer(), ImageSize: interactions.ImageResponseFormatImageSizeOneK.ToPointer(), }), ) res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput(prompt), ResponseFormat: genai.Ptr(format), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputText != nil { fmt.Println(*res.Interaction.OutputText) } if res.Interaction.OutputImage != nil && res.Interaction.OutputImage.Data != nil { imageBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputImage.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("butterfly.png", imageBytes, 0644); err != nil { log.Fatal(err) } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-nano-banana-2.1", "input": "Da Vinci style anatomical sketch of a dissected Monarch butterfly. Detailed drawings of the head, wings, and legs on textured parchment with notes in English.", "response_format": { "type": "image", "mime_type": "image/jpeg", "aspect_ratio": "1:1", "image_size": "1K" } }' ``` {% /tab %} {% /tabs %} The following is an example image generated from this prompt: {% image src="/googledevai/static/gemini-api/docs/images/gemini3-4k-image.png" alt="AI-generated Da Vinci style anatomical sketch of a dissected Monarch butterfly." caption="AI-generated Da Vinci style anatomical sketch of a dissected Monarch butterfly." variant="screenshot" /%} ### Thinking Process {% id="thinking-process" %} Gemini 3 image models are thinking models that use a reasoning process ("Thinking") for complex prompts. This feature is enabled by default and cannot be disabled in the API. To learn more about the thinking process, see the [Gemini Thinking](/docs/thinking) guide. The model generates up to two interim images to test composition and logic. The last image within Thinking is also the final rendered image. You can check the thoughts that lead to the final image being produced. {% tabs %} {% tab label="Python" %} ```python for step in interaction.steps: if step.type == "thought": for content_block in step.summary: if content_block.type == "text": print(content_block.text) elif content_block.type == "image": image = Image.open(io.BytesIO(base64.b64decode(content_block.data))) image.show() ``` {% /tab %} {% tab label="JavaScript" %} ```javascript for (const step of interaction.steps) { if (step.type === "thought") { for (const contentBlock of step.summary) { if (contentBlock.type === "text") { console.log(contentBlock.text); } else if (contentBlock.type === "image") { if (contentBlock.data) { const buffer = Buffer.from(contentBlock.data, "base64"); fs.writeFileSync("thought_image.png", buffer); } } } } } ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.Step; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.interactions.ThoughtStep; import com.google.genai.gaos.models.interactions.ThoughtSummaryContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Base64; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input( InteractionsInput.of( "A futuristic city built inside a giant glass bottle floating in space")) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.steps().isPresent()) { for (Step step : interaction.steps().get()) { if (step instanceof ThoughtStep) { ThoughtStep thoughtStep = (ThoughtStep) step; if (thoughtStep.summary().isPresent()) { for (ThoughtSummaryContent contentBlock : thoughtStep.summary().get()) { if (contentBlock instanceof TextContent) { System.out.println(((TextContent) contentBlock).text().orElse("")); } else if (contentBlock instanceof ImageContent) { ImageContent img = (ImageContent) contentBlock; if (img.data().isPresent()) { byte[] imgBytes = Base64.getDecoder().decode(img.data().get()); Files.write(Paths.get("thought_image.png"), imgBytes); } } } } } } } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "fmt" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput("A futuristic city built inside a giant glass bottle floating in space"), }), }) if err != nil { log.Fatal(err) } for _, step := range res.Interaction.Steps { if step.ThoughtStep != nil { for _, contentBlock := range step.ThoughtStep.Summary { if contentBlock.TextContent != nil { fmt.Println(contentBlock.TextContent.Text) } else if contentBlock.ImageContent != nil && contentBlock.ImageContent.Data != nil { imgBytes, err := base64.StdEncoding.DecodeString(*contentBlock.ImageContent.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("thought_image.png", imgBytes, 0644); err != nil { log.Fatal(err) } } } } } } ``` {% /tab %} {% /tabs %} #### Interleaved text and images {% id="interleaved-output" %} While standard image generation models only output images, some advanced Gemini 3 models (such as `gemini-3-pro-image`) can generate interleaved content-like stories or instructional guides containing both text blocks and illustrations inside the same response. Because the output is complex and interleaved, convenience properties like `.output_image` or `.output_text` will not capture the full sequence. To access and save interleaved content, you must manually iterate over `steps`: {% tabs %} {% tab label="Python" %} ```python interaction = client.interactions.create( model="gemini-3-pro-image", input="Write the story of the lifecycle of a monarch butterfly, interleave illustrations", ) image_counter = 1 for step in interaction.steps: if step.type == "model_output": for content_block in step.content: if content_block.type == "text": print(content_block.text) elif content_block.type == "image": filename = f"butterfly_lifecycle_{image_counter}.png" with open(filename, "wb") as f: f.write(base64.b64decode(content_block.data)) print(f"\n[Saved illustration: {filename}]\n") image_counter += 1 ``` {% /tab %} {% tab label="JavaScript" %} ```javascript const interaction = await ai.interactions.create({ model: "gemini-3-pro-image", input: "Write the story of the lifecycle of a monarch butterfly, interleave illustrations", }); let imageCounter = 1; for (const step of interaction.steps) { if (step.type === "model_output") { for (const contentBlock of step.content || []) { if (contentBlock.type === "text") { console.log(contentBlock.text); } else if (contentBlock.type === "image") { const buffer = Buffer.from(contentBlock.data, "base64"); const filename = `butterfly_lifecycle_${imageCounter}.png`; fs.writeFileSync(filename, buffer); console.log(`\n[Saved illustration: ${filename}]\n`); imageCounter++; } } } } ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ModelOutputStep; import com.google.genai.gaos.models.interactions.Step; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Base64; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-3-pro-image")) .input( InteractionsInput.of( "Write the story of the lifecycle of a monarch butterfly, interleave illustrations")) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); int imageCounter = 1; if (interaction.steps().isPresent()) { for (Step step : interaction.steps().get()) { if (step instanceof ModelOutputStep) { ModelOutputStep outputStep = (ModelOutputStep) step; if (outputStep.content().isPresent()) { for (Content contentBlock : outputStep.content().get()) { if (contentBlock instanceof TextContent) { System.out.println(((TextContent) contentBlock).text().orElse("")); } else if (contentBlock instanceof ImageContent) { ImageContent img = (ImageContent) contentBlock; if (img.data().isPresent()) { String filename = String.format("butterfly_lifecycle_%d.png", imageCounter); byte[] imgBytes = Base64.getDecoder().decode(img.data().get()); Files.write(Paths.get(filename), imgBytes); System.out.printf("%n[Saved illustration: %s]%n", filename); imageCounter++; } } } } } } } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "fmt" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3-pro-image"), Input: interactions.NewInteractionsInput("Write the story of the lifecycle of a monarch butterfly, interleave illustrations"), }), }) if err != nil { log.Fatal(err) } imageCounter := 1 for _, step := range res.Interaction.Steps { if step.ModelOutputStep != nil { for _, contentBlock := range step.ModelOutputStep.Content { if contentBlock.TextContent != nil { fmt.Println(contentBlock.TextContent.Text) } else if contentBlock.ImageContent != nil && contentBlock.ImageContent.Data != nil { filename := fmt.Sprintf("butterfly_lifecycle_%d.png", imageCounter) imgBytes, err := base64.StdEncoding.DecodeString(*contentBlock.ImageContent.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile(filename, imgBytes, 0644); err != nil { log.Fatal(err) } fmt.Printf("\n[Saved illustration: %s]\n", filename) imageCounter++ } } } } } ``` {% /tab %} {% /tabs %} #### Controlling thinking levels {% id="thinking-levels" %} With Gemini Nano Banana 2.1, Gemini 3.1 Flash Image, and Gemini 3.1 Flash Lite Image, you can control the amount of thinking the model uses to balance quality and latency: | Model | Supported thinking levels | Default | | :---- | :---- | :---- | | **Gemini Nano Banana 2.1** | `minimal`, `medium`, `high` | `medium` | | **Gemini 3.1 Flash Image** | `minimal`, `high` | `minimal` | | **Gemini 3.1 Flash Lite Image** | `minimal`, `high` | `minimal` | {% tabs %} {% tab label="Python" %} ```python from google import genai from PIL import Image import base64 import io client = genai.Client() interaction = client.interactions.create( model="gemini-nano-banana-2.1", input="A futuristic city built inside a giant glass bottle floating in space", generation_config={"thinking_level": "high"}, ) print(interaction.output_text) image = Image.open(io.BytesIO(base64.b64decode(interaction.output_image.data))) image.show() ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: "A futuristic city built inside a giant glass bottle floating in space", generation_config: { thinking_level: "high" }, }); console.log(interaction.output_text); if (interaction.output_image && interaction.output_image.data) { const buffer = Buffer.from(interaction.output_image.data, 'base64'); fs.writeFileSync('image.png', buffer); } } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.GenerationConfig; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ThinkingLevel; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Base64; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input( InteractionsInput.of( "A futuristic city built inside a giant glass bottle floating in space")) .generationConfig(GenerationConfig.builder().thinkingLevel(ThinkingLevel.HIGH).build()) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); System.out.println(interaction.outputText().orElse("")); if (interaction.outputImage().isPresent() && interaction.outputImage().get().data().isPresent()) { byte[] imageBytes = Base64.getDecoder().decode(interaction.outputImage().get().data().get()); Files.write(Paths.get("futuristic_city.png"), imageBytes); } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "fmt" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput("A futuristic city built inside a giant glass bottle floating in space"), GenerationConfig: &interactions.GenerationConfig{ ThinkingLevel: interactions.ThinkingLevelHigh.ToPointer(), }, }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputText != nil { fmt.Println(*res.Interaction.OutputText) } if res.Interaction.OutputImage != nil && res.Interaction.OutputImage.Data != nil { imageBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputImage.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("futuristic_city.png", imageBytes, 0644); err != nil { log.Fatal(err) } } } ``` {% /tab %} {% tab label="REST" %} ```shell curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-nano-banana-2.1", "input": "A futuristic city built inside a giant glass bottle floating in space", "generation_config": { "thinking_level": "high" } }' ``` {% /tab %} {% /tabs %} Note that thinking tokens are billed by default for thinking models, as the [thinking process](/docs/image-generation#thinking-process) always happens by default whether you view the process or not. ## Other image generation modes {% id="other-modes" %} Although Nano Banana image generation models are recommended for most use cases, you can also explore dedicated image generation models: * **Imagen**: Google's legacy text-to-image models (shut down). * **[Veo](/docs/video)**: Google's video generation model. ## Generate images in batch {% id="batch-api" %} All of the image generation capabilities described on this page can also be run as batch jobs using the [Batch API](/docs/batch-api). ## Prompting guide and strategies {% id="prompt-guide" %} This section provides prompt examples and templates for common image generation and editing workflows. Each example includes a re-usable template and a sample prompt for the Interactions API. ### Prompts for generating images {% id="image-generation-prompts" %} The following examples show how to use text prompts to generate various types of images. #### 1. Photorealistic scenes {% id="1-photorealistic-scenes" %} Describe a scene in rich detail. The more specific you are, the more control you have over the results. {% tabs %} {% tab label="Template" %} ```none A photorealistic [type of shot] of a [subject description] in a [setting description]. [Description of the light]. Shot from a [camera angle] with a [lens type]. ``` {% /tab %} {% tab label="Prompt" %} ```none A photorealistic wide-angle shot of a vibrant coral reef teeming with tropical fish. Crystal-clear turquoise water with sunbeams filtering down from the surface, illuminating a sea turtle gliding gracefully over the coral. Shot from a low perspective with a wide-angle lens. Aspect ratio 16:9. ``` {% /tab %} {% tab label="Python" %} ```python from google import genai from google.genai import types import base64 client = genai.Client() interaction = client.interactions.create( model="gemini-nano-banana-2.1", input="A photorealistic wide-angle shot of a vibrant coral reef teeming with tropical fish. Crystal-clear turquoise water with sunbeams filtering down from the surface, illuminating a sea turtle gliding gracefully over the coral. Shot from a low perspective with a wide-angle lens. Aspect ratio 16:9.", response_format=[ { "type": "image", "mime_type": "image/jpeg", "aspect_ratio": "16:9", } ], ) print(interaction.output_text) with open("coral_reef.png", "wb") as f: f.write(base64.b64decode(interaction.output_image.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: "A photorealistic wide-angle shot of a vibrant coral reef teeming with tropical fish. Crystal-clear turquoise water with sunbeams filtering down from the surface, illuminating a sea turtle gliding gracefully over the coral. Shot from a low perspective with a wide-angle lens. Aspect ratio 16:9.", response_format: [ { type: "image", mime_type: "image/jpeg", aspect_ratio: "16:9", } ], }); console.log(interaction.output_text); if (interaction.output_image && interaction.output_image.data) { const buffer = Buffer.from(interaction.output_image.data, 'base64'); fs.writeFileSync('coral_reef.png', buffer); } } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.CreateModelInteractionResponseFormat; import com.google.genai.gaos.models.interactions.ImageResponseFormat; import com.google.genai.gaos.models.interactions.ImageResponseFormatAspectRatio; import com.google.genai.gaos.models.interactions.ImageResponseFormatMimeType; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ResponseFormat; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; Client client = new Client(); CreateModelInteractionResponseFormat format = CreateModelInteractionResponseFormat.of( Arrays.asList( ResponseFormat.of( ImageResponseFormat.builder() .mimeType(ImageResponseFormatMimeType.IMAGE_JPEG) .aspectRatio(ImageResponseFormatAspectRatio.of("16:9")) .build()))); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input( InteractionsInput.of( "A photorealistic wide-angle shot of a vibrant coral reef teeming with tropical fish. Crystal-clear turquoise water with sunbeams filtering down from the surface, illuminating a sea turtle gliding gracefully over the coral. Shot from a low perspective with a wide-angle lens. Aspect ratio 16:9.")) .responseFormat(format) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); System.out.println(interaction.outputText().orElse("")); if (interaction.outputImage().isPresent() && interaction.outputImage().get().data().isPresent()) { byte[] imageBytes = Base64.getDecoder().decode(interaction.outputImage().get().data().get()); Files.write(Paths.get("coral_reef.png"), imageBytes); } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "fmt" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } format := interactions.NewCreateModelInteractionResponseFormat([]interactions.ResponseFormat{ interactions.NewResponseFormat(interactions.ImageResponseFormat{ MimeType: interactions.ImageResponseFormatMimeTypeImageJpeg.ToPointer(), AspectRatio: interactions.ImageResponseFormatAspectRatio("16:9").ToPointer(), }), }) res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput("A photorealistic wide-angle shot of a vibrant coral reef teeming with tropical fish. Crystal-clear turquoise water with sunbeams filtering down from the surface, illuminating a sea turtle gliding gracefully over the coral. Shot from a low perspective with a wide-angle lens. Aspect ratio 16:9."), ResponseFormat: genai.Ptr(format), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputText != nil { fmt.Println(*res.Interaction.OutputText) } if res.Interaction.OutputImage != nil && res.Interaction.OutputImage.Data != nil { imageBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputImage.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("coral_reef.png", imageBytes, 0644); err != nil { log.Fatal(err) } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-nano-banana-2.1", "input": "A photorealistic wide-angle shot of a vibrant coral reef teeming with tropical fish. Crystal-clear turquoise water with sunbeams filtering down from the surface, illuminating a sea turtle gliding gracefully over the coral. Shot from a low perspective with a wide-angle lens. Aspect ratio 16:9.", "response_format": { "type": "image", "mime_type": "image/png", "aspect_ratio": "16:9" } }' ``` {% /tab %} {% /tabs %} #### 2. Stylized illustrations & stickers {% id="2-stylized-illustrations-stickers" %} Describe the artistic style, subject, and medium. Be specific about the visual detail (bold lines, colors, etc.) for consistent results. {% tabs %} {% tab label="Template" %} ```none A [style] of a [subject, with details about accessories or actions] doing [activity]. The design features [visual qualities, e.g., bold outlines, cel-shading, etc.] and [color/background preference]. ``` {% /tab %} {% tab label="Prompt" %} ```none A kawaii-style sticker of a happy red panda wearing a tiny bamboo hat. It's munching on a green bamboo leaf. The design features bold, clean outlines, simple cel-shading, and a vibrant color palette. The background must be white. ``` {% /tab %} {% tab label="Python" %} ```python from google import genai import base64 client = genai.Client() interaction = client.interactions.create( model="gemini-nano-banana-2.1", input="A kawaii-style sticker of a happy red panda wearing a tiny bamboo hat. It's munching on a green bamboo leaf. The design features bold, clean outlines, simple cel-shading, and a vibrant color palette. The background must be white.", ) for step in interaction.steps: if step.type == "model_output": for content_block in step.content: if content_block.type == "text": print(content_block.text) elif content_block.type == "image": with open("red_panda_sticker.png", "wb") as f: f.write(base64.b64decode(content_block.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: "A kawaii-style sticker of a happy red panda wearing a tiny bamboo hat. It's munching on a green bamboo leaf. The design features bold, clean outlines, simple cel-shading, and a vibrant color palette. The background must be white.", }); for (const step of interaction.steps) { if (step.type === "model_output") { for (const contentBlock of step.content || []) { if (contentBlock.type === "text") { console.log(contentBlock.text); } else if (contentBlock.type === "image") { if (contentBlock.data) { const buffer = Buffer.from(contentBlock.data, "base64"); fs.writeFileSync("red_panda_sticker.png", buffer); } } } } } } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ModelOutputStep; import com.google.genai.gaos.models.interactions.Step; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Base64; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input( InteractionsInput.of( "A kawaii-style sticker of a happy red panda wearing a tiny bamboo hat. It's munching on a green bamboo leaf. The design features bold, clean outlines, simple cel-shading, and a vibrant color palette. The background must be white.")) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.steps().isPresent()) { for (Step step : interaction.steps().get()) { if (step instanceof ModelOutputStep) { ModelOutputStep outputStep = (ModelOutputStep) step; if (outputStep.content().isPresent()) { for (Content contentBlock : outputStep.content().get()) { if (contentBlock instanceof TextContent) { System.out.println(((TextContent) contentBlock).text().orElse("")); } else if (contentBlock instanceof ImageContent) { ImageContent img = (ImageContent) contentBlock; if (img.data().isPresent()) { byte[] imgBytes = Base64.getDecoder().decode(img.data().get()); Files.write(Paths.get("red_panda_sticker.png"), imgBytes); } } } } } } } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "fmt" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput("A kawaii-style sticker of a happy red panda wearing a tiny bamboo hat. It's munching on a green bamboo leaf. The design features bold, clean outlines, simple cel-shading, and a vibrant color palette. The background must be white."), }), }) if err != nil { log.Fatal(err) } for _, step := range res.Interaction.Steps { if step.ModelOutputStep != nil { for _, contentBlock := range step.ModelOutputStep.Content { if contentBlock.TextContent != nil { fmt.Println(contentBlock.TextContent.Text) } else if contentBlock.ImageContent != nil && contentBlock.ImageContent.Data != nil { imgBytes, err := base64.StdEncoding.DecodeString(*contentBlock.ImageContent.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("red_panda_sticker.png", imgBytes, 0644); err != nil { log.Fatal(err) } } } } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gemini-nano-banana-2.1", "input": "A kawaii-style sticker of a happy red panda wearing a tiny bamboo hat. It is munching on a green bamboo leaf. The design features bold, clean outlines, simple cel-shading, and a vibrant color palette. The background must be white." }' ``` {% /tab %} {% /tabs %} {% image src="/googledevai/static/gemini-api/docs/images/red_panda_sticker.png" alt="A kawaii-style sticker of a happy red..." caption="A kawaii-style sticker of a happy red panda..." variant="screenshot" /%} #### 3. Accurate text in images {% id="3-accurate-text-in-images" %} Gemini excels at rendering text. Be clear about the text, the font style (descriptively), and the overall design. Use Gemini 3 Pro Image for professional asset production. {% tabs %} {% tab label="Template" %} ```none Create a [image type] for [brand/concept] with the text "[text to render]" in a [font style]. The design should be [style description], with a [color scheme]. ``` {% /tab %} {% tab label="Prompt" %} ```none Create a modern, minimalist logo for a coffee shop called 'The Daily Grind'. The text should be in a clean, bold, sans-serif font. The color scheme is black and white. Put the logo in a circle. Use a coffee bean in a clever way. ``` {% /tab %} {% tab label="Python" %} ```python from google import genai import base64 client = genai.Client() interaction = client.interactions.create( model="gemini-nano-banana-2.1", input="Create a modern, minimalist logo for a coffee shop called 'The Daily Grind'. The text should be in a clean, bold, sans-serif font. The color scheme is black and white. Put the logo in a circle. Use a coffee bean in a clever way.", response_format={"type": "image", "aspect_ratio": "1:1"}, ) for step in interaction.steps: if step.type == "model_output": for content_block in step.content: if content_block.type == "text": print(content_block.text) elif content_block.type == "image": with open("logo_example.jpg", "wb") as f: f.write(base64.b64decode(content_block.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: "Create a modern, minimalist logo for a coffee shop called 'The Daily Grind'. The text should be in a clean, bold, sans-serif font. The color scheme is black and white. Put the logo in a circle. Use a coffee bean in a clever way.", response_format: { type: "image", aspect_ratio: "1:1" }, }); for (const step of interaction.steps) { if (step.type === "model_output") { for (const contentBlock of step.content || []) { if (contentBlock.type === "text") { console.log(contentBlock.text); } else if (contentBlock.type === "image") { if (contentBlock.data) { const buffer = Buffer.from(contentBlock.data, "base64"); fs.writeFileSync("logo_example.jpg", buffer); } } } } } } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.CreateModelInteractionResponseFormat; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.ImageResponseFormat; import com.google.genai.gaos.models.interactions.ImageResponseFormatAspectRatio; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ModelOutputStep; import com.google.genai.gaos.models.interactions.ResponseFormat; import com.google.genai.gaos.models.interactions.Step; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Base64; Client client = new Client(); CreateModelInteractionResponseFormat format = CreateModelInteractionResponseFormat.of( ResponseFormat.of( ImageResponseFormat.builder() .aspectRatio(ImageResponseFormatAspectRatio.of("1:1")) .build())); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input( InteractionsInput.of( "Create a modern, minimalist logo for a coffee shop called 'The Daily Grind'. The text should be in a clean, bold, sans-serif font. The color scheme is black and white. Put the logo in a circle. Use a coffee bean in a clever way.")) .responseFormat(format) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.steps().isPresent()) { for (Step step : interaction.steps().get()) { if (step instanceof ModelOutputStep) { ModelOutputStep outputStep = (ModelOutputStep) step; if (outputStep.content().isPresent()) { for (Content contentBlock : outputStep.content().get()) { if (contentBlock instanceof TextContent) { System.out.println(((TextContent) contentBlock).text().orElse("")); } else if (contentBlock instanceof ImageContent) { ImageContent img = (ImageContent) contentBlock; if (img.data().isPresent()) { byte[] imgBytes = Base64.getDecoder().decode(img.data().get()); Files.write(Paths.get("logo_example.jpg"), imgBytes); } } } } } } } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "fmt" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } format := interactions.NewCreateModelInteractionResponseFormat( interactions.NewResponseFormat(interactions.ImageResponseFormat{ AspectRatio: interactions.ImageResponseFormatAspectRatio("1:1").ToPointer(), }), ) res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput("Create a modern, minimalist logo for a coffee shop called 'The Daily Grind'. The text should be in a clean, bold, sans-serif font. The color scheme is black and white. Put the logo in a circle. Use a coffee bean in a clever way."), ResponseFormat: genai.Ptr(format), }), }) if err != nil { log.Fatal(err) } for _, step := range res.Interaction.Steps { if step.ModelOutputStep != nil { for _, contentBlock := range step.ModelOutputStep.Content { if contentBlock.TextContent != nil { fmt.Println(contentBlock.TextContent.Text) } else if contentBlock.ImageContent != nil && contentBlock.ImageContent.Data != nil { imgBytes, err := base64.StdEncoding.DecodeString(*contentBlock.ImageContent.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("logo_example.jpg", imgBytes, 0644); err != nil { log.Fatal(err) } } } } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gemini-nano-banana-2.1", "input": "Create a modern, minimalist logo for a coffee shop called The Daily Grind. The text should be in a clean, bold, sans-serif font. The color scheme is black and white. Put the logo in a circle. Use a coffee bean in a clever way.", "response_format": { "type": "image", "aspect_ratio": "1:1" } }' ``` {% /tab %} {% /tabs %} {% image src="/googledevai/static/gemini-api/docs/images/logo_example.jpg" alt="Create a modern, minimalist logo for a coffee shop called 'The Daily Grind'..." caption="Create a modern, minimalist logo for a coffee shop called 'The Daily Grind'..." variant="screenshot" /%} #### 4. Product mockups & commercial photography {% id="4-product-mockups-commercial-photography" %} Perfect for creating clean, professional product shots for ecommerce, advertising, or branding. {% tabs %} {% tab label="Template" %} ```none A high-resolution, studio-lit product photograph of a [product description] on a [background surface/description]. The lighting is a [lighting setup, e.g., three-point softbox setup] to [lighting purpose]. The camera angle is a [angle type] to showcase [specific feature]. Ultra-realistic, with sharp focus on [key detail]. [Aspect ratio]. ``` {% /tab %} {% tab label="Prompt" %} ```none A high-resolution, studio-lit product photograph of a minimalist ceramic coffee mug in matte black, presented on a polished concrete surface. The lighting is a three-point softbox setup designed to create soft, diffused highlights and eliminate harsh shadows. The camera angle is a slightly elevated 45-degree shot to showcase its clean lines. Ultra-realistic, with sharp focus on the steam rising from the coffee. Square image. ``` {% /tab %} {% tab label="Python" %} ```python from google import genai import base64 client = genai.Client() interaction = client.interactions.create( model="gemini-nano-banana-2.1", input="A high-resolution, studio-lit product photograph of a minimalist ceramic coffee mug in matte black, presented on a polished concrete surface. The lighting is a three-point softbox setup designed to create soft, diffused highlights and eliminate harsh shadows. The camera angle is a slightly elevated 45-degree shot to showcase its clean lines. Ultra-realistic, with sharp focus on the steam rising from the coffee. Square image.", ) for step in interaction.steps: if step.type == "model_output": for content_block in step.content: if content_block.type == "text": print(content_block.text) elif content_block.type == "image": with open("product_mockup.png", "wb") as f: f.write(base64.b64decode(content_block.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: "A high-resolution, studio-lit product photograph of a minimalist ceramic coffee mug in matte black, presented on a polished concrete surface. The lighting is a three-point softbox setup designed to create soft, diffused highlights and eliminate harsh shadows. The camera angle is a slightly elevated 45-degree shot to showcase its clean lines. Ultra-realistic, with sharp focus on the steam rising from the coffee. Square image.", }); for (const step of interaction.steps) { if (step.type === "model_output") { for (const contentBlock of step.content || []) { if (contentBlock.type === "text") { console.log(contentBlock.text); } else if (contentBlock.type === "image") { if (contentBlock.data) { const buffer = Buffer.from(contentBlock.data, "base64"); fs.writeFileSync("product_mockup.png", buffer); } } } } } } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ModelOutputStep; import com.google.genai.gaos.models.interactions.Step; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Base64; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input( InteractionsInput.of( "A high-resolution, studio-lit product photograph of a minimalist ceramic coffee mug in matte black, presented on a polished concrete surface. The lighting is a three-point softbox setup designed to create soft, diffused highlights and eliminate harsh shadows. The camera angle is a slightly elevated 45-degree shot to showcase its clean lines. Ultra-realistic, with sharp focus on the steam rising from the coffee. Square image.")) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.steps().isPresent()) { for (Step step : interaction.steps().get()) { if (step instanceof ModelOutputStep) { ModelOutputStep outputStep = (ModelOutputStep) step; if (outputStep.content().isPresent()) { for (Content contentBlock : outputStep.content().get()) { if (contentBlock instanceof TextContent) { System.out.println(((TextContent) contentBlock).text().orElse("")); } else if (contentBlock instanceof ImageContent) { ImageContent img = (ImageContent) contentBlock; if (img.data().isPresent()) { byte[] imgBytes = Base64.getDecoder().decode(img.data().get()); Files.write(Paths.get("product_mockup.png"), imgBytes); } } } } } } } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "fmt" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput("A high-resolution, studio-lit product photograph of a minimalist ceramic coffee mug in matte black, presented on a polished concrete surface. The lighting is a three-point softbox setup designed to create soft, diffused highlights and eliminate harsh shadows. The camera angle is a slightly elevated 45-degree shot to showcase its clean lines. Ultra-realistic, with sharp focus on the steam rising from the coffee. Square image."), }), }) if err != nil { log.Fatal(err) } for _, step := range res.Interaction.Steps { if step.ModelOutputStep != nil { for _, contentBlock := range step.ModelOutputStep.Content { if contentBlock.TextContent != nil { fmt.Println(contentBlock.TextContent.Text) } else if contentBlock.ImageContent != nil && contentBlock.ImageContent.Data != nil { imgBytes, err := base64.StdEncoding.DecodeString(*contentBlock.ImageContent.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("product_mockup.png", imgBytes, 0644); err != nil { log.Fatal(err) } } } } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gemini-nano-banana-2.1", "input": "A high-resolution, studio-lit product photograph of a minimalist ceramic coffee mug in matte black, presented on a polished concrete surface. The lighting is a three-point softbox setup designed to create soft, diffused highlights and eliminate harsh shadows. The camera angle is a slightly elevated 45-degree shot to showcase its clean lines. Ultra-realistic, with sharp focus on the steam rising from the coffee. Square image." }' ``` {% /tab %} {% /tabs %} {% image src="/googledevai/static/gemini-api/docs/images/product_mockup.png" alt="A high-resolution, studio-lit product photograph of a minimalist ceramic coffee mug..." caption="A high-resolution, studio-lit product photograph of a minimalist ceramic coffee mug..." variant="screenshot" /%} #### 5. Minimalist & negative space design {% id="5-minimalist-negative-space-design" %} Excellent for creating backgrounds for websites, presentations, or marketing materials where text will be overlaid. {% tabs %} {% tab label="Template" %} ```none A minimalist composition featuring a single [subject] positioned in the [bottom-right/top-left/etc.] of the frame. The background is a vast, empty [color] canvas, creating significant negative space. Soft, subtle lighting. [Aspect ratio]. ``` {% /tab %} {% tab label="Prompt" %} ```none A minimalist composition featuring a single, delicate red maple leaf positioned in the bottom-right of the frame. The background is a vast, empty off-white canvas, creating significant negative space for text. Soft, diffused lighting from the top left. Square image. ``` {% /tab %} {% tab label="Python" %} ```python from google import genai import base64 client = genai.Client() interaction = client.interactions.create( model="gemini-nano-banana-2.1", input="A minimalist composition featuring a single, delicate red maple leaf positioned in the bottom-right of the frame. The background is a vast, empty off-white canvas, creating significant negative space for text. Soft, diffused lighting from the top left. Square image.", ) for step in interaction.steps: if step.type == "model_output": for content_block in step.content: if content_block.type == "text": print(content_block.text) elif content_block.type == "image": with open("minimalist_design.png", "wb") as f: f.write(base64.b64decode(content_block.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: "A minimalist composition featuring a single, delicate red maple leaf positioned in the bottom-right of the frame. The background is a vast, empty off-white canvas, creating significant negative space for text. Soft, diffused lighting from the top left. Square image.", }); for (const step of interaction.steps) { if (step.type === "model_output") { for (const contentBlock of step.content || []) { if (contentBlock.type === "text") { console.log(contentBlock.text); } else if (contentBlock.type === "image") { if (contentBlock.data) { const buffer = Buffer.from(contentBlock.data, "base64"); fs.writeFileSync("minimalist_design.png", buffer); } } } } } } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ModelOutputStep; import com.google.genai.gaos.models.interactions.Step; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Base64; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input( InteractionsInput.of( "A minimalist composition featuring a single, delicate red maple leaf positioned in the bottom-right of the frame. The background is a vast, empty off-white canvas, creating significant negative space for text. Soft, diffused lighting from the top left. Square image.")) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.steps().isPresent()) { for (Step step : interaction.steps().get()) { if (step instanceof ModelOutputStep) { ModelOutputStep outputStep = (ModelOutputStep) step; if (outputStep.content().isPresent()) { for (Content contentBlock : outputStep.content().get()) { if (contentBlock instanceof TextContent) { System.out.println(((TextContent) contentBlock).text().orElse("")); } else if (contentBlock instanceof ImageContent) { ImageContent img = (ImageContent) contentBlock; if (img.data().isPresent()) { byte[] imgBytes = Base64.getDecoder().decode(img.data().get()); Files.write(Paths.get("minimalist_design.png"), imgBytes); } } } } } } } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "fmt" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput("A minimalist composition featuring a single, delicate red maple leaf positioned in the bottom-right of the frame. The background is a vast, empty off-white canvas, creating significant negative space for text. Soft, diffused lighting from the top left. Square image."), }), }) if err != nil { log.Fatal(err) } for _, step := range res.Interaction.Steps { if step.ModelOutputStep != nil { for _, contentBlock := range step.ModelOutputStep.Content { if contentBlock.TextContent != nil { fmt.Println(contentBlock.TextContent.Text) } else if contentBlock.ImageContent != nil && contentBlock.ImageContent.Data != nil { imgBytes, err := base64.StdEncoding.DecodeString(*contentBlock.ImageContent.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("minimalist_design.png", imgBytes, 0644); err != nil { log.Fatal(err) } } } } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gemini-nano-banana-2.1", "input": "A minimalist composition featuring a single, delicate red maple leaf positioned in the bottom-right of the frame. The background is a vast, empty off-white canvas, creating significant negative space for text. Soft, diffused lighting from the top left. Square image." }' ``` {% /tab %} {% /tabs %} {% image src="/googledevai/static/gemini-api/docs/images/minimalist_design.png" alt="A minimalist composition featuring a single, delicate red maple leaf..." caption="A minimalist composition featuring a single, delicate red maple leaf..." variant="screenshot" /%} #### 6. Sequential art (Comic panel / Storyboard) {% id="6-sequential-art-comic-panel-storyboard" %} Builds on character consistency and scene description to create panels for visual storytelling. For accuracy with text and storytelling ability, these prompts work best with Gemini 3 Pro and Gemini 3.1 Flash Image. {% tabs %} {% tab label="Template" %} ```none Make a 3 panel comic in a [style]. Put the character in a [type of scene]. ``` {% /tab %} {% tab label="Prompt" %} ```none Make a 3 panel comic in a gritty, noir art style with high-contrast black and white inks. Put the character in a humurous scene. ``` {% /tab %} {% tab label="Python" %} ```python from google import genai from PIL import Image import base64 client = genai.Client() with open('/path/to/your/man_in_white_glasses.jpg', 'rb') as f: image_bytes = f.read() text_input = "Make a 3 panel comic in a gritty, noir art style with high-contrast black and white inks. Put the character in a humurous scene." interaction = client.interactions.create( model="gemini-nano-banana-2.1", input=[ {"type": "text", "text": text_input}, { "type": "image", "data": base64.b64encode(image_bytes).decode('utf-8'), "mime_type": "image/jpeg" } ], ) for step in interaction.steps: if step.type == "model_output": for content_block in step.content: if content_block.type == "text": print(content_block.text) elif content_block.type == "image": with open("comic_panel.jpg", "wb") as f: f.write(base64.b64decode(content_block.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const imagePath = "/path/to/your/man_in_white_glasses.jpg"; const imageData = fs.readFileSync(imagePath); const base64Image = imageData.toString("base64"); const interaction = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: [ { type: "text", text: "Make a 3 panel comic in a gritty, noir art style with high-contrast black and white inks. Put the character in a humurous scene." }, { type: "image", mime_type: "image/jpeg", data: base64Image }, ], }); for (const step of interaction.steps) { if (step.type === "model_output") { for (const contentBlock of step.content || []) { if (contentBlock.type === "text") { console.log(contentBlock.text); } else if (contentBlock.type === "image") { if (contentBlock.data) { const buffer = Buffer.from(contentBlock.data, "base64"); fs.writeFileSync("comic_panel.jpg", buffer); } } } } } } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.ImageContentMimeType; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ModelOutputStep; import com.google.genai.gaos.models.interactions.Step; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; import java.util.List; Client client = new Client(); byte[] imageBytes = Files.readAllBytes(Paths.get("/path/to/your/man_in_white_glasses.jpg")); String base64Image = Base64.getEncoder().encodeToString(imageBytes); String textInput = "Make a 3 panel comic in a gritty, noir art style with high-contrast black and white inks. Put the character in a humurous scene."; Content textContent = TextContent.builder().text(textInput).build(); Content imageContent = ImageContent.builder() .data(base64Image) .mimeType(ImageContentMimeType.IMAGE_JPEG) .build(); List contents = Arrays.asList(textContent, imageContent); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input(InteractionsInput.ofContent(contents)) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.steps().isPresent()) { for (Step step : interaction.steps().get()) { if (step instanceof ModelOutputStep) { ModelOutputStep outputStep = (ModelOutputStep) step; if (outputStep.content().isPresent()) { for (Content contentBlock : outputStep.content().get()) { if (contentBlock instanceof TextContent) { System.out.println(((TextContent) contentBlock).text().orElse("")); } else if (contentBlock instanceof ImageContent) { ImageContent img = (ImageContent) contentBlock; if (img.data().isPresent()) { byte[] outBytes = Base64.getDecoder().decode(img.data().get()); Files.write(Paths.get("comic_panel.jpg"), outBytes); } } } } } } } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "fmt" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } imageBytes, err := os.ReadFile("/path/to/your/man_in_white_glasses.jpg") if err != nil { log.Fatal(err) } base64Image := base64.StdEncoding.EncodeToString(imageBytes) textInput := "Make a 3 panel comic in a gritty, noir art style with high-contrast black and white inks. Put the character in a humurous scene." contents := []interactions.Content{ interactions.NewContent(interactions.TextContent{ Text: textInput, }), interactions.NewContent(interactions.ImageContent{ Data: genai.Ptr(base64Image), MimeType: interactions.ImageContentMimeTypeImageJpeg.ToPointer(), }), } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput(contents), }), }) if err != nil { log.Fatal(err) } for _, step := range res.Interaction.Steps { if step.ModelOutputStep != nil { for _, contentBlock := range step.ModelOutputStep.Content { if contentBlock.TextContent != nil { fmt.Println(contentBlock.TextContent.Text) } else if contentBlock.ImageContent != nil && contentBlock.ImageContent.Data != nil { outBytes, err := base64.StdEncoding.DecodeString(*contentBlock.ImageContent.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("comic_panel.jpg", outBytes, 0644); err != nil { log.Fatal(err) } } } } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gemini-nano-banana-2.1", "input": [ {"type": "text", "text": "Make a 3 panel comic in a gritty, noir art style with high-contrast black and white inks. Put the character in a humurous scene."}, {"type": "image", "data": "[BASE64_IMAGE_DATA]", "mime_type": "image/jpeg"} ] }' ``` {% /tab %} {% /tabs %} {% table %} * Input * Output --- * ![Man in white glasses](/googledevai/static/gemini-api/docs/images/man_in_white_glasses.jpg){% class="screenshot" width="50%" %} Input image * ![Make a 3 panel comic in a gritty, noir art style...](/googledevai/static/gemini-api/docs/images/comic_panel.jpg){% class="screenshot" width="50%" %} Make a 3 panel comic in a gritty, noir art style... {% /table %} #### 7. Grounding with Google Search {% id="grounding-with-search" %} Use Google Search to generate images based on recent or real-time information. This is useful for news, weather, and other time-sensitive topics. {% tabs %} {% tab label="Prompt" %} ```none Make a simple but stylish graphic of last night's Arsenal game in the Champion's League ``` {% /tab %} {% tab label="Python" %} ```python from google import genai from google.genai import types import base64 client = genai.Client() interaction = client.interactions.create( model="gemini-nano-banana-2.1", input="Make a simple but stylish graphic of last night's Arsenal game in the Champion's League", tools=[{"type": "google_search"}], response_format={"type": "image", "aspect_ratio": "16:9"}, ) for step in interaction.steps: if step.type == "model_output": for content_block in step.content: if content_block.type == "text": print(content_block.text) elif content_block.type == "image": with open("football-score.jpg", "wb") as f: f.write(base64.b64decode(content_block.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: "Make a simple but stylish graphic of last night's Arsenal game in the Champion's League", tools: [{ type: "google_search" }], response_format: { type: "image", aspect_ratio: "16:9", image_size: "2K" }, }); for (const step of interaction.steps) { if (step.type === "model_output") { for (const contentBlock of step.content || []) { if (contentBlock.type === "text") { console.log(contentBlock.text); } else if (contentBlock.type === "image") { if (contentBlock.data) { const buffer = Buffer.from(contentBlock.data, "base64"); fs.writeFileSync("football-score.jpg", buffer); } } } } } } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.CreateModelInteractionResponseFormat; import com.google.genai.gaos.models.interactions.GoogleSearch; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.ImageResponseFormat; import com.google.genai.gaos.models.interactions.ImageResponseFormatAspectRatio; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ModelOutputStep; import com.google.genai.gaos.models.interactions.ResponseFormat; import com.google.genai.gaos.models.interactions.Step; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; Client client = new Client(); CreateModelInteractionResponseFormat format = CreateModelInteractionResponseFormat.of( ResponseFormat.of( ImageResponseFormat.builder() .aspectRatio(ImageResponseFormatAspectRatio.of("16:9")) .build())); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input( InteractionsInput.of( "Make a simple but stylish graphic of last night's Arsenal game in the Champion's League")) .tools(Arrays.asList(new GoogleSearch())) .responseFormat(format) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.steps().isPresent()) { for (Step step : interaction.steps().get()) { if (step instanceof ModelOutputStep) { ModelOutputStep outputStep = (ModelOutputStep) step; if (outputStep.content().isPresent()) { for (Content contentBlock : outputStep.content().get()) { if (contentBlock instanceof TextContent) { System.out.println(((TextContent) contentBlock).text().orElse("")); } else if (contentBlock instanceof ImageContent) { ImageContent img = (ImageContent) contentBlock; if (img.data().isPresent()) { byte[] imgBytes = Base64.getDecoder().decode(img.data().get()); Files.write(Paths.get("football-score.jpg"), imgBytes); } } } } } } } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "fmt" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } format := interactions.NewCreateModelInteractionResponseFormat( interactions.NewResponseFormat(interactions.ImageResponseFormat{ AspectRatio: interactions.ImageResponseFormatAspectRatio("16:9").ToPointer(), }), ) res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput("Make a simple but stylish graphic of last night's Arsenal game in the Champion's League"), Tools: []interactions.Tool{ interactions.NewTool(interactions.GoogleSearch{}), }, ResponseFormat: genai.Ptr(format), }), }) if err != nil { log.Fatal(err) } for _, step := range res.Interaction.Steps { if step.ModelOutputStep != nil { for _, contentBlock := range step.ModelOutputStep.Content { if contentBlock.TextContent != nil { fmt.Println(contentBlock.TextContent.Text) } else if contentBlock.ImageContent != nil && contentBlock.ImageContent.Data != nil { imgBytes, err := base64.StdEncoding.DecodeString(*contentBlock.ImageContent.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("football-score.jpg", imgBytes, 0644); err != nil { log.Fatal(err) } } } } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gemini-nano-banana-2.1", "input": "Make a simple but stylish graphic of last nights Arsenal game in the Champions League", "tools": [{"type": "google_search"}], "response_format": { "type": "image", "aspect_ratio": "16:9" } }' ``` {% /tab %} {% /tabs %} {% image src="/googledevai/static/gemini-api/docs/images/football-score.jpg" alt="AI-generated graphic of an Arsenal football score" caption="AI-generated graphic of an Arsenal football score" variant="screenshot" /%} ### Prompts for editing images {% id="image-editing-prompts" %} These examples show how to provide images alongside your text prompts for editing, composition, and style transfer. #### 1. Adding and removing elements {% id="1-adding-and-removing-elements" %} Provide an image and describe your change. The model will match the original image's style, lighting, and perspective. {% tabs %} {% tab label="Template" %} ```none Using the provided image of [subject], please [add/remove/modify] [element] to/from the scene. Ensure the change is [description of how the change should integrate]. ``` {% /tab %} {% tab label="Prompt" %} ```none "Using the provided image of my cat, please add a small, knitted wizard hat on its head. Make it look like it's sitting comfortably and matches the soft lighting of the photo." ``` {% /tab %} {% tab label="Python" %} ```python from google import genai from PIL import Image import base64 client = genai.Client() with open('/path/to/your/cat_photo.png', 'rb') as f: image_bytes = f.read() text_input = """Using the provided image of my cat, please add a small, knitted wizard hat on its head. Make it look like it's sitting comfortably and not falling off.""" interaction = client.interactions.create( model="gemini-nano-banana-2.1", input=[ {"type": "text", "text": text_input}, { "type": "image", "data": base64.b64encode(image_bytes).decode('utf-8'), "mime_type": "image/png" } ], ) for step in interaction.steps: if step.type == "model_output": for content_block in step.content: if content_block.type == "text": print(content_block.text) elif content_block.type == "image": with open("cat_with_hat.png", "wb") as f: f.write(base64.b64decode(content_block.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const imagePath = "/path/to/your/cat_photo.png"; const imageData = fs.readFileSync(imagePath); const base64Image = imageData.toString("base64"); const interaction = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: [ { type: "text", text: "Using the provided image of my cat, please add a small, knitted wizard hat on its head. Make it look like it's sitting comfortably and not falling off." }, { type: "image", mime_type: "image/png", data: base64Image }, ], }); for (const step of interaction.steps) { if (step.type === "model_output") { for (const contentBlock of step.content || []) { if (contentBlock.type === "text") { console.log(contentBlock.text); } else if (contentBlock.type === "image") { if (contentBlock.data) { const buffer = Buffer.from(contentBlock.data, "base64"); fs.writeFileSync("cat_with_hat.png", buffer); } } } } } } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.ImageContentMimeType; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ModelOutputStep; import com.google.genai.gaos.models.interactions.Step; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; import java.util.List; Client client = new Client(); byte[] imageBytes = Files.readAllBytes(Paths.get("/path/to/your/cat_photo.png")); String base64Image = Base64.getEncoder().encodeToString(imageBytes); String textInput = "Using the provided image of my cat, please add a small, knitted wizard hat on its head. Make it look like it's sitting comfortably and not falling off."; Content textContent = TextContent.builder().text(textInput).build(); Content imageContent = ImageContent.builder() .data(base64Image) .mimeType(ImageContentMimeType.IMAGE_PNG) .build(); List contents = Arrays.asList(textContent, imageContent); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input(InteractionsInput.ofContent(contents)) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.steps().isPresent()) { for (Step step : interaction.steps().get()) { if (step instanceof ModelOutputStep) { ModelOutputStep outputStep = (ModelOutputStep) step; if (outputStep.content().isPresent()) { for (Content contentBlock : outputStep.content().get()) { if (contentBlock instanceof TextContent) { System.out.println(((TextContent) contentBlock).text().orElse("")); } else if (contentBlock instanceof ImageContent) { ImageContent img = (ImageContent) contentBlock; if (img.data().isPresent()) { byte[] outBytes = Base64.getDecoder().decode(img.data().get()); Files.write(Paths.get("cat_with_hat.png"), outBytes); } } } } } } } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "fmt" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } imageBytes, err := os.ReadFile("/path/to/your/cat_photo.png") if err != nil { log.Fatal(err) } base64Image := base64.StdEncoding.EncodeToString(imageBytes) textInput := "Using the provided image of my cat, please add a small, knitted wizard hat on its head. Make it look like it's sitting comfortably and not falling off." contents := []interactions.Content{ interactions.NewContent(interactions.TextContent{ Text: textInput, }), interactions.NewContent(interactions.ImageContent{ Data: genai.Ptr(base64Image), MimeType: interactions.ImageContentMimeTypeImagePng.ToPointer(), }), } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput(contents), }), }) if err != nil { log.Fatal(err) } for _, step := range res.Interaction.Steps { if step.ModelOutputStep != nil { for _, contentBlock := range step.ModelOutputStep.Content { if contentBlock.TextContent != nil { fmt.Println(contentBlock.TextContent.Text) } else if contentBlock.ImageContent != nil && contentBlock.ImageContent.Data != nil { outBytes, err := base64.StdEncoding.DecodeString(*contentBlock.ImageContent.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("cat_with_hat.png", outBytes, 0644); err != nil { log.Fatal(err) } } } } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -d "{ \"model\": \"gemini-nano-banana-2.1\", \"input\": [ {\"type\": \"text\", \"text\": \"Using the provided image of my cat, please add a small, knitted wizard hat on its head. Make it look like it's sitting comfortably and not falling off.\"}, {\"type\": \"image\", \"mime_type\":\"image/png\", \"data\": \"[BASE64_IMAGE_DATA]\"} ] }" ``` {% /tab %} {% /tabs %} {% table %} * Input * Output --- * ![A photorealistic picture of a fluffy ginger cat..](/googledevai/static/gemini-api/docs/images/cat.png){% class="screenshot" width="50%" %} A photorealistic picture of a fluffy ginger cat... * ![Using the provided image of my cat, please add a small, knitted wizard hat...](/googledevai/static/gemini-api/docs/images/cat_with_hat.png){% class="screenshot" width="50%" %} Using the provided image of my cat, please add a small, knitted wizard hat... {% /table %} #### 2. Inpainting (Semantic masking) {% id="2-inpainting-semantic-masking" %} Conversationally define a "mask" to edit a specific part of an image while leaving the rest untouched. {% tabs %} {% tab label="Template" %} ```none Using the provided image, change only the [specific element] to [new element/description]. Keep everything else in the image exactly the same, preserving the original style, lighting, and composition. ``` {% /tab %} {% tab label="Prompt" %} ```none "Using the provided image of a living room, change only the blue sofa to be a vintage, brown leather chesterfield sofa. Keep the rest of the room, including the pillows on the sofa and the lighting, unchanged." ``` {% /tab %} {% tab label="Python" %} ```python from google import genai from PIL import Image import base64 client = genai.Client() with open('/path/to/your/living_room.png', 'rb') as f: image_bytes = f.read() text_input = """Using the provided image of a living room, change only the blue sofa to be a vintage, brown leather chesterfield sofa. Keep the rest of the room, including the pillows on the sofa and the lighting, unchanged.""" interaction = client.interactions.create( model="gemini-nano-banana-2.1", input=[ { "type": "image", "data": base64.b64encode(image_bytes).decode('utf-8'), "mime_type": "image/png" }, {"type": "text", "text": text_input} ], ) for step in interaction.steps: if step.type == "model_output": for content_block in step.content: if content_block.type == "text": print(content_block.text) elif content_block.type == "image": with open("living_room_edited.png", "wb") as f: f.write(base64.b64decode(content_block.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const imagePath = "/path/to/your/living_room.png"; const imageData = fs.readFileSync(imagePath); const base64Image = imageData.toString("base64"); const interaction = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: [ { type: "image", mime_type: "image/png", data: base64Image }, { type: "text", text: "Using the provided image of a living room, change only the blue sofa to be a vintage, brown leather chesterfield sofa. Keep the rest of the room, including the pillows on the sofa and the lighting, unchanged." }, ], }); for (const step of interaction.steps) { if (step.type === "model_output") { for (const contentBlock of step.content || []) { if (contentBlock.type === "text") { console.log(contentBlock.text); } else if (contentBlock.type === "image") { if (contentBlock.data) { const buffer = Buffer.from(contentBlock.data, "base64"); fs.writeFileSync("living_room_edited.png", buffer); } } } } } } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.ImageContentMimeType; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ModelOutputStep; import com.google.genai.gaos.models.interactions.Step; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; import java.util.List; Client client = new Client(); byte[] imageBytes = Files.readAllBytes(Paths.get("/path/to/your/living_room.png")); String base64Image = Base64.getEncoder().encodeToString(imageBytes); String textInput = "Using the provided image of a living room, change only the blue sofa to be a vintage, brown leather chesterfield sofa. Keep the rest of the room, including the pillows on the sofa and the lighting, unchanged."; Content imageContent = ImageContent.builder() .data(base64Image) .mimeType(ImageContentMimeType.IMAGE_PNG) .build(); Content textContent = TextContent.builder().text(textInput).build(); List contents = Arrays.asList(imageContent, textContent); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input(InteractionsInput.ofContent(contents)) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.steps().isPresent()) { for (Step step : interaction.steps().get()) { if (step instanceof ModelOutputStep) { ModelOutputStep outputStep = (ModelOutputStep) step; if (outputStep.content().isPresent()) { for (Content contentBlock : outputStep.content().get()) { if (contentBlock instanceof TextContent) { System.out.println(((TextContent) contentBlock).text().orElse("")); } else if (contentBlock instanceof ImageContent) { ImageContent img = (ImageContent) contentBlock; if (img.data().isPresent()) { byte[] outBytes = Base64.getDecoder().decode(img.data().get()); Files.write(Paths.get("living_room_edited.png"), outBytes); } } } } } } } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "fmt" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } imageBytes, err := os.ReadFile("/path/to/your/living_room.png") if err != nil { log.Fatal(err) } base64Image := base64.StdEncoding.EncodeToString(imageBytes) textInput := "Using the provided image of a living room, change only the blue sofa to be a vintage, brown leather chesterfield sofa. Keep the rest of the room, including the pillows on the sofa and the lighting, unchanged." contents := []interactions.Content{ interactions.NewContent(interactions.ImageContent{ Data: genai.Ptr(base64Image), MimeType: interactions.ImageContentMimeTypeImagePng.ToPointer(), }), interactions.NewContent(interactions.TextContent{ Text: textInput, }), } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput(contents), }), }) if err != nil { log.Fatal(err) } for _, step := range res.Interaction.Steps { if step.ModelOutputStep != nil { for _, contentBlock := range step.ModelOutputStep.Content { if contentBlock.TextContent != nil { fmt.Println(contentBlock.TextContent.Text) } else if contentBlock.ImageContent != nil && contentBlock.ImageContent.Data != nil { outBytes, err := base64.StdEncoding.DecodeString(*contentBlock.ImageContent.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("living_room_edited.png", outBytes, 0644); err != nil { log.Fatal(err) } } } } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -d "{ \"model\": \"gemini-nano-banana-2.1\", \"input\": [ {\"type\": \"image\", \"mime_type\":\"image/png\", \"data\": \"[BASE64_IMAGE_DATA]\"}, {\"type\": \"text\", \"text\": \"Using the provided image of a living room, change only the blue sofa to be a vintage, brown leather chesterfield sofa. Keep the rest of the room, including the pillows on the sofa and the lighting, unchanged.\"} ] }" ``` {% /tab %} {% /tabs %} {% table %} * Input * Output --- * ![A wide shot of a modern, well-lit living room...](/googledevai/static/gemini-api/docs/images/living_room.png){% class="screenshot" width="50%" %} A wide shot of a modern, well-lit living room... * ![Using the provided image of a living room, change only the blue sofa to be a vintage, brown leather chesterfield sofa...](/googledevai/static/gemini-api/docs/images/living_room_edited.png){% class="screenshot" width="50%" %} Using the provided image of a living room, change only the blue sofa to be a vintage, brown leather chesterfield sofa... {% /table %} #### 3. Style transfer {% id="3-style-transfer" %} Provide an image and ask the model to recreate its content in a different artistic style. {% tabs %} {% tab label="Template" %} ```none Transform the provided photograph of [subject] into the artistic style of [artist/art style]. Preserve the original composition but render it with [description of stylistic elements]. ``` {% /tab %} {% tab label="Prompt" %} ```none "Transform the provided photograph of a modern city street at night into the artistic style of Vincent van Gogh's 'Starry Night'. Preserve the original composition of buildings and cars, but render all elements with swirling, impasto brushstrokes and a dramatic palette of deep blues and bright yellows." ``` {% /tab %} {% tab label="Python" %} ```python from google import genai from PIL import Image import base64 client = genai.Client() with open('/path/to/your/city.png', 'rb') as f: image_bytes = f.read() text_input = """Transform the provided photograph of a modern city street at night into the artistic style of Vincent van Gogh's 'Starry Night'. Preserve the original composition of buildings and cars, but render all elements with swirling, impasto brushstrokes and a dramatic palette of deep blues and bright yellows.""" interaction = client.interactions.create( model="gemini-nano-banana-2.1", input=[ { "type": "image", "data": base64.b64encode(image_bytes).decode('utf-8'), "mime_type": "image/png" }, {"type": "text", "text": text_input} ], ) for step in interaction.steps: if step.type == "model_output": for content_block in step.content: if content_block.type == "text": print(content_block.text) elif content_block.type == "image": with open("city_style_transfer.png", "wb") as f: f.write(base64.b64decode(content_block.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const imageData = fs.readFileSync("/path/to/your/city.png"); const base64Image = imageData.toString("base64"); const interaction = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: [ { type: "image", mime_type: "image/png", data: base64Image }, { type: "text", text: "Transform the provided photograph of a modern city street at night into the artistic style of Vincent van Gogh's 'Starry Night'. Preserve the original composition of buildings and cars, but render all elements with swirling, impasto brushstrokes and a dramatic palette of deep blues and bright yellows." }, ], }); for (const step of interaction.steps) { if (step.type === "model_output") { for (const contentBlock of step.content || []) { if (contentBlock.type === "text") { console.log(contentBlock.text); } else if (contentBlock.type === "image") { if (contentBlock.data) { const buffer = Buffer.from(contentBlock.data, "base64"); fs.writeFileSync("city_style_transfer.png", buffer); } } } } } } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.ImageContentMimeType; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ModelOutputStep; import com.google.genai.gaos.models.interactions.Step; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; import java.util.List; Client client = new Client(); byte[] imageBytes = Files.readAllBytes(Paths.get("/path/to/your/city.png")); String base64Image = Base64.getEncoder().encodeToString(imageBytes); String textInput = "Transform the provided photograph of a modern city street at night into the artistic style of Vincent van Gogh's 'Starry Night'. Preserve the original composition of buildings and cars, but render all elements with swirling, impasto brushstrokes and a dramatic palette of deep blues and bright yellows."; Content imageContent = ImageContent.builder() .data(base64Image) .mimeType(ImageContentMimeType.IMAGE_PNG) .build(); Content textContent = TextContent.builder().text(textInput).build(); List contents = Arrays.asList(imageContent, textContent); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input(InteractionsInput.ofContent(contents)) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.steps().isPresent()) { for (Step step : interaction.steps().get()) { if (step instanceof ModelOutputStep) { ModelOutputStep outputStep = (ModelOutputStep) step; if (outputStep.content().isPresent()) { for (Content contentBlock : outputStep.content().get()) { if (contentBlock instanceof TextContent) { System.out.println(((TextContent) contentBlock).text().orElse("")); } else if (contentBlock instanceof ImageContent) { ImageContent img = (ImageContent) contentBlock; if (img.data().isPresent()) { byte[] outBytes = Base64.getDecoder().decode(img.data().get()); Files.write(Paths.get("city_style_transfer.png"), outBytes); } } } } } } } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "fmt" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } imageBytes, err := os.ReadFile("/path/to/your/city.png") if err != nil { log.Fatal(err) } base64Image := base64.StdEncoding.EncodeToString(imageBytes) textInput := "Transform the provided photograph of a modern city street at night into the artistic style of Vincent van Gogh's 'Starry Night'. Preserve the original composition of buildings and cars, but render all elements with swirling, impasto brushstrokes and a dramatic palette of deep blues and bright yellows." contents := []interactions.Content{ interactions.NewContent(interactions.ImageContent{ Data: genai.Ptr(base64Image), MimeType: interactions.ImageContentMimeTypeImagePng.ToPointer(), }), interactions.NewContent(interactions.TextContent{ Text: textInput, }), } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput(contents), }), }) if err != nil { log.Fatal(err) } for _, step := range res.Interaction.Steps { if step.ModelOutputStep != nil { for _, contentBlock := range step.ModelOutputStep.Content { if contentBlock.TextContent != nil { fmt.Println(contentBlock.TextContent.Text) } else if contentBlock.ImageContent != nil && contentBlock.ImageContent.Data != nil { outBytes, err := base64.StdEncoding.DecodeString(*contentBlock.ImageContent.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("city_style_transfer.png", outBytes, 0644); err != nil { log.Fatal(err) } } } } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -d "{ \"model\": \"gemini-nano-banana-2.1\", \"input\": [ {\"type\": \"image\", \"mime_type\":\"image/png\", \"data\": \"[BASE64_IMAGE_DATA]\"}, {\"type\": \"text\", \"text\": \"Transform the provided photograph of a modern city street at night into the artistic style of Vincent van Gogh's 'Starry Night'. Preserve the original composition of buildings and cars, but render all elements with swirling, impasto brushstrokes and a dramatic palette of deep blues and bright yellows.\"} ] }" ``` {% /tab %} {% /tabs %} {% table %} * Input * Output --- * ![A photorealistic, high-resolution photograph of a busy city street...](/googledevai/static/gemini-api/docs/images/city.png){% class="screenshot" width="50%" %} A photorealistic, high-resolution photograph of a busy city street... * ![Transform the provided photograph of a modern city street at night...](/googledevai/static/gemini-api/docs/images/city_style_transfer.png){% class="screenshot" width="50%" %} Transform the provided photograph of a modern city street at night... {% /table %} #### 4. Advanced composition: Combining multiple images {% id="4-advanced-composition-combining-multiple-images" %} Provide multiple images as context to create a new, composite scene. This is perfect for product mockups or creative collages. {% tabs %} {% tab label="Template" %} ```none Create a new image by combining the elements from the provided images. Take the [element from image 1] and place it with/on the [element from image 2]. The final image should be a [description of the final scene]. ``` {% /tab %} {% tab label="Prompt" %} ```none "Create a professional e-commerce fashion photo. Take the blue floral dress from the first image and let the woman from the second image wear it. Generate a realistic, full-body shot of the woman wearing the dress, with the lighting and shadows adjusted to match the outdoor environment." ``` {% /tab %} {% tab label="Python" %} ```python from google import genai from PIL import Image import base64 client = genai.Client() with open('/path/to/your/dress.png', 'rb') as f: dress_bytes = f.read() with open('/path/to/your/model.png', 'rb') as f: model_bytes = f.read() text_input = """Create a professional e-commerce fashion photo. Take the blue floral dress from the first image and let the woman from the second image wear it. Generate a realistic, full-body shot of the woman wearing the dress, with the lighting and shadows adjusted to match the outdoor environment.""" interaction = client.interactions.create( model="gemini-nano-banana-2.1", input=[ { "type": "image", "data": base64.b64encode(dress_bytes).decode('utf-8'), "mime_type": "image/png" }, { "type": "image", "data": base64.b64encode(model_bytes).decode('utf-8'), "mime_type": "image/png" }, {"type": "text", "text": text_input} ], ) for step in interaction.steps: if step.type == "model_output": for content_block in step.content: if content_block.type == "text": print(content_block.text) elif content_block.type == "image": with open("fashion_ecommerce_shot.png", "wb") as f: f.write(base64.b64decode(content_block.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const imagePath1 = "/path/to/your/dress.png"; const imageData1 = fs.readFileSync(imagePath1); const base64Image1 = imageData1.toString("base64"); const imagePath2 = "/path/to/your/model.png"; const imageData2 = fs.readFileSync(imagePath2); const base64Image2 = imageData2.toString("base64"); const interaction = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: [ { type: "image", mime_type: "image/png", data: base64Image1 }, { type: "image", mime_type: "image/png", data: base64Image2 }, { type: "text", text: "Create a professional e-commerce fashion photo. Take the blue floral dress from the first image and let the woman from the second image wear it. Generate a realistic, full-body shot of the woman wearing the dress, with the lighting and shadows adjusted to match the outdoor environment." }, ], }); for (const step of interaction.steps) { if (step.type === "model_output") { for (const contentBlock of step.content || []) { if (contentBlock.type === "text") { console.log(contentBlock.text); } else if (contentBlock.type === "image") { if (contentBlock.data) { const buffer = Buffer.from(contentBlock.data, "base64"); fs.writeFileSync("fashion_ecommerce_shot.png", buffer); } } } } } } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.ImageContentMimeType; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ModelOutputStep; import com.google.genai.gaos.models.interactions.Step; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; import java.util.List; Client client = new Client(); byte[] dressBytes = Files.readAllBytes(Paths.get("/path/to/your/dress.png")); byte[] modelBytes = Files.readAllBytes(Paths.get("/path/to/your/model.png")); String textInput = "Create a professional e-commerce fashion photo. Take the blue floral dress from the first image and let the woman from the second image wear it. Generate a realistic, full-body shot of the woman wearing the dress, with the lighting and shadows adjusted to match the outdoor environment."; Content dressContent = ImageContent.builder() .data(Base64.getEncoder().encodeToString(dressBytes)) .mimeType(ImageContentMimeType.IMAGE_PNG) .build(); Content modelContent = ImageContent.builder() .data(Base64.getEncoder().encodeToString(modelBytes)) .mimeType(ImageContentMimeType.IMAGE_PNG) .build(); Content textContent = TextContent.builder().text(textInput).build(); List contents = Arrays.asList(dressContent, modelContent, textContent); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input(InteractionsInput.ofContent(contents)) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.steps().isPresent()) { for (Step step : interaction.steps().get()) { if (step instanceof ModelOutputStep) { ModelOutputStep outputStep = (ModelOutputStep) step; if (outputStep.content().isPresent()) { for (Content contentBlock : outputStep.content().get()) { if (contentBlock instanceof TextContent) { System.out.println(((TextContent) contentBlock).text().orElse("")); } else if (contentBlock instanceof ImageContent) { ImageContent img = (ImageContent) contentBlock; if (img.data().isPresent()) { byte[] outBytes = Base64.getDecoder().decode(img.data().get()); Files.write(Paths.get("fashion_ecommerce_shot.png"), outBytes); } } } } } } } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "fmt" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } dressBytes, err := os.ReadFile("/path/to/your/dress.png") if err != nil { log.Fatal(err) } modelBytes, err := os.ReadFile("/path/to/your/model.png") if err != nil { log.Fatal(err) } textInput := "Create a professional e-commerce fashion photo. Take the blue floral dress from the first image and let the woman from the second image wear it. Generate a realistic, full-body shot of the woman wearing the dress, with the lighting and shadows adjusted to match the outdoor environment." contents := []interactions.Content{ interactions.NewContent(interactions.ImageContent{ Data: genai.Ptr(base64.StdEncoding.EncodeToString(dressBytes)), MimeType: interactions.ImageContentMimeTypeImagePng.ToPointer(), }), interactions.NewContent(interactions.ImageContent{ Data: genai.Ptr(base64.StdEncoding.EncodeToString(modelBytes)), MimeType: interactions.ImageContentMimeTypeImagePng.ToPointer(), }), interactions.NewContent(interactions.TextContent{ Text: textInput, }), } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput(contents), }), }) if err != nil { log.Fatal(err) } for _, step := range res.Interaction.Steps { if step.ModelOutputStep != nil { for _, contentBlock := range step.ModelOutputStep.Content { if contentBlock.TextContent != nil { fmt.Println(contentBlock.TextContent.Text) } else if contentBlock.ImageContent != nil && contentBlock.ImageContent.Data != nil { outBytes, err := base64.StdEncoding.DecodeString(*contentBlock.ImageContent.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("fashion_ecommerce_shot.png", outBytes, 0644); err != nil { log.Fatal(err) } } } } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -d "{ \"model\": \"gemini-nano-banana-2.1\", \"input\": [ {\"type\": \"image\", \"mime_type\":\"image/png\", \"data\": \"[BASE64_IMAGE_DATA_1]\"}, {\"type\": \"image\", \"mime_type\":\"image/png\", \"data\": \"[BASE64_IMAGE_DATA_2]\"}, {\"type\": \"text\", \"text\": \"Create a professional e-commerce fashion photo. Take the blue floral dress from the first image and let the woman from the second image wear it. Generate a realistic, full-body shot of the woman wearing the dress, with the lighting and shadows adjusted to match the outdoor environment.\"} }] }" ``` {% /tab %} {% /tabs %} {% table %} * Input 1 * Input 2 * Output --- * ![A blue floral summer dress on a neutral background](/googledevai/static/gemini-api/docs/images/dress.png){% class="screenshot" width="50%" %} A blue floral summer dress on a neutral background * ![Full-body shot of a woman with her hair in a bun...](/googledevai/static/gemini-api/docs/images/model.png){% class="screenshot" width="50%" %} Full-body shot of a woman with her hair in a bun... * ![A woman wearing a blue floral summer dress in an outdoor setting](/googledevai/static/gemini-api/docs/images/fashion_ecommerce_shot.png){% class="screenshot" width="50%" %} A woman wearing a blue floral summer dress in an outdoor setting {% /table %} #### 5. High-fidelity detail preservation {% id="5-high-fidelity-detail-preservation" %} To ensure critical details (like a face or logo) are preserved during an edit, describe them in great detail along with your edit request. {% tabs %} {% tab label="Template" %} ```none Using the provided images, place [element from image 2] onto [element from image 1]. Ensure that the features of [element from image 1] remain completely unchanged. The added element should [description of how the element should integrate]. ``` {% /tab %} {% tab label="Prompt" %} ```none "Take the first image of the woman with brown hair, blue eyes, and a neutral expression. Add the logo from the second image onto her black t-shirt. Ensure the woman's face and features remain completely unchanged. The logo should look like it's naturally printed on the fabric, following the folds of the shirt." ``` {% /tab %} {% tab label="Python" %} ```python from google import genai from PIL import Image import base64 client = genai.Client() with open('/path/to/your/woman.png', 'rb') as f: woman_bytes = f.read() with open('/path/to/your/logo.png', 'rb') as f: logo_bytes = f.read() text_input = """Take the first image of the woman with brown hair, blue eyes, and a neutral expression. Add the logo from the second image onto her black t-shirt. Ensure the woman's face and features remain completely unchanged. The logo should look like it's naturally printed on the fabric, following the folds of the shirt.""" interaction = client.interactions.create( model="gemini-nano-banana-2.1", input=[ {"type": "image", "mime_type":"image/png", "data": base64.b64encode(woman_bytes).decode('utf-8')}, {"type": "image", "mime_type":"image/png", "data": base64.b64encode(logo_bytes).decode('utf-8')}, {"type": "text", "text": text_input} ], ) for step in interaction.steps: if step.type == "model_output": for content_block in step.content: if content_block.type == "text": print(content_block.text) elif content_block.type == "image": with open("woman_with_logo.png", "wb") as f: f.write(base64.b64decode(content_block.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const imagePath1 = "/path/to/your/woman.png"; const imageData1 = fs.readFileSync(imagePath1); const base64Image1 = imageData1.toString("base64"); const imagePath2 = "/path/to/your/logo.png"; const imageData2 = fs.readFileSync(imagePath2); const base64Image2 = imageData2.toString("base64"); const interaction = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: [ {"type": "image", "mime_type":"image/png", "data": base64Image1}, {"type": "image", "mime_type":"image/png", "data": base64Image2}, {"type": "text", "text": "Take the first image of the woman with brown hair, blue eyes, and a neutral expression. Add the logo from the second image onto her black t-shirt. Ensure the woman's face and features remain completely unchanged. The logo should look like it's naturally printed on the fabric, following the folds of the shirt."}, ], }); for (const step of interaction.steps) { if (step.type === "model_output") { for (const contentBlock of step.content || []) { if (contentBlock.type === "text") { console.log(contentBlock.text); } else if (contentBlock.type === "image") { if (contentBlock.data) { const buffer = Buffer.from(contentBlock.data, "base64"); fs.writeFileSync("woman_with_logo.png", buffer); } } } } } } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.ImageContentMimeType; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ModelOutputStep; import com.google.genai.gaos.models.interactions.Step; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; import java.util.List; Client client = new Client(); byte[] womanBytes = Files.readAllBytes(Paths.get("/path/to/your/woman.png")); byte[] logoBytes = Files.readAllBytes(Paths.get("/path/to/your/logo.png")); String textInput = "Take the first image of the woman with brown hair, blue eyes, and a neutral expression. Add the logo from the second image onto her black t-shirt. Ensure the woman's face and features remain completely unchanged. The logo should look like it's naturally printed on the fabric, following the folds of the shirt."; Content womanContent = ImageContent.builder() .data(Base64.getEncoder().encodeToString(womanBytes)) .mimeType(ImageContentMimeType.IMAGE_PNG) .build(); Content logoContent = ImageContent.builder() .data(Base64.getEncoder().encodeToString(logoBytes)) .mimeType(ImageContentMimeType.IMAGE_PNG) .build(); Content textContent = TextContent.builder().text(textInput).build(); List contents = Arrays.asList(womanContent, logoContent, textContent); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input(InteractionsInput.ofContent(contents)) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.steps().isPresent()) { for (Step step : interaction.steps().get()) { if (step instanceof ModelOutputStep) { ModelOutputStep outputStep = (ModelOutputStep) step; if (outputStep.content().isPresent()) { for (Content contentBlock : outputStep.content().get()) { if (contentBlock instanceof TextContent) { System.out.println(((TextContent) contentBlock).text().orElse("")); } else if (contentBlock instanceof ImageContent) { ImageContent img = (ImageContent) contentBlock; if (img.data().isPresent()) { byte[] outBytes = Base64.getDecoder().decode(img.data().get()); Files.write(Paths.get("woman_with_logo.png"), outBytes); } } } } } } } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "fmt" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } womanBytes, err := os.ReadFile("/path/to/your/woman.png") if err != nil { log.Fatal(err) } logoBytes, err := os.ReadFile("/path/to/your/logo.png") if err != nil { log.Fatal(err) } textInput := "Take the first image of the woman with brown hair, blue eyes, and a neutral expression. Add the logo from the second image onto her black t-shirt. Ensure the woman's face and features remain completely unchanged. The logo should look like it's naturally printed on the fabric, following the folds of the shirt." contents := []interactions.Content{ interactions.NewContent(interactions.ImageContent{ Data: genai.Ptr(base64.StdEncoding.EncodeToString(womanBytes)), MimeType: interactions.ImageContentMimeTypeImagePng.ToPointer(), }), interactions.NewContent(interactions.ImageContent{ Data: genai.Ptr(base64.StdEncoding.EncodeToString(logoBytes)), MimeType: interactions.ImageContentMimeTypeImagePng.ToPointer(), }), interactions.NewContent(interactions.TextContent{ Text: textInput, }), } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput(contents), }), }) if err != nil { log.Fatal(err) } for _, step := range res.Interaction.Steps { if step.ModelOutputStep != nil { for _, contentBlock := range step.ModelOutputStep.Content { if contentBlock.TextContent != nil { fmt.Println(contentBlock.TextContent.Text) } else if contentBlock.ImageContent != nil && contentBlock.ImageContent.Data != nil { outBytes, err := base64.StdEncoding.DecodeString(*contentBlock.ImageContent.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("woman_with_logo.png", outBytes, 0644); err != nil { log.Fatal(err) } } } } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -d "{ \"model\": \"gemini-nano-banana-2.1\", \"input\": [ {\"type\": \"image\", \"mime_type\":\"image/png\", \"data\": \"[BASE64_IMAGE_DATA_1]\"}, {\"type\": \"image\", \"mime_type\":\"image/png\", \"data\": \"[BASE64_IMAGE_DATA_2]\"}, {\"type\": \"text\", \"text\": \"Take the first image of the woman with brown hair, blue eyes, and a neutral expression. Add the logo from the second image onto her black t-shirt. Ensure the woman's face and features remain completely unchanged. The logo should look like it's naturally printed on the fabric, following the folds of the shirt.\"} ] }" ``` {% /tab %} {% /tabs %} {% table %} * Input 1 * Input 2 * Output --- * ![A professional headshot of a woman with brown hair and blue eyes...](/googledevai/static/gemini-api/docs/images/woman.png){% class="screenshot" width="50%" %} A professional headshot of a woman with brown hair and blue eyes... * ![Modern brand identifier with letters G and A](/googledevai/static/gemini-api/docs/images/logo.png){% class="screenshot" width="50%" %} Modern brand identifier with letters G and A * ![Take the first image of the woman with brown hair, blue eyes, and a neutral expression...](/googledevai/static/gemini-api/docs/images/woman_with_logo.png){% class="screenshot" width="50%" %} Take the first image of the woman with brown hair, blue eyes, and a neutral expression... {% /table %} #### 6. Bring something to life {% id="6-bring-something-to-life" %} Upload a rough sketch or drawing and ask the model to refine it into a finished image. {% tabs %} {% tab label="Template" %} ```none Turn this rough [medium] sketch of a [subject] into a [style description] photo. Keep the [specific features] from the sketch but add [new details/materials]. ``` {% /tab %} {% tab label="Prompt" %} ```none "Turn this rough pencil sketch of a futuristic car into a polished photo of the finished concept car in a showroom. Keep the sleek lines and low profile from the sketch but add metallic blue paint and neon rim lighting." ``` {% /tab %} {% tab label="Python" %} ```python from google import genai from PIL import Image import base64 client = genai.Client() with open('/path/to/your/car_sketch.png', 'rb') as f: sketch_bytes = f.read() text_input = """Turn this rough pencil sketch of a futuristic car into a polished photo of the finished concept car in a showroom. Keep the sleek lines and low profile from the sketch but add metallic blue paint and neon rim lighting.""" interaction = client.interactions.create( model="gemini-nano-banana-2.1", input=[ {"type": "image", "mime_type":"image/png", "data": base64.b64encode(sketch_bytes).decode('utf-8')}, {"type": "text", "text": text_input} ], ) for step in interaction.steps: if step.type == "model_output": for content_block in step.content: if content_block.type == "text": print(content_block.text) elif content_block.type == "image": with open("car_photo.png", "wb") as f: f.write(base64.b64decode(content_block.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const imagePath = "/path/to/your/car_sketch.png"; const imageData = fs.readFileSync(imagePath); const base64Image = imageData.toString("base64"); const interaction = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: [ {"type": "image", "mime_type":"image/png", "data": base64Image}, {"type": "text", "text": "Turn this rough pencil sketch of a futuristic car into a polished photo of the finished concept car in a showroom. Keep the sleek lines and low profile from the sketch but add metallic blue paint and neon rim lighting."}, ], }); for (const step of interaction.steps) { if (step.type === "model_output") { for (const contentBlock of step.content || []) { if (contentBlock.type === "text") { console.log(contentBlock.text); } else if (contentBlock.type === "image") { if (contentBlock.data) { const buffer = Buffer.from(contentBlock.data, "base64"); fs.writeFileSync("car_photo.png", buffer); } } } } } } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.ImageContentMimeType; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ModelOutputStep; import com.google.genai.gaos.models.interactions.Step; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; import java.util.List; Client client = new Client(); byte[] sketchBytes = Files.readAllBytes(Paths.get("/path/to/your/car_sketch.png")); String textInput = "Turn this rough pencil sketch of a futuristic car into a polished photo of the finished concept car in a showroom. Keep the sleek lines and low profile from the sketch but add metallic blue paint and neon rim lighting."; Content sketchContent = ImageContent.builder() .data(Base64.getEncoder().encodeToString(sketchBytes)) .mimeType(ImageContentMimeType.IMAGE_PNG) .build(); Content textContent = TextContent.builder().text(textInput).build(); List contents = Arrays.asList(sketchContent, textContent); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input(InteractionsInput.ofContent(contents)) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.steps().isPresent()) { for (Step step : interaction.steps().get()) { if (step instanceof ModelOutputStep) { ModelOutputStep outputStep = (ModelOutputStep) step; if (outputStep.content().isPresent()) { for (Content contentBlock : outputStep.content().get()) { if (contentBlock instanceof TextContent) { System.out.println(((TextContent) contentBlock).text().orElse("")); } else if (contentBlock instanceof ImageContent) { ImageContent img = (ImageContent) contentBlock; if (img.data().isPresent()) { byte[] outBytes = Base64.getDecoder().decode(img.data().get()); Files.write(Paths.get("car_photo.png"), outBytes); } } } } } } } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "fmt" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } sketchBytes, err := os.ReadFile("/path/to/your/car_sketch.png") if err != nil { log.Fatal(err) } textInput := "Turn this rough pencil sketch of a futuristic car into a polished photo of the finished concept car in a showroom. Keep the sleek lines and low profile from the sketch but add metallic blue paint and neon rim lighting." contents := []interactions.Content{ interactions.NewContent(interactions.ImageContent{ Data: genai.Ptr(base64.StdEncoding.EncodeToString(sketchBytes)), MimeType: interactions.ImageContentMimeTypeImagePng.ToPointer(), }), interactions.NewContent(interactions.TextContent{ Text: textInput, }), } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput(contents), }), }) if err != nil { log.Fatal(err) } for _, step := range res.Interaction.Steps { if step.ModelOutputStep != nil { for _, contentBlock := range step.ModelOutputStep.Content { if contentBlock.TextContent != nil { fmt.Println(contentBlock.TextContent.Text) } else if contentBlock.ImageContent != nil && contentBlock.ImageContent.Data != nil { outBytes, err := base64.StdEncoding.DecodeString(*contentBlock.ImageContent.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("car_photo.png", outBytes, 0644); err != nil { log.Fatal(err) } } } } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -d "{ \"model\": \"gemini-nano-banana-2.1\", \"input\": [ {\"type\": \"image\", \"mime_type\":\"image/png\", \"data\": \"[BASE64_IMAGE_DATA]\"}, {\"type\": \"text\", \"text\": \"Turn this rough pencil sketch of a futuristic car into a polished photo of the finished concept car in a showroom. Keep the sleek lines and low profile from the sketch but add metallic blue paint and neon rim lighting.\"} ] }" ``` {% /tab %} {% /tabs %} {% table %} * Input * Output --- * ![Sketch of a car](/googledevai/static/gemini-api/docs/images/car-sketch.jpg){% class="screenshot" width="50%" %} Rough sketch of a car * ![Output showing the final concept car](/googledevai/static/gemini-api/docs/images/car-photo.jpg){% class="screenshot" width="50%" %} Polished photo of a car {% /table %} #### 7. Character consistency: 360 view {% id="7-character-consistency-360-view" %} You can generate 360-degree views of a character by iteratively prompting for different angles. For best results, include previously generated images in subsequent prompts to maintain consistency. For complex poses, include a reference image of the selected pose. {% tabs %} {% tab label="Template" %} ```none A studio portrait of [person] against [background], [looking forward/in profile looking right/etc.] ``` {% /tab %} {% tab label="Prompt" %} ```none A studio portrait of this man against white, in profile looking right ``` {% /tab %} {% tab label="Python" %} ```python from google import genai from PIL import Image import base64 client = genai.Client() with open('/path/to/your/man_in_white_glasses.jpg', 'rb') as f: image_bytes = f.read() text_input = """A studio portrait of this man against white, in profile looking right""" interaction = client.interactions.create( model="gemini-nano-banana-2.1", input={ {"type": "text", "text": text_input}, {"type": "image", "mime_type":"image/png", "data": base64.b64encode(image_bytes).decode('utf-8')} }, ) for step in interaction.steps: if step.type == "model_output": for content_block in step.content: if content_block.type == "text": print(content_block.text) elif content_block.type == "image": with open("man_right_profile.png", "wb") as f: f.write(base64.b64decode(content_block.data)) ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.ImageContentMimeType; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ModelOutputStep; import com.google.genai.gaos.models.interactions.Step; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; import java.util.List; Client client = new Client(); byte[] imageBytes = Files.readAllBytes(Paths.get("/path/to/your/man_in_white_glasses.jpg")); String textInput = "A studio portrait of this man against white, in profile looking right"; Content textContent = TextContent.builder().text(textInput).build(); Content imageContent = ImageContent.builder() .data(Base64.getEncoder().encodeToString(imageBytes)) .mimeType(ImageContentMimeType.IMAGE_PNG) .build(); List contents = Arrays.asList(textContent, imageContent); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input(InteractionsInput.ofContent(contents)) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.steps().isPresent()) { for (Step step : interaction.steps().get()) { if (step instanceof ModelOutputStep) { ModelOutputStep outputStep = (ModelOutputStep) step; if (outputStep.content().isPresent()) { for (Content contentBlock : outputStep.content().get()) { if (contentBlock instanceof TextContent) { System.out.println(((TextContent) contentBlock).text().orElse("")); } else if (contentBlock instanceof ImageContent) { ImageContent img = (ImageContent) contentBlock; if (img.data().isPresent()) { byte[] outBytes = Base64.getDecoder().decode(img.data().get()); Files.write(Paths.get("man_right_profile.png"), outBytes); } } } } } } } ``` {% /tab %} {% /tabs %} {% table %} * Input * Output 1 * Output 2 --- * ![Original input of a man in white glasses](/googledevai/static/gemini-api/docs/images/man_in_white_glasses.jpg){% class="screenshot" width="50%" %} Original image * ![Output of a man in white glasses looking right](/googledevai/static/gemini-api/docs/images/man_in_white_glasses_looking_right.jpg){% class="screenshot" width="50%" %} Man in white glasses looking right * ![Output of a man in white glasses looking forward](/googledevai/static/gemini-api/docs/images/man_in_white_glasses_looking_forward.jpg){% class="screenshot" width="50%" %} Man in white glasses looking forward {% /table %} ### Best Practices {% id="best-practices" %} To elevate your results from good to great, incorporate these professional strategies into your workflow. * **Be Hyper-Specific:** The more detail you provide, the more control you have. Instead of "fantasy armor," describe it: "ornate elven plate armor, etched with silver leaf patterns, with a high collar and pauldrons shaped like falcon wings." * **Provide Context and Intent:** Explain the *purpose* of the image. The model's understanding of context will influence the final output. For example, "Create a logo for a high-end, minimalist skincare brand" will yield better results than just "Create a logo." * **Iterate and Refine:** Don't expect a perfect image on the first try. Use the conversational nature of the model to make small changes. Follow up with prompts like, "That's great, but can you make the lighting a bit warmer?" or "Keep everything the same, but change the character's expression to be more serious." * **Use Step-by-Step Instructions:** For complex scenes with many elements, break your prompt into steps. "First, create a background of a serene, misty forest at dawn. Then, in the foreground, add a moss-covered ancient stone altar. Finally, place a single, glowing sword on top of the altar." * **Use "Semantic Negative Prompts":** Instead of saying "no cars," describe the intended scene positively: "an empty, deserted street with no signs of traffic." * **Control the Camera:** Use photographic and cinematic language to control the composition. Terms like `wide-angle shot`, `macro shot`, `low-angle perspective`. ## Limitations {% id="limitations" %} * For best performance, use the following languages: EN, ar-EG, de-DE, es-MX, fr-FR, hi-IN, id-ID, it-IT, ja-JP, ko-KR, pt-BR, ru-RU, ua-UA, vi-VN, zh-CN. * Image generation does not support audio inputs. Video inputs are only supported for Gemini Nano Banana 2.1, Gemini 3.1 Flash Image, and Gemini 3.1 Flash Lite Image. * The model won't always follow the exact number of image outputs that the user explicitly asks for. * `gemini-2.5-flash-image` works best with up to 3 images as input, while `gemini-3-pro-image` supports 5 images with high fidelity, and up to 14 images in total. `gemini-nano-banana-2.1` and `gemini-3.1-flash-image` support character resemblance of up to 4 characters and the fidelity of up to 10 objects in a single workflow. * When generating text for an image, Gemini works best if you first generate the text and then ask for an image with the text. * `gemini-nano-banana-2.1` and `gemini-3.1-flash-image` Grounding with Google Search do not support using real-world images of people from web search at this time. * All generated images include a [SynthID watermark](https://ai.google.dev/responsible/docs/safeguards/synthid). ## Optional configurations {% id="optional-configurations" %} You can optionally configure the output format, aspect ratio, and image size using the `response_format` parameter. ### Output format {% id="output-format" %} The model defaults to returning both text and image responses. You can configure the response to return only the generated images (omitting the conversational text) by specifying an image format in the `response_format` parameter. To request multiple modalities (for example, both text and the generated image), pass an array of format entries to `response_format` instead. {% tabs %} {% tab label="Python" %} ```python interaction = client.interactions.create( model="gemini-nano-banana-2.1", input="Write a short poem about a starry night and generate an image of it.", response_format=[ {"type": "text"}, {"type": "image"}, ], ) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript const interaction = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: "Write a short poem about a starry night and generate an image of it.", response_format: [ { type: "text" }, { type: "image" }, ], }); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.CreateModelInteractionResponseFormat; import com.google.genai.gaos.models.interactions.ImageResponseFormat; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ResponseFormat; import com.google.genai.gaos.models.interactions.TextResponseFormat; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.util.Arrays; Client client = new Client(); CreateModelInteractionResponseFormat format = CreateModelInteractionResponseFormat.of( Arrays.asList( ResponseFormat.of(TextResponseFormat.builder().build()), ResponseFormat.of(ImageResponseFormat.builder().build()))); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input( InteractionsInput.of( "Write a short poem about a starry night and generate an image of it.")) .responseFormat(format) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } format := interactions.NewCreateModelInteractionResponseFormat([]interactions.ResponseFormat{ interactions.NewResponseFormat(interactions.TextResponseFormat{}), interactions.NewResponseFormat(interactions.ImageResponseFormat{}), }) res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput("Write a short poem about a starry night and generate an image of it."), ResponseFormat: genai.Ptr(format), }), }) if err != nil { log.Fatal(err) } _ = res } ``` {% /tab %} {% tab label="REST" %} ```bash curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-nano-banana-2.1", "input": "Write a short poem about a starry night and generate an image of it.", "response_format": [ { "type": "text" }, { "type": "image" } ] }' ``` {% /tab %} {% /tabs %} ### Aspect ratios and image size {% id="aspect-ratios-and-image-size" %} By default, the model matches the output image size to that of your input image, or otherwise generates 1:1 squares. You can control the aspect ratio and the size of the output image using the `aspect_ratio` and `image_size` fields under `response_format` when `type` is set to `"image"`. {% tabs %} {% tab label="Python" %} ```python interaction = client.interactions.create( model="gemini-nano-banana-2.1", input=prompt, response_format={ "type": "image", "aspect_ratio": "16:9", "image_size": "2K", }, ) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript const interaction = await ai.interactions.create({ model: "gemini-nano-banana-2.1", input: prompt, response_format: { type: "image", aspect_ratio: "16:9", image_size: "2K", }, }); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.CreateModelInteractionResponseFormat; import com.google.genai.gaos.models.interactions.ImageResponseFormat; import com.google.genai.gaos.models.interactions.ImageResponseFormatAspectRatio; import com.google.genai.gaos.models.interactions.ImageResponseFormatImageSize; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ResponseFormat; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; Client client = new Client(); String prompt = "Create a picture of a nano banana dish in a fancy restaurant with a Gemini theme"; CreateModelInteractionResponseFormat format = CreateModelInteractionResponseFormat.of( ResponseFormat.of( ImageResponseFormat.builder() .aspectRatio(ImageResponseFormatAspectRatio.of("16:9")) .imageSize(ImageResponseFormatImageSize.TWO_K) .build())); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-nano-banana-2.1")) .input(InteractionsInput.of(prompt)) .responseFormat(format) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } prompt := "Create a picture of a nano banana dish in a fancy restaurant with a Gemini theme" format := interactions.NewCreateModelInteractionResponseFormat( interactions.NewResponseFormat(interactions.ImageResponseFormat{ AspectRatio: interactions.ImageResponseFormatAspectRatio("16:9").ToPointer(), ImageSize: interactions.ImageResponseFormatImageSizeTwoK.ToPointer(), }), ) res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-nano-banana-2.1"), Input: interactions.NewInteractionsInput(prompt), ResponseFormat: genai.Ptr(format), }), }) if err != nil { log.Fatal(err) } _ = res } ``` {% /tab %} {% tab label="REST" %} ```bash curl -s -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -H "Api-Revision: 2026-05-20" \ -d '{ "model": "gemini-nano-banana-2.1", "input": "Create a picture of a nano banana dish in a fancy restaurant with a Gemini theme", "response_format": { "type": "image", "aspect_ratio": "16:9", "image_size": "2K" } }' ``` {% /tab %} {% /tabs %} The different ratios available and the size of the image generated are listed in the following tables: {% tabs %} {% tab label="Nano Banana 2.1" %} | Aspect ratio | 1K resolution | 1K tokens | 2K resolution | 2K tokens | 4K resolution | 4K tokens | | :--- | :--- | :--- | :--- | :--- | :--- | :--- | | **1:1** | 1024x1024 | 1120 | 2048x2048 | 1680 | 4096x4096 | 2520 | | **1:4** | 512x2048 | 1120 | 1024x4096 | 1680 | 2048x8192 | 2520 | | **1:8** | 384x3072 | 1120 | 768x6144 | 1680 | 1536x12288 | 2520 | | **2:3** | 848x1264 | 1120 | 1696x2528 | 1680 | 3392x5056 | 2520 | | **3:2** | 1264x848 | 1120 | 2528x1696 | 1680 | 5056x3392 | 2520 | | **3:4** | 896x1200 | 1120 | 1792x2400 | 1680 | 3584x4800 | 2520 | | **4:1** | 2048x512 | 1120 | 4096x1024 | 1680 | 8192x2048 | 2520 | | **4:3** | 1200x896 | 1120 | 2400x1792 | 1680 | 4800x3584 | 2520 | | **4:5** | 928x1152 | 1120 | 1856x2304 | 1680 | 3712x4608 | 2520 | | **5:4** | 1152x928 | 1120 | 2304x1856 | 1680 | 4608x3712 | 2520 | | **8:1** | 3072x384 | 1120 | 6144x768 | 1680 | 12288x1536 | 2520 | | **9:16** | 768x1376 | 1120 | 1536x2752 | 1680 | 3072x5504 | 2520 | | **16:9** | 1376x768 | 1120 | 2752x1536 | 1680 | 5504x3072 | 2520 | | **21:9** | 1584x672 | 1120 | 3168x1344 | 1680 | 6336x2688 | 2520 | {% /tab %} {% tab label="3.1 Flash Image" %} | Aspect ratio | 512px resolution | 0.5K tokens | 1K resolution | 1K tokens | 2K resolution | 2K tokens | 4K resolution | 4K tokens | | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | | **1:1** | 512x512 | 747 | 1024x1024 | 1120 | 2048x2048 | 1680 | 4096x4096 | 2520 | | **1:4** | 256x1024 | 747 | 512x2048 | 1120 | 1024x4096 | 1680 | 2048x8192 | 2520 | | **1:8** | 192x1536 | 747 | 384x3072 | 1120 | 768x6144 | 1680 | 1536x12288 | 2520 | | **2:3** | 424x632 | 747 | 848x1264 | 1120 | 1696x2528 | 1680 | 3392x5056 | 2520 | | **3:2** | 632x424 | 747 | 1264x848 | 1120 | 2528x1696 | 1680 | 5056x3392 | 2520 | | **3:4** | 448x600 | 747 | 896x1200 | 1120 | 1792x2400 | 1680 | 3584x4800 | 2520 | | **4:1** | 1024x256 | 747 | 2048x512 | 1120 | 4096x1024 | 1680 | 8192x2048 | 2520 | | **4:3** | 600x448 | 747 | 1200x896 | 1120 | 2400x1792 | 1680 | 4800x3584 | 2520 | | **4:5** | 464x576 | 747 | 928x1152 | 1120 | 1856x2304 | 1680 | 3712x4608 | 2520 | | **5:4** | 576x464 | 747 | 1152x928 | 1120 | 2304x1856 | 1680 | 4608x3712 | 2520 | | **8:1** | 1536x192 | 747 | 3072x384 | 1120 | 6144x768 | 1680 | 12288x1536 | 2520 | | **9:16** | 384x688 | 747 | 768x1376 | 1120 | 1536x2752 | 1680 | 3072x5504 | 2520 | | **16:9** | 688x384 | 747 | 1376x768 | 1120 | 2752x1536 | 1680 | 5504x3072 | 2520 | | **21:9** | 792x168 | 747 | 1584x672 | 1120 | 3168x1344 | 1680 | 6336x2688 | 2520 | {% /tab %} {% tab label="3 Pro Image" %} | Aspect ratio | 1K resolution | 1K tokens | 2K resolution | 2K tokens | 4K resolution | 4K tokens | | :--- | :--- | :--- | :--- | :--- | :--- | :--- | | **1:1** | 1024x1024 | 1120 | 2048x2048 | 1120 | 4096x4096 | 2000 | | **2:3** | 848x1264 | 1120 | 1696x2528 | 1120 | 3392x5056 | 2000 | | **3:2** | 1264x848 | 1120 | 2528x1696 | 1120 | 5056x3392 | 2000 | | **3:4** | 896x1200 | 1120 | 1792x2400 | 1120 | 3584x4800 | 2000 | | **4:3** | 1200x896 | 1120 | 2400x1792 | 1120 | 4800x3584 | 2000 | | **4:5** | 928x1152 | 1120 | 1856x2304 | 1120 | 3712x4608 | 2000 | | **5:4** | 1152x928 | 1120 | 2304x1856 | 1120 | 4608x3712 | 2000 | | **9:16** | 768x1376 | 1120 | 1536x2752 | 1120 | 3072x5504 | 2000 | | **16:9** | 1376x768 | 1120 | 2752x1536 | 1120 | 5504x3072 | 2000 | | **21:9** | 1584x672 | 1120 | 3168x1344 | 1120 | 6336x2688 | 2000 | {% /tab %} {% tab label="Gemini 2.5 Flash Image" %} | Aspect ratio | Resolution | Tokens | | --- | --- | --- | | 1:1 | 1024x1024 | 1290 | | 2:3 | 832x1248 | 1290 | | 3:2 | 1248x832 | 1290 | | 3:4 | 864x1184 | 1290 | | 4:3 | 1184x864 | 1290 | | 4:5 | 896x1152 | 1290 | | 5:4 | 1152x896 | 1290 | | 9:16 | 768x1344 | 1290 | | 16:9 | 1344x768 | 1290 | | 21:9 | 1536x672 | 1290 | {% /tab %} {% /tabs %} ## When to use Imagen {% id="choose-a-model" %} {% callout type="warning" %} Imagen models are shut down. Use Nano Banana models for all image generation tasks. {% /callout %} Imagen is shut down and no longer available through the Gemini API. Use Nano Banana for image generation and editing. ## What's next {% id="what-is-next" %} * Check out the [Veo guide](/docs/video) to learn how to generate videos with the Gemini API. * To learn more about Gemini models, see [Gemini models](/docs/models). # Generate videos with Veo 3.1 in Gemini API Source: https://aistudio.google.com/docs/veo Description: Generate high-fidelity videos with native audio using Google's Veo 3.1 API. {% callout type="warning" %} Veo 3.1 Preview (`veo-3.1-generate-preview`, `veo-3.1-fast-generate-preview`, and `veo-3.1-lite-generate-preview`) in the Gemini API was [shut down](/docs/deprecations) on **October 22, 2026**. Migrate to [Gemini Omni Flash](/docs/models/gemini-omni-flash) (`gemini-omni-1.1-flash`) or the GA models available through the [Gemini Enterprise Agent Platform](https://docs.cloud.google.com/gemini-enterprise-agent-platform/models/veo/3-1-generate) to avoid service interruptions. {% /callout %} > To learn about video understanding, see the [Video understanding](/docs/video-understanding) guide. [Veo 3.1](https://deepmind.google/models/veo/) is a model for generating 8-second videos (720p, 1080p, or 4k) with natively generated audio. You can access this model programmatically using the Gemini API. To learn more about the available Veo model variants, see the [Model Versions](/docs/veo#model-versions) section. Veo 3.1 excels at a wide range of visual and cinematic styles and introduces several new capabilities: * **Portrait videos**: Choose between landscape (`16:9`) and portrait (`9:16`) videos. * **Video extension**: Extend videos that were previously generated using Veo. * **Frame-specific generation**: Generate a video by specifying the first and last frames. * **Image-based direction**: Use up to three reference images to guide the content of your generated video. For more information about writing effective text prompts for video generation, see the [Veo prompt guide](/docs/veo#prompt-guide) ## Text to video generation {% id="generate-from-text" %} The following examples show how you can generate a video with [dialogue](/docs/veo#dialogue), [cinematic realism](/docs/veo#realism), or [creative animation](/docs/veo#style): ### Dialogue & sound effects {% id="dialogue" %} {% tabs %} {% tab label="Python" filename="sample.py" %} ```python import time from google import genai from google.genai import types client = genai.Client() prompt = """A close up of two people staring at a cryptic drawing on a wall, torchlight flickering. A man murmurs, 'This must be it. That's the secret code.' The woman looks at him and whispering excitedly, 'What did you find?'""" operation = client.models.generate_videos( model="veo-3.1-generate-preview", prompt=prompt, ) # Poll the operation status until the video is ready. while not operation.done: print("Waiting for video generation to complete...") time.sleep(10) operation = client.operations.get(operation) # Download the generated video. generated_video = operation.response.generated_videos[0] client.files.download(file=generated_video.video, destination="dialogue_example.mp4") print("Generated video saved to dialogue_example.mp4") ``` {% /tab %} {% tab label="JavaScript" filename="sample.js" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); const prompt = `A close up of two people staring at a cryptic drawing on a wall, torchlight flickering. A man murmurs, 'This must be it. That's the secret code.' The woman looks at him and whispering excitedly, 'What did you find?'`; let operation = await ai.models.generateVideos({ model: "veo-3.1-generate-preview", prompt: prompt, }); // Poll the operation status until the video is ready. while (!operation.done) { console.log("Waiting for video generation to complete...") await new Promise((resolve) => setTimeout(resolve, 10000)); operation = await ai.operations.getVideosOperation({ operation: operation, }); } // Download the generated video. const video = operation.response?.generatedVideos?.[0]?.video; if (video) { await ai.files.download({ file: video, downloadPath: "dialogue_example.mp4", }); console.log(`Generated video saved to dialogue_example.mp4`); } ``` {% /tab %} {% tab label="Go" filename="sample.go" %} ```go package main import ( "context" "log" "os" "time" "google.golang.org/genai" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } prompt := `A close up of two people staring at a cryptic drawing on a wall, torchlight flickering. A man murmurs, 'This must be it. That's the secret code.' The woman looks at him and whispering excitedly, 'What did you find?'` operation, _ := client.Models.GenerateVideos( ctx, "veo-3.1-generate-preview", prompt, nil, nil, ) // Poll the operation status until the video is ready. for !operation.Done { log.Println("Waiting for video generation to complete...") time.Sleep(10 * time.Second) operation, _ = client.Operations.GetVideosOperation(ctx, operation, nil) } // Download the generated video. video := operation.Response.GeneratedVideos[0] client.Files.Download(ctx, video.Video, nil) fname := "dialogue_example.mp4" _ = os.WriteFile(fname, video.Video.VideoBytes, 0644) log.Printf("Generated video saved to %s\n", fname) } ``` {% /tab %} {% tab label="Java" filename="sample.java" %} ```java import com.google.genai.Client; import com.google.genai.types.GenerateVideosOperation; import com.google.genai.types.GeneratedVideo; Client client = new Client(); String prompt = "A close up of two people staring at a cryptic drawing on a wall, torchlight flickering.\n" + "A man murmurs, 'This must be it. That's the secret code.' The woman looks at him and whispering excitedly, 'What did you find?'"; GenerateVideosOperation operation = client.models.generateVideos("veo-3.1-generate-preview", prompt, null, null); // Poll the operation status until the video is ready. while (!operation.done().orElse(false)) { System.out.println("Waiting for video generation to complete..."); Thread.sleep(10000); operation = client.operations.getVideosOperation(operation, null); } // Download the generated video. GeneratedVideo generatedVideo = operation.response().get().generatedVideos().get().get(0); client.files.download(generatedVideo, "dialogue_example.mp4", null); System.out.println("Generated video saved to dialogue_example.mp4"); ``` {% /tab %} {% tab label="REST" filename="sample.sh" %} ```shell # Note: This script uses jq to parse the JSON response. # GEMINI API Base URL BASE_URL="https://generativelanguage.googleapis.com/v1beta" # Send request to generate video and capture the operation name into a variable. operation_name=$(curl -s "${BASE_URL}/models/veo-3.1-generate-preview:predictLongRunning" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -X "POST" \ -d '{ "instances": [{ "prompt": "A close up of two people staring at a cryptic drawing on a wall, torchlight flickering. A man murmurs, \"This must be it. That'\''s the secret code.\" The woman looks at him and whispering excitedly, \"What did you find?\"" } ] }' | jq -r .name) # Poll the operation status until the video is ready while true; do # Get the full JSON status and store it in a variable. status_response=$(curl -s -H "x-goog-api-key: $GEMINI_API_KEY" "${BASE_URL}/${operation_name}") # Check the "done" field from the JSON stored in the variable. is_done=$(echo "${status_response}" | jq .done) if [ "${is_done}" = "true" ]; then # Extract the download URI from the final response. video_uri=$(echo "${status_response}" | jq -r '.response.generateVideoResponse.generatedSamples[0].video.uri') echo "Downloading video from: ${video_uri}" # Download the video using the URI and API key and follow redirects. curl -L -o dialogue_example.mp4 -H "x-goog-api-key: $GEMINI_API_KEY" "${video_uri}" break fi # Wait for 5 seconds before checking again. sleep 10 done ``` {% /tab %} {% /tabs %} ### Cinematic realism {% id="realism" %} {% tabs %} {% tab label="Python" filename="sample.py" %} ```python import time from google import genai from google.genai import types client = genai.Client() prompt = """Drone shot following a classic red convertible driven by a man along a winding coastal road at sunset, waves crashing against the rocks below. The convertible accelerates fast and the engine roars loudly.""" operation = client.models.generate_videos( model="veo-3.1-generate-preview", prompt=prompt, ) # Poll the operation status until the video is ready. while not operation.done: print("Waiting for video generation to complete...") time.sleep(10) operation = client.operations.get(operation) # Download the generated video. generated_video = operation.response.generated_videos[0] client.files.download(file=generated_video.video, destination="realism_example.mp4") print("Generated video saved to realism_example.mp4") ``` {% /tab %} {% tab label="JavaScript" filename="sample.js" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); const prompt = `Drone shot following a classic red convertible driven by a man along a winding coastal road at sunset, waves crashing against the rocks below. The convertible accelerates fast and the engine roars loudly.`; let operation = await ai.models.generateVideos({ model: "veo-3.1-generate-preview", prompt: prompt, }); // Poll the operation status until the video is ready. while (!operation.done) { console.log("Waiting for video generation to complete...") await new Promise((resolve) => setTimeout(resolve, 10000)); operation = await ai.operations.getVideosOperation({ operation: operation, }); } // Download the generated video. const video = operation.response?.generatedVideos?.[0]?.video; if (video) { await ai.files.download({ file: video, downloadPath: "realism_example.mp4", }); console.log(`Generated video saved to realism_example.mp4`); } ``` {% /tab %} {% tab label="Go" filename="sample.go" %} ```go package main import ( "context" "log" "os" "time" "google.golang.org/genai" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } prompt := `Drone shot following a classic red convertible driven by a man along a winding coastal road at sunset, waves crashing against the rocks below. The convertible accelerates fast and the engine roars loudly.` operation, _ := client.Models.GenerateVideos( ctx, "veo-3.1-generate-preview", prompt, nil, nil, ) // Poll the operation status until the video is ready. for !operation.Done { log.Println("Waiting for video generation to complete...") time.Sleep(10 * time.Second) operation, _ = client.Operations.GetVideosOperation(ctx, operation, nil) } // Download the generated video. video := operation.Response.GeneratedVideos[0] client.Files.Download(ctx, video.Video, nil) fname := "realism_example.mp4" _ = os.WriteFile(fname, video.Video.VideoBytes, 0644) log.Printf("Generated video saved to %s\n", fname) } ``` {% /tab %} {% tab label="Java" filename="sample.java" %} ```java import com.google.genai.Client; import com.google.genai.types.GenerateVideosOperation; import com.google.genai.types.GeneratedVideo; Client client = new Client(); String prompt = "Drone shot following a classic red convertible driven by a man along a winding coastal road at sunset, waves crashing against the rocks below.\n" + "The convertible accelerates fast and the engine roars loudly."; GenerateVideosOperation operation = client.models.generateVideos("veo-3.1-generate-preview", prompt, null, null); // Poll the operation status until the video is ready. while (!operation.done().orElse(false)) { System.out.println("Waiting for video generation to complete..."); Thread.sleep(10000); operation = client.operations.getVideosOperation(operation, null); } // Download the generated video. GeneratedVideo generatedVideo = operation.response().get().generatedVideos().get().get(0); client.files.download(generatedVideo, "realism_example.mp4", null); System.out.println("Generated video saved to realism_example.mp4"); ``` {% /tab %} {% tab label="REST" filename="sample.sh" %} ```shell # Note: This script uses jq to parse the JSON response. # GEMINI API Base URL BASE_URL="https://generativelanguage.googleapis.com/v1beta" # Send request to generate video and capture the operation name into a variable. operation_name=$(curl -s "${BASE_URL}/models/veo-3.1-generate-preview:predictLongRunning" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -X "POST" \ -d '{ "instances": [{ "prompt": "Drone shot following a classic red convertible driven by a man along a winding coastal road at sunset, waves crashing against the rocks below. The convertible accelerates fast and the engine roars loudly." } ] }' | jq -r .name) # Poll the operation status until the video is ready while true; do # Get the full JSON status and store it in a variable. status_response=$(curl -s -H "x-goog-api-key: $GEMINI_API_KEY" "${BASE_URL}/${operation_name}") # Check the "done" field from the JSON stored in the variable. is_done=$(echo "${status_response}" | jq .done) if [ "${is_done}" = "true" ]; then # Extract the download URI from the final response. video_uri=$(echo "${status_response}" | jq -r '.response.generateVideoResponse.generatedSamples[0].video.uri') echo "Downloading video from: ${video_uri}" # Download the video using the URI and API key and follow redirects. curl -L -o realism_example.mp4 -H "x-goog-api-key: $GEMINI_API_KEY" "${video_uri}" break fi # Wait for 5 seconds before checking again. sleep 10 done ``` {% /tab %} {% /tabs %} ### Creative animation {% id="style" %} {% tabs %} {% tab label="Python" filename="sample.py" %} ```python import time from google import genai client = genai.Client() prompt = "A whimsical stop-motion animation of a tiny robot tending to a garden of glowing mushrooms on a miniature planet." operation = client.models.generate_videos( model="veo-3.1-generate-preview", prompt=prompt, ) # Poll the operation status until the video is ready. while not operation.done: print("Waiting for video generation to complete...") time.sleep(10) operation = client.operations.get(operation) # Download the generated video. generated_video = operation.response.generated_videos[0] client.files.download(file=generated_video.video, destination="style_example.mp4") print("Generated video saved to style_example.mp4") ``` {% /tab %} {% tab label="JavaScript" filename="sample.js" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); const prompt = "A whimsical stop-motion animation of a tiny robot tending to a garden of glowing mushrooms on a miniature planet."; let operation = await ai.models.generateVideos({ model: "veo-3.1-generate-preview", prompt: prompt, }); // Poll the operation status until the video is ready. while (!operation.done) { console.log("Waiting for video generation to complete...") await new Promise((resolve) => setTimeout(resolve, 10000)); operation = await ai.operations.getVideosOperation({ operation: operation, }); } // Download the generated video. const video = operation.response?.generatedVideos?.[0]?.video; if (video) { await ai.files.download({ file: video, downloadPath: "style_example.mp4", }); console.log(`Generated video saved to style_example.mp4`); } ``` {% /tab %} {% tab label="Go" filename="sample.go" %} ```go package main import ( "context" "log" "os" "time" "google.golang.org/genai" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } prompt := `A whimsical stop-motion animation of a tiny robot tending to a garden of glowing mushrooms on a miniature planet.` operation, _ := client.Models.GenerateVideos( ctx, "veo-3.1-generate-preview", prompt, nil, nil, ) // Poll the operation status until the video is ready. for !operation.Done { log.Println("Waiting for video generation to complete...") time.Sleep(10 * time.Second) operation, _ = client.Operations.GetVideosOperation(ctx, operation, nil) } // Download the generated video. video := operation.Response.GeneratedVideos[0] client.Files.Download(ctx, video.Video, nil) fname := "style_example.mp4" _ = os.WriteFile(fname, video.Video.VideoBytes, 0644) log.Printf("Generated video saved to %s\n", fname) } ``` {% /tab %} {% tab label="Java" filename="sample.java" %} ```java import com.google.genai.Client; import com.google.genai.types.GenerateVideosOperation; import com.google.genai.types.GeneratedVideo; Client client = new Client(); String prompt = "A whimsical stop-motion animation of a tiny robot tending to a garden of glowing mushrooms on a miniature planet."; GenerateVideosOperation operation = client.models.generateVideos("veo-3.1-generate-preview", prompt, null, null); // Poll the operation status until the video is ready. while (!operation.done().orElse(false)) { System.out.println("Waiting for video generation to complete..."); Thread.sleep(10000); operation = client.operations.getVideosOperation(operation, null); } // Download the generated video. GeneratedVideo generatedVideo = operation.response().get().generatedVideos().get().get(0); client.files.download(generatedVideo, "style_example.mp4", null); System.out.println("Generated video saved to style_example.mp4"); ``` {% /tab %} {% tab label="REST" filename="sample.sh" %} ```shell # Note: This script uses jq to parse the JSON response. # GEMINI API Base URL BASE_URL="https://generativelanguage.googleapis.com/v1beta" # Send request to generate video and capture the operation name into a variable. operation_name=$(curl -s "${BASE_URL}/models/veo-3.1-generate-preview:predictLongRunning" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -X "POST" \ -d '{ "instances": [{ "prompt": "A whimsical stop-motion animation of a tiny robot tending to a garden of glowing mushrooms on a miniature planet." } ] }' | jq -r .name) # Poll the operation status until the video is ready while true; do # Get the full JSON status and store it in a variable. status_response=$(curl -s -H "x-goog-api-key: $GEMINI_API_KEY" "${BASE_URL}/${operation_name}") # Check the "done" field from the JSON stored in the variable. is_done=$(echo "${status_response}" | jq .done) if [ "${is_done}" = "true" ]; then # Extract the download URI from the final response. video_uri=$(echo "${status_response}" | jq -r '.response.generateVideoResponse.generatedSamples[0].video.uri') echo "Downloading video from: ${video_uri}" # Download the video using the URI and API key and follow redirects. curl -L -o style_example.mp4 -H "x-goog-api-key: $GEMINI_API_KEY" "${video_uri}" break fi # Wait for 5 seconds before checking again. sleep 10 done ``` {% /tab %} {% /tabs %} ## Control the aspect ratio {% id="aspect-ratio" %} Veo 3.1 lets you create landscape (`16:9`, the default setting) or portrait (`9:16`) videos. You can tell the model which one you want using the `aspect_ratio` parameter: {% tabs %} {% tab label="Python" filename="sample.py" %} ```python import time from google import genai from google.genai import types client = genai.Client() prompt = """A montage of pizza making: a chef tossing and flattening the floury dough, ladling rich red tomato sauce in a spiral, sprinkling mozzarella cheese and pepperoni, and a final shot of the bubbling golden-brown pizza, upbeat electronic music with a rhythmical beat is playing, high energy professional video.""" operation = client.models.generate_videos( model="veo-3.1-generate-preview", prompt=prompt, config=types.GenerateVideosConfig( aspect_ratio="9:16", ), ) # Poll the operation status until the video is ready. while not operation.done: print("Waiting for video generation to complete...") time.sleep(10) operation = client.operations.get(operation) # Download the generated video. generated_video = operation.response.generated_videos[0] client.files.download(file=generated_video.video, destination="pizza_making.mp4") print("Generated video saved to pizza_making.mp4") ``` {% /tab %} {% tab label="JavaScript" filename="sample.js" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); const prompt = `A montage of pizza making: a chef tossing and flattening the floury dough, ladling rich red tomato sauce in a spiral, sprinkling mozzarella cheese and pepperoni, and a final shot of the bubbling golden-brown pizza, upbeat electronic music with a rhythmical beat is playing, high energy professional video.`; let operation = await ai.models.generateVideos({ model: "veo-3.1-generate-preview", prompt: prompt, config: { aspectRatio: "9:16", }, }); // Poll the operation status until the video is ready. while (!operation.done) { console.log("Waiting for video generation to complete...") await new Promise((resolve) => setTimeout(resolve, 10000)); operation = await ai.operations.getVideosOperation({ operation: operation, }); } // Download the generated video. const video = operation.response?.generatedVideos?.[0]?.video; if (video) { await ai.files.download({ file: video, downloadPath: "pizza_making.mp4", }); console.log(`Generated video saved to pizza_making.mp4`); } ``` {% /tab %} {% tab label="Go" filename="sample.go" %} ```go package main import ( "context" "log" "os" "time" "google.golang.org/genai" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } prompt := `A montage of pizza making: a chef tossing and flattening the floury dough, ladling rich red tomato sauce in a spiral, sprinkling mozzarella cheese and pepperoni, and a final shot of the bubbling golden-brown pizza, upbeat electronic music with a rhythmical beat is playing, high energy professional video.` videoConfig := &genai.GenerateVideosConfig{ AspectRatio: "9:16", } operation, _ := client.Models.GenerateVideos( ctx, "veo-3.1-generate-preview", prompt, nil, videoConfig, ) // Poll the operation status until the video is ready. for !operation.Done { log.Println("Waiting for video generation to complete...") time.Sleep(10 * time.Second) operation, _ = client.Operations.GetVideosOperation(ctx, operation, nil) } // Download the generated video. video := operation.Response.GeneratedVideos[0] client.Files.Download(ctx, video.Video, nil) fname := "pizza_making.mp4" _ = os.WriteFile(fname, video.Video.VideoBytes, 0644) log.Printf("Generated video saved to %s\n", fname) } ``` {% /tab %} {% tab label="REST" filename="sample.sh" %} ```shell # Note: This script uses jq to parse the JSON response. # GEMINI API Base URL BASE_URL="https://generativelanguage.googleapis.com/v1beta" # Send request to generate video and capture the operation name into a variable. operation_name=$(curl -s "${BASE_URL}/models/veo-3.1-generate-preview:predictLongRunning" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -X "POST" \ -d '{ "instances": [{ "prompt": "A montage of pizza making: a chef tossing and flattening the floury dough, ladling rich red tomato sauce in a spiral, sprinkling mozzarella cheese and pepperoni, and a final shot of the bubbling golden-brown pizza, upbeat electronic music with a rhythmical beat is playing, high energy professional video." } ], "parameters": { "aspectRatio": "9:16" } }' | jq -r .name) # Poll the operation status until the video is ready while true; do # Get the full JSON status and store it in a variable. status_response=$(curl -s -H "x-goog-api-key: $GEMINI_API_KEY" "${BASE_URL}/${operation_name}") # Check the "done" field from the JSON stored in the variable. is_done=$(echo "${status_response}" | jq .done) if [ "${is_done}" = "true" ]; then # Extract the download URI from the final response. video_uri=$(echo "${status_response}" | jq -r '.response.generateVideoResponse.generatedSamples[0].video.uri') echo "Downloading video from: ${video_uri}" # Download the video using the URI and API key and follow redirects. curl -L -o pizza_making.mp4 -H "x-goog-api-key: $GEMINI_API_KEY" "${video_uri}" break fi # Wait for 5 seconds before checking again. sleep 10 done ``` {% /tab %} {% /tabs %} ## Control the resolution {% id="resolution" %} Veo 3.1 can also directly generate 720p, 1080p or 4k videos (4k not available for Veo 3.1 Lite). Note that the higher the resolution, the higher the latency will be. 4k videos are also more expensive (see [pricing](/docs/pricing)). [Video extension](/docs/veo#extending-veo-videos) is also limited to 720p videos. {% tabs %} {% tab label="Python" filename="sample.py" %} ```python import time from google import genai from google.genai import types client = genai.Client() prompt = """A stunning drone view of the Grand Canyon during a flamboyant sunset that highlights the canyon's colors. The drone slowly flies towards the sun then accelerates, dives and flies inside the canyon.""" operation = client.models.generate_videos( model="veo-3.1-generate-preview", prompt=prompt, config=types.GenerateVideosConfig( resolution="4k", ), ) # Poll the operation status until the video is ready. while not operation.done: print("Waiting for video generation to complete...") time.sleep(10) operation = client.operations.get(operation) # Download the generated video. generated_video = operation.response.generated_videos[0] client.files.download(file=generated_video.video, destination="4k_grand_canyon.mp4") print("Generated video saved to 4k_grand_canyon.mp4") ``` {% /tab %} {% tab label="JavaScript" filename="sample.js" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); const prompt = `A stunning drone view of the Grand Canyon during a flamboyant sunset that highlights the canyon's colors. The drone slowly flies towards the sun then accelerates, dives and flies inside the canyon.`; let operation = await ai.models.generateVideos({ model: "veo-3.1-generate-preview", prompt: prompt, config: { resolution: "4k", }, }); // Poll the operation status until the video is ready. while (!operation.done) { console.log("Waiting for video generation to complete...") await new Promise((resolve) => setTimeout(resolve, 10000)); operation = await ai.operations.getVideosOperation({ operation: operation, }); } // Download the generated video. const video = operation.response?.generatedVideos?.[0]?.video; if (video) { await ai.files.download({ file: video, downloadPath: "4k_grand_canyon.mp4", }); console.log(`Generated video saved to 4k_grand_canyon.mp4`); } ``` {% /tab %} {% tab label="Go" filename="sample.go" %} ```go package main import ( "context" "log" "os" "time" "google.golang.org/genai" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } prompt := `A stunning drone view of the Grand Canyon during a flamboyant sunset that highlights the canyon's colors. The drone slowly flies towards the sun then accelerates, dives and flies inside the canyon.` videoConfig := &genai.GenerateVideosConfig{ Resolution: "4k", } operation, _ := client.Models.GenerateVideos( ctx, "veo-3.1-generate-preview", prompt, nil, videoConfig, ) // Poll the operation status until the video is ready. for !operation.Done { log.Println("Waiting for video generation to complete...") time.Sleep(10 * time.Second) operation, _ = client.Operations.GetVideosOperation(ctx, operation, nil) } // Download the generated video. video := operation.Response.GeneratedVideos[0] client.Files.Download(ctx, video.Video, nil) fname := "4k_grand_canyon.mp4" _ = os.WriteFile(fname, video.Video.VideoBytes, 0644) log.Printf("Generated video saved to %s\n", fname) } ``` {% /tab %} {% tab label="REST" filename="sample.sh" %} ```shell # Note: This script uses jq to parse the JSON response. # GEMINI API Base URL BASE_URL="https://generativelanguage.googleapis.com/v1beta" # Send request to generate video and capture the operation name into a variable. operation_name=$(curl -s "${BASE_URL}/models/veo-3.1-generate-preview:predictLongRunning" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -X "POST" \ -d '{ "instances": [{ "prompt": "A stunning drone view of the Grand Canyon during a flamboyant sunset that highlights the canyon'\''s colors. The drone slowly flies towards the sun then accelerates, dives and flies inside the canyon." } ], "parameters": { "resolution": "4k" } }' | jq -r .name) # Poll the operation status until the video is ready while true; do # Get the full JSON status and store it in a variable. status_response=$(curl -s -H "x-goog-api-key: $GEMINI_API_KEY" "${BASE_URL}/${operation_name}") # Check the "done" field from the JSON stored in the variable. is_done=$(echo "${status_response}" | jq .done) if [ "${is_done}" = "true" ]; then # Extract the download URI from the final response. video_uri=$(echo "${status_response}" | jq -r '.response.generateVideoResponse.generatedSamples[0].video.uri') echo "Downloading video from: ${video_uri}" # Download the video using the URI and API key and follow redirects. curl -L -o 4k_grand_canyon.mp4 -H "x-goog-api-key: $GEMINI_API_KEY" "${video_uri}" break fi # Wait for 5 seconds before checking again. sleep 10 done ``` {% /tab %} {% /tabs %} ## Image to video generation {% id="generate-from-images" %} The following code demonstrates generating an image using [Gemini 3.1 Flash Image aka Nano Banana 2](/docs/image-generation), then using that image as the starting frame for generating a video with Veo 3.1. {% tabs %} {% tab label="Python" filename="sample.py" %} ```python import time from google import genai client = genai.Client() prompt = "Panning wide shot of a calico kitten sleeping in the sunshine" # Step 1: Generate an image with Nano Banana 2. image = client.models.generate_content( model="gemini-3.1-flash-image-preview", contents=prompt, config={"response_modalities":['IMAGE']} ) # Step 2: Generate video with Veo 3.1 using the image. operation = client.models.generate_videos( model="veo-3.1-generate-preview", prompt=prompt, image=image.parts[0].as_image(), ) # Poll the operation status until the video is ready. while not operation.done: print("Waiting for video generation to complete...") time.sleep(10) operation = client.operations.get(operation) # Download the video. video = operation.response.generated_videos[0] client.files.download(file=video.video, destination="veo3_with_image_input.mp4") print("Generated video saved to veo3_with_image_input.mp4") ``` {% /tab %} {% tab label="JavaScript" filename="sample.js" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); const prompt = "Panning wide shot of a calico kitten sleeping in the sunshine"; // Step 1: Generate an image with Nano Banana 2. const imageResponse = await ai.models.generateContent({ model: "gemini-3.1-flash-image-preview", contents: prompt, config: { responseModalities: ["IMAGE"] }, }); const inlineData = imageResponse.candidates?.[0]?.content?.parts?.[0]?.inlineData; // Step 2: Generate video with Veo 3.1 using the image. let operation = await ai.models.generateVideos({ model: "veo-3.1-generate-preview", prompt: prompt, image: { imageBytes: inlineData?.data || '', mimeType: inlineData?.mimeType || "image/png", }, }); // Poll the operation status until the video is ready. while (!operation.done) { console.log("Waiting for video generation to complete...") await new Promise((resolve) => setTimeout(resolve, 10000)); operation = await ai.operations.getVideosOperation({ operation: operation, }); } // Download the video. const video = operation.response?.generatedVideos?.[0]?.video; if (video) { await ai.files.download({ file: video, downloadPath: "veo3_with_image_input.mp4", }); console.log(`Generated video saved to veo3_with_image_input.mp4`); } ``` {% /tab %} {% tab label="Go" filename="sample.go" %} ```go package main import ( "context" "log" "os" "time" "google.golang.org/genai" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } prompt := "Panning wide shot of a calico kitten sleeping in the sunshine" // Step 1: Generate an image with Nano Banana 2. imageResponse, err := client.Models.GenerateContent( ctx, "gemini-3.1-flash-image-preview", prompt, nil, // GenerateImagesConfig ) if err != nil { log.Fatal(err) } // Step 2: Generate video with Veo 3.1 using the image. operation, err := client.Models.GenerateVideos( ctx, "veo-3.1-generate-preview", prompt, imageResponse.GeneratedImages[0].Image, nil, // GenerateVideosConfig ) if err != nil { log.Fatal(err) } // Poll the operation status until the video is ready. for !operation.Done { log.Println("Waiting for video generation to complete...") time.Sleep(10 * time.Second) operation, _ = client.Operations.GetVideosOperation(ctx, operation, nil) } // Download the video. video := operation.Response.GeneratedVideos[0] client.Files.Download(ctx, video.Video, nil) fname := "veo3_with_image_input.mp4" _ = os.WriteFile(fname, video.Video.VideoBytes, 0644) log.Printf("Generated video saved to %s\n", fname) } ``` {% /tab %} {% tab label="Java" filename="sample.java" %} ```java import com.google.genai.Client; import com.google.genai.types.Blob; import com.google.genai.types.GenerateContentConfig; import com.google.genai.types.GenerateContentResponse; import com.google.genai.types.GenerateVideosOperation; import com.google.genai.types.GeneratedVideo; import com.google.genai.types.Image; Client client = new Client(); String prompt = "Panning wide shot of a calico kitten sleeping in the sunshine"; // Step 1: Generate an image with Nano Banana 2. GenerateContentResponse imageResponse = client.models.generateContent( "gemini-3.1-flash-image-preview", prompt, GenerateContentConfig.builder().responseModalities("IMAGE").build()); Blob inlineData = imageResponse.parts().get(0).inlineData().get(); Image image = Image.builder() .imageBytes(inlineData.data().get()) .mimeType(inlineData.mimeType().orElse("image/png")) .build(); // Step 2: Generate video with Veo 3.1 using the image. GenerateVideosOperation operation = client.models.generateVideos("veo-3.1-generate-preview", prompt, image, null); // Poll the operation status until the video is ready. while (!operation.done().orElse(false)) { System.out.println("Waiting for video generation to complete..."); Thread.sleep(10000); operation = client.operations.getVideosOperation(operation, null); } // Download the video. GeneratedVideo video = operation.response().get().generatedVideos().get().get(0); client.files.download(video, "veo3_with_image_input.mp4", null); System.out.println("Generated video saved to veo3_with_image_input.mp4"); ``` {% /tab %} {% /tabs %} ### Using reference images {% id="reference-images" %} {% callout type="note" %} This feature is available for Veo 3.1 models only. {% /callout %} Veo 3.1 now accepts up to 3 reference images to guide your generated video's content. Provide images of a person, character, or product to preserve the subject's appearance in the output video. For example, using these three images generated with [Nano Banana](/docs/image-generation) as references with a [well-written prompt](/docs/veo#use-reference-images) creates the following video: | `dress_image` | `woman_image` | `glasses_image` | | :--- | :--- | :--- | | | | | {% tabs %} {% tab label="Python" filename="sample.py" %} ```python import time from google import genai client = genai.Client() prompt = "The video opens with a medium, eye-level shot of a beautiful woman with dark hair and warm brown eyes. She wears a magnificent, high-fashion flamingo dress with layers of pink and fuchsia feathers, complemented by whimsical pink, heart-shaped sunglasses. She walks with serene confidence through the crystal-clear, shallow turquoise water of a sun-drenched lagoon. The camera slowly pulls back to a medium-wide shot, revealing the breathtaking scene as the dress's long train glides and floats gracefully on the water's surface behind her. The cinematic, dreamlike atmosphere is enhanced by the vibrant colors of the dress against the serene, minimalist landscape, capturing a moment of pure elegance and high-fashion fantasy." dress_reference = types.VideoGenerationReferenceImage( image=dress_image, # Generated separately with Nano Banana reference_type="asset" ) sunglasses_reference = types.VideoGenerationReferenceImage( image=glasses_image, # Generated separately with Nano Banana reference_type="asset" ) woman_reference = types.VideoGenerationReferenceImage( image=woman_image, # Generated separately with Nano Banana reference_type="asset" ) operation = client.models.generate_videos( model="veo-3.1-generate-preview", prompt=prompt, config=types.GenerateVideosConfig( reference_images=[dress_reference, glasses_reference, woman_reference], ), ) # Poll the operation status until the video is ready. while not operation.done: print("Waiting for video generation to complete...") time.sleep(10) operation = client.operations.get(operation) # Download the video. video = operation.response.generated_videos[0] client.files.download(file=video.video, destination="veo3.1_with_reference_images.mp4") print("Generated video saved to veo3.1_with_reference_images.mp4") ``` {% /tab %} {% tab label="JavaScript" filename="sample.js" %} ```javascript import { GoogleGenAI, VideoGenerationReferenceType } from "@google/genai"; const ai = new GoogleGenAI({}); const prompt = "The video opens with a medium, eye-level shot of a beautiful woman with dark hair and warm brown eyes. She wears a magnificent, high-fashion flamingo dress with layers of pink and fuchsia feathers, complemented by whimsical pink, heart-shaped sunglasses. She walks with serene confidence through the crystal-clear, shallow turquoise water of a sun-drenched lagoon. The camera slowly pulls back to a medium-wide shot, revealing the breathtaking scene as the dress's long train glides and floats gracefully on the water's surface behind her. The cinematic, dreamlike atmosphere is enhanced by the vibrant colors of the dress against the serene, minimalist landscape, capturing a moment of pure elegance and high-fashion fantasy."; // dressImage, glassesImage, womanImage generated separately with Nano Banana // and available as objects like { imageBytes: "...", mimeType: "image/png" } let operation = await ai.models.generateVideos({ model: "veo-3.1-generate-preview", prompt: prompt, config: { referenceImages: [ { image: dressImage, referenceType: VideoGenerationReferenceType.ASSET }, { image: glassesImage, referenceType: VideoGenerationReferenceType.ASSET }, { image: womanImage, referenceType: VideoGenerationReferenceType.ASSET }, ], }, }); // Poll the operation status until the video is ready. while (!operation.done) { console.log("Waiting for video generation to complete..."); await new Promise((resolve) => setTimeout(resolve, 10000)); operation = await ai.operations.getVideosOperation({ operation: operation, }); } // Download the video. const video = operation.response?.generatedVideos?.[0]?.video; if (video) { await ai.files.download({ file: video, downloadPath: "veo3.1_with_reference_images.mp4", }); console.log(`Generated video saved to veo3.1_with_reference_images.mp4`); } ``` {% /tab %} {% tab label="Go" filename="sample.go" %} ```go package main import ( "context" "log" "os" "time" "google.golang.org/genai" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } prompt := `The video opens with a medium, eye-level shot of a beautiful woman with dark hair and warm brown eyes. She wears a magnificent, high-fashion flamingo dress with layers of pink and fuchsia feathers, complemented by whimsical pink, heart-shaped sunglasses. She walks with serene confidence through the crystal-clear, shallow turquoise water of a sun-drenched lagoon. The camera slowly pulls back to a medium-wide shot, revealing the breathtaking scene as the dress's long train glides and floats gracefully on the water's surface behind her. The cinematic, dreamlike atmosphere is enhanced by the vibrant colors of the dress against the serene, minimalist landscape, capturing a moment of pure elegance and high-fashion fantasy.` // dressImage, glassesImage, womanImage generated separately with Nano Banana // and available as *genai.Image objects. var dressImage, glassesImage, womanImage *genai.Image dressReference := &genai.VideoGenerationReferenceImage{ Image: dressImage, ReferenceType: "asset", } sunglassesReference := &genai.VideoGenerationReferenceImage{ Image: glassesImage, ReferenceType: "asset", } womanReference := &genai.VideoGenerationReferenceImage{ Image: womanImage, ReferenceType: "asset", } operation, _ := client.Models.GenerateVideos( ctx, "veo-3.1-generate-preview", prompt, nil, // image &genai.GenerateVideosConfig{ ReferenceImages: []*genai.VideoGenerationReferenceImage{ dressReference, sunglassesReference, womanReference, }, }, ) // Poll the operation status until the video is ready. for !operation.Done { log.Println("Waiting for video generation to complete...") time.Sleep(10 * time.Second) operation, _ = client.Operations.GetVideosOperation(ctx, operation, nil) } // Download the video. video := operation.Response.GeneratedVideos[0] client.Files.Download(ctx, video.Video, nil) fname := "veo3.1_with_reference_images.mp4" _ = os.WriteFile(fname, video.Video.VideoBytes, 0644) log.Printf("Generated video saved to %s\n", fname) } ``` {% /tab %} {% tab label="REST" filename="sample.sh" %} ```shell # Note: This script uses jq to parse the JSON response. # It assumes dress_image_base64, glasses_image_base64, and woman_image_base64 # contain base64-encoded image data. # GEMINI API Base URL BASE_URL="https://generativelanguage.googleapis.com/v1beta" # Send request to generate video and capture the operation name into a variable. operation_name=$(curl -s "${BASE_URL}/models/veo-3.1-generate-preview:predictLongRunning" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -X "POST" \ -d '{ "instances": [{ "prompt": "The video opens with a medium, eye-level shot of a beautiful woman with dark hair and warm brown eyes. She wears a magnificent, high-fashion flamingo dress with layers of pink and fuchsia feathers, complemented by whimsical pink, heart-shaped sunglasses. She walks with serene confidence through the crystal-clear, shallow turquoise water of a sun-drenched lagoon. The camera slowly pulls back to a medium-wide shot, revealing the breathtaking scene as the dress'\''s long train glides and floats gracefully on the water'\''s surface behind her. The cinematic, dreamlike atmosphere is enhanced by the vibrant colors of the dress against the serene, minimalist landscape, capturing a moment of pure elegance and high-fashion fantasy.", "referenceImages": [ { "image": {"inlineData": {"mimeType": "image/png", "data": "'"$dress_image_base64"'"}}, "referenceType": "asset" }, { "image": {"inlineData": {"mimeType": "image/png", "data": "'"$glasses_image_base64"'"}}, "referenceType": "asset" }, { "image": {"inlineData": {"mimeType": "image/png", "data": "'"$woman_image_base64"'"}}, "referenceType": "asset" } ] }], }' | jq -r .name) # Poll the operation status until the video is ready while true; do # Get the full JSON status and store it in a variable. status_response=$(curl -s -H "x-goog-api-key: $GEMINI_API_KEY" "${BASE_URL}/${operation_name}") # Check the "done" field from the JSON stored in the variable. is_done=$(echo "${status_response}" | jq .done) if [ "${is_done}" = "true" ]; then # Extract the download URI from the final response. video_uri=$(echo "${status_response}" | jq -r '.response.generateVideoResponse.generatedSamples[0].video.uri') echo "Downloading video from: ${video_uri}" # Download the video using the URI and API key and follow redirects. curl -L -o veo3.1_with_reference_images.mp4 -H "x-goog-api-key: $GEMINI_API_KEY" "${video_uri}" break fi # Wait for 10 seconds before checking again. sleep 10 done ``` {% /tab %} {% /tabs %} ### Using first and last frames {% id="using-first-and-last-video-frames" %} {% callout type="note" %} This feature is available for Veo 3.1 models only {% /callout %} Veo 3.1 lets you create videos using interpolation, or specifying the first and last frames of the video. For information about writing effective text prompts for video generation, see the [Veo prompt guide](/docs/veo#use-reference-images). {% tabs %} {% tab label="Python" filename="sample.py" %} ```python import time from google import genai client = genai.Client() prompt = "A cinematic, haunting video. A ghostly woman with long white hair and a flowing dress swings gently on a rope swing beneath a massive, gnarled tree in a foggy, moonlit clearing. The fog thickens and swirls around her, and she slowly fades away, vanishing completely. The empty swing is left swaying rhythmically on its own in the eerie silence." operation = client.models.generate_videos( model="veo-3.1-generate-preview", prompt=prompt, image=first_image, # The starting frame is passed as a primary input config=types.GenerateVideosConfig( last_frame=last_image # The ending frame is passed as a generation constraint in the config ), ) # Poll the operation status until the video is ready. while not operation.done: print("Waiting for video generation to complete...") time.sleep(10) operation = client.operations.get(operation) # Download the video. video = operation.response.generated_videos[0] client.files.download(file=video.video, destination="veo3.1_with_interpolation.mp4") print("Generated video saved to veo3.1_with_interpolation.mp4") ``` {% /tab %} {% tab label="JavaScript" filename="sample.js" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); const prompt = "A cinematic, haunting video. A ghostly woman with long white hair and a flowing dress swings gently on a rope swing beneath a massive, gnarled tree in a foggy, moonlit clearing. The fog thickens and swirls around her, and she slowly fades away, vanishing completely. The empty swing is left swaying rhythmically on its own in the eerie silence."; // firstImage and lastImage generated separately with Nano Banana // and available as objects like { imageBytes: "...", mimeType: "image/png" } let operation = await ai.models.generateVideos({ model: "veo-3.1-generate-preview", prompt: prompt, image: firstImage, // The starting frame is passed as a primary input config: { lastFrame: lastImage, // The ending frame is passed as a generation constraint in the config }, }); // Poll the operation status until the video is ready. while (!operation.done) { console.log("Waiting for video generation to complete...") await new Promise((resolve) => setTimeout(resolve, 10000)); operation = await ai.operations.getVideosOperation({ operation: operation, }); } // Download the video. const video = operation.response?.generatedVideos?.[0]?.video; if (video) { await ai.files.download({ file: video, downloadPath: "veo3.1_with_interpolation.mp4", }); console.log(`Generated video saved to veo3.1_with_interpolation.mp4`); } ``` {% /tab %} {% tab label="Go" filename="sample.go" %} ```go package main import ( "context" "log" "os" "time" "google.golang.org/genai" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } prompt := `A cinematic, haunting video. A ghostly woman with long white hair and a flowing dress swings gently on a rope swing beneath a massive, gnarled tree in a foggy, moonlit clearing. The fog thickens and swirls around her, and she slowly fades away, vanishing completely. The empty swing is left swaying rhythmically on its own in the eerie silence.` // firstImage and lastImage generated separately with Nano Banana // and available as *genai.Image objects. var firstImage, lastImage *genai.Image operation, _ := client.Models.GenerateVideos( ctx, "veo-3.1-generate-preview", prompt, firstImage, // The starting frame is passed as a primary input &genai.GenerateVideosConfig{ LastFrame: lastImage, // The ending frame is passed as a generation constraint in the config }, ) // Poll the operation status until the video is ready. for !operation.Done { log.Println("Waiting for video generation to complete...") time.Sleep(10 * time.Second) operation, _ = client.Operations.GetVideosOperation(ctx, operation, nil) } // Download the video. video := operation.Response.GeneratedVideos[0] client.Files.Download(ctx, video.Video, nil) fname := "veo3.1_with_interpolation.mp4" _ = os.WriteFile(fname, video.Video.VideoBytes, 0644) log.Printf("Generated video saved to %s\n", fname) } ``` {% /tab %} {% tab label="REST" filename="sample.sh" %} ```shell # Note: This script uses jq to parse the JSON response. # It assumes first_image_base64 and last_image_base64 # contain base64-encoded image data. # GEMINI API Base URL BASE_URL="https://generativelanguage.googleapis.com/v1beta" # Send request to generate video and capture the operation name into a variable. # The starting frame is passed as a primary input # The ending frame is passed as a generation constraint in the config operation_name=$(curl -s "${BASE_URL}/models/veo-3.1-generate-preview:predictLongRunning" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -X "POST" \ -d '{ "instances": [{ "prompt": "A cinematic, haunting video. A ghostly woman with long white hair and a flowing dress swings gently on a rope swing beneath a massive, gnarled tree in a foggy, moonlit clearing. The fog thickens and swirls around her, and she slowly fades away, vanishing completely. The empty swing is left swaying rhythmically on its own in the eerie silence.", "image": {"inlineData": {"mimeType": "image/png", "data": "'"$first_image_base64"'"}}, "lastFrame": {"inlineData": {"mimeType": "image/png", "data": "'"$last_image_base64"'"}} }], }' | jq -r .name) # Poll the operation status until the video is ready while true; do # Get the full JSON status and store it in a variable. status_response=$(curl -s -H "x-goog-api-key: $GEMINI_API_KEY" "${BASE_URL}/${operation_name}") # Check the "done" field from the JSON stored in the variable. is_done=$(echo "${status_response}" | jq .done) if [ "${is_done}" = "true" ]; then # Extract the download URI from the final response. video_uri=$(echo "${status_response}" | jq -r '.response.generateVideoResponse.generatedSamples[0].video.uri') echo "Downloading video from: ${video_uri}" # Download the video using the URI and API key and follow redirects. curl -L -o veo3.1_with_interpolation.mp4 -H "x-goog-api-key: $GEMINI_API_KEY" "${video_uri}" break fi # Wait for 10 seconds before checking again. sleep 10 done ``` | `first_image` | `last_image` | veo3.1_with_interpolation.mp4 | | :--- | :--- | :--- | | | | | {% /tab %} {% /tabs %} ## Extending Veo videos {% id="extending-veo-videos" %} {% callout type="note" %} This feature is available for Veo 3.1 & Veo 3.1 Fast models only, not {% /callout %} Veo 3.1 Lite. Use Veo 3.1 to extend videos that you previously generated with Veo by 7 seconds and up to 20 times. Input video limitations: * Veo-generated videos only up to 141 seconds long. * Gemini API only supports video extensions for Veo-generated videos. * The video should come from a previous generation, like `operation.response.generated_videos[0].video` * Videos are stored for 2 days, but if a video is referenced for extension, its 2-day storage timer resets. You can only extend videos that were generated or referenced in the last two days. * Input videos are expected to have a certain length, aspect ratio, and dimensions: * Aspect ratio: 9:16 or 16:9 * Resolution: 720p * Video length: 141 seconds or less The output of the extension is a single video combining the user input video and the generated extended video for up to 148 seconds of video. This example takes the a Veo-generated video, shown here with its original prompt, and extends it using the `video` parameter and a new prompt: | Prompt | Output: butterfly_video | | :--- | :--- | | An origami butterfly flaps its wings and flies out of the french doors into the garden. | | {% tabs %} {% tab label="Python" filename="sample.py" %} ```python import time from google import genai client = genai.Client() prompt = "Track the butterfly into the garden as it lands on an orange origami flower. A fluffy white puppy runs up and gently pats the flower." operation = client.models.generate_videos( model="veo-3.1-generate-preview", video=operation.response.generated_videos[0].video, # This must be a video from a previous generation prompt=prompt, config=types.GenerateVideosConfig( number_of_videos=1, resolution="720p" ), ) # Poll the operation status until the video is ready. while not operation.done: print("Waiting for video generation to complete...") time.sleep(10) operation = client.operations.get(operation) # Download the video. video = operation.response.generated_videos[0] client.files.download(file=video.video, destination="veo3.1_extension.mp4") print("Generated video saved to veo3.1_extension.mp4") ``` {% /tab %} {% tab label="JavaScript" filename="sample.js" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); const prompt = "Track the butterfly into the garden as it lands on an orange origami flower. A fluffy white puppy runs up and gently pats the flower."; // butterflyVideo must be a video from a previous generation // available as an object like { videoBytes: "...", mimeType: "video/mp4" } let operation = await ai.models.generateVideos({ model: "veo-3.1-generate-preview", video: butterflyVideo, prompt: prompt, config: { numberOfVideos: 1, resolution: "720p", }, }); // Poll the operation status until the video is ready. while (!operation.done) { console.log("Waiting for video generation to complete...") await new Promise((resolve) => setTimeout(resolve, 10000)); operation = await ai.operations.getVideosOperation({ operation: operation, }); } // Download the video. const video = operation.response?.generatedVideos?.[0]?.video; if (video) { await ai.files.download({ file: video, downloadPath: "veo3.1_extension.mp4", }); console.log(`Generated video saved to veo3.1_extension.mp4`); } ``` {% /tab %} {% tab label="Go" filename="sample.go" %} ```go package main import ( "context" "log" "os" "time" "google.golang.org/genai" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } prompt := `Track the butterfly into the garden as it lands on an orange origami flower. A fluffy white puppy runs up and gently pats the flower.` // butterflyVideo must be a video from a previous generation // available as a *genai.Video object. var butterflyVideo *genai.Video operation, _ := client.Models.GenerateVideos( ctx, "veo-3.1-generate-preview", prompt, nil, // image butterflyVideo, &genai.GenerateVideosConfig{ NumberOfVideos: 1, Resolution: "720p", }, ) // Poll the operation status until the video is ready. for !operation.Done { log.Println("Waiting for video generation to complete...") time.Sleep(10 * time.Second) operation, _ = client.Operations.GetVideosOperation(ctx, operation, nil) } // Download the video. video := operation.Response.GeneratedVideos[0] client.Files.Download(ctx, video.Video, nil) fname := "veo3.1_extension.mp4" _ = os.WriteFile(fname, video.Video.VideoBytes, 0644) log.Printf("Generated video saved to %s\n", fname) } ``` {% /tab %} {% tab label="REST" filename="sample.sh" %} ```shell # Note: This script uses jq to parse the JSON response. # It assumes butterfly_video_base64 contains base64-encoded # video data from a previous generation. # GEMINI API Base URL BASE_URL="https://generativelanguage.googleapis.com/v1beta" # Send request to generate video and capture the operation name into a variable. operation_name=$(curl -s "${BASE_URL}/models/veo-3.1-generate-preview:predictLongRunning" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -X "POST" \ -d '{ "instances": [{ "prompt": "Track the butterfly into the garden as it lands on an orange origami flower. A fluffy white puppy runs up and gently pats the flower.", "video": {"inlineData": {"mimeType": "video/mp4", "data": "'"$butterfly_video_base64"'"}} }], "parameters": { "numberOfVideos": 1, "resolution": "720p" } }' | jq -r .name) # Poll the operation status until the video is ready while true; do # Get the full JSON status and store it in a variable. status_response=$(curl -s -H "x-goog-api-key: $GEMINI_API_KEY" "${BASE_URL}/${operation_name}") # Check the "done" field from the JSON stored in the variable. is_done=$(echo "${status_response}" | jq .done) if [ "${is_done}" = "true" ]; then # Extract the download URI from the final response. video_uri=$(echo "${status_response}" | jq -r '.response.generateVideoResponse.generatedSamples[0].video.uri') echo "Downloading video from: ${video_uri}" # Download the video using the URI and API key and follow redirects. curl -L -o veo3.1_extension.mp4 -H "x-goog-api-key: $GEMINI_API_KEY" "${video_uri}" break fi # Wait for 10 seconds before checking again. sleep 10 done ``` For information about writing effective text prompts for video generation, see the [Veo prompt guide](/docs/veo#extend-prompt). {% /tab %} {% /tabs %} ## Handling asynchronous operations {% id="handling-asynchronous-operations" %} Video generation is a computationally intensive task. When you send a request to the API, it starts a long-running job and immediately returns an `operation` object. You must then poll until the video is ready, which is indicated by the `done` status being true. The core of this process is a polling loop, which periodically checks the job's status. {% tabs %} {% tab label="Python" filename="sample.py" %} ```python import time from google import genai from google.genai import types client = genai.Client() # After starting the job, you get an operation object. operation = client.models.generate_videos( model="veo-3.1-generate-preview", prompt="A cinematic shot of a majestic lion in the savannah.", ) # Alternatively, you can use operation.name to get the operation. operation = types.GenerateVideosOperation(name=operation.name) # This loop checks the job status every 10 seconds. while not operation.done: time.sleep(10) # Refresh the operation object to get the latest status. operation = client.operations.get(operation) # Once done, the result is in operation.response. # ... process and download your video ... ``` {% /tab %} {% tab label="JavaScript" filename="sample.js" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); // After starting the job, you get an operation object. let operation = await ai.models.generateVideos({ model: "veo-3.1-generate-preview", prompt: "A cinematic shot of a majestic lion in the savannah.", }); // Alternatively, you can use operation.name to get the operation. // operation = types.GenerateVideosOperation(name=operation.name) // This loop checks the job status every 10 seconds. while (!operation.done) { await new Promise((resolve) => setTimeout(resolve, 1000)); // Refresh the operation object to get the latest status. operation = await ai.operations.getVideosOperation({ operation }); } // Once done, the result is in operation.response. // ... process and download your video ... ``` {% /tab %} {% tab label="Go" filename="sample.go" %} ```go package main import ( "context" "log" "time" "google.golang.org/genai" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } // After starting the job, you get an operation object. operation, _ := client.Models.GenerateVideos( ctx, "veo-3.1-generate-preview", "A cinematic shot of a majestic lion in the savannah.", nil, nil, ) // This loop checks the job status every 10 seconds. for !operation.Done { time.Sleep(10 * time.Second) // Refresh the operation object to get the latest status. operation, _ = client.Operations.GetVideosOperation(ctx, operation, nil) } // Once done, the result is in operation.Response. // ... process and download your video ... } ``` {% /tab %} {% tab label="Java" filename="sample.java" %} ```java import com.google.genai.Client; import com.google.genai.types.GenerateVideosOperation; Client client = new Client(); // After starting the job, you get an operation object. GenerateVideosOperation operation = client.models.generateVideos( "veo-3.1-generate-preview", "A cinematic shot of a majestic lion in the savannah.", null, null); // Alternatively, you can use operation.name to construct the operation. operation = GenerateVideosOperation.builder().name(operation.name().get()).build(); // This loop checks the job status every 10 seconds. while (!operation.done().orElse(false)) { Thread.sleep(10000); // Refresh the operation object to get the latest status. operation = client.operations.getVideosOperation(operation, null); } // Once done, the result is in operation.response(). // ... process and download your video ... ``` {% /tab %} {% tab label="REST" filename="sample.sh" %} ```shell # Note: This script uses jq to parse the JSON response. # GEMINI API Base URL BASE_URL="https://generativelanguage.googleapis.com/v1beta" # Send request to generate video and capture the operation name into a variable. operation_name=$(curl -s "${BASE_URL}/models/veo-3.1-generate-preview:predictLongRunning" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -X "POST" \ -d '{ "instances": [{ "prompt": "A cinematic shot of a majestic lion in the savannah." } ] }' | jq -r .name) # This loop checks the job status every 10 seconds. while true; do # Get the full JSON status and store it in a variable. status_response=$(curl -s -H "x-goog-api-key: $GEMINI_API_KEY" "${BASE_URL}/${operation_name}") # Check the "done" field from the JSON stored in the variable. is_done=$(echo "${status_response}" | jq .done) if [ "${is_done}" = "true" ]; then # Once done, the result is in status_response. # ... process and download your video ... echo "Video generation complete." break fi # Wait for 10 seconds before checking again. echo "Waiting for video generation to complete..." sleep 10 done ``` {% /tab %} {% /tabs %} ## Veo API parameters and specifications {% id="veo-model-parameters" %} These are the parameters you can set in your API request to control the video generation process. | Parameter | Veo 3.1 & Veo 3.1 Fast | Veo 3.1 Lite | Veo 3 & Veo 3 Fast | | :--- | :--- | :--- | :--- | | Instances | | | | | `prompt`: The text description for the video. Supports audio cues. | `string` | `string` | `string` | | `image`: An initial image to animate. | `Image` object | `Image` object | `Image` object | | `lastFrame`: The final image for an interpolation video to transition. Must be used in combination with the `image` parameter. | `Image` object | `Image` object | `Image` object | | `referenceImages`: Up to three images to be used as style and content references. | `VideoGenerationReferenceImage` object | `n/a` object | n/a | | `video`: Video to be used for video extension. | `Video` object from a previous generation | n/a | n/a | | Parameters | | | | | `aspectRatio`: The video's aspect ratio. | `"16:9"` (default), `"9:16"` | `"16:9"` (default), `"9:16"` | `"16:9"` (default), `"9:16"` | | `durationSeconds`: Length of the generated video. | `"4"`, `"6"`, `"8"`. Must be "8" when using extension, reference images or with 1080p and 4k resolutions | `"4"`, `"6"`, `"8"`. Must be "8" when using reference images or with 1080p | `"4"`, `"6"`, `"8"`. Must be "8" when using extension, reference images or with 1080p and 4k resolutions | | `personGeneration`: Controls the generation of people. (See [Limitations](/docs/veo#limitations) for region restrictions) | Text-to-video & Extension: `"allow_all"` only Image-to-video, Interpolation, & Reference images: `"allow_adult"` only | Text-to-video: `"allow_all"` only Image-to-video, Interpolation, & Reference images: `"allow_adult"` only | Text-to-video: `"allow_all"` only Image-to-video: `"allow_adult"` only | | `resolution`: The video's resolution. | `"720p"` (default), `"1080p"` (only supports 8s duration), `"4k"` (only supports 8s duration) `"720p"` only for extension | `"720p"` (default), `"1080p"` (only supports 8s duration) | `"720p"` (default), `"1080p"` (only supports 8s duration), `"4k"` (only supports 8s duration) `"720p"` only for extension | Note that the `seed` parameter is also available for Veo 3 models. It doesn't guarantee determinism, but slightly improves it. ## Model features {% id="model-features" %} | Feature | Veo 3.1 & Veo 3.1 Fast | Veo 3.1 Lite | Veo 3 & Veo 3 Fast | | :--- | :--- | :--- | :--- | | **Audio:** Natively generates audio with video. | ✔️ Always on | ✔️ Always on | ✔️ Always on | | **Input modalities:** The type of input used for generation. | Text-to-Video, Image-to-Video, Video-to-Video | Text-to-Video, Image-to-Video | Text-to-Video, Image-to-Video | | **Resolution:** The output resolution of the video. | 720p, 1080p (8s length only), 4k (8s length only) 720p only when using video extension. | 720p, 1080p (8s length only) | 720p & 1080p (16:9 only) | | **Frame rate:** The output frame rate of the video. | 24fps | 24fps | 24fps | | **Video duration:** Length of the generated video. | 8 seconds, 6 seconds, 4 seconds 8 seconds only if 1080p or 4k or using reference images | 8 seconds, 6 seconds, 4 seconds 8 seconds only if 1080p or using reference images | 8 seconds | | **Videos per request:** Number of videos generated per request. | 1 | 1 | 1 | | **Status:** Model availability | [Preview](/docs/models#preview) | [Preview](/docs/models#preview) | [Stable](/docs/models#stable) | ## Limitations {% id="limitations" %} * **Multi-video prompting:** Referencing or reasoning across multiple videos is not currently supported. Attempting multi-video prompting may result in degraded model performance or unexpected outputs. * **Language support:** English (EN) is fully supported, but other languages have not been evaluated, so they may work but results can vary. * **Request latency:** Min: 11 seconds; Max: 6 minutes (during peak hours). * **Regional limitations:** In EU, UK, CH, MENA locations, `allow_adult` is the only allowed value for `personGeneration`. * **Video retention:** Generated videos are stored on the server for 2 days, after which they are removed. To save a local copy, you must download your video within 2 days of generation. Extended videos are treated as newly generated videos. * **Watermarking:** Videos created by Veo are watermarked using [SynthID](https://deepmind.google/technologies/synthid/), our tool for watermarking and identifying AI-generated content. Videos can be verified using the [SynthID](https://deepmind.google/science/synthid/) verification platform. * **Safety:** Generated videos are passed through safety filters and memorization checking processes that help mitigate privacy, copyright and bias risks. * **Audio error:** Veo 3.1 will sometimes block a video from generating because of safety filters or other processing issues with the audio. You will not be charged if your video is blocked from generating. ## Veo prompt guide {% id="prompt-guide" %} This section contains examples of videos you can create using Veo, and shows you how to modify prompts to produce distinct results. ### Safety filters {% id="safety-filters" %} Veo applies safety filters across Gemini to help ensure that generated videos and uploaded photos don't contain offensive content. Prompts that violate our [terms and guidelines](/docs/usage-policies#abuse-monitoring) are blocked. ### Prompt writing basics {% id="basics" %} Good prompts are descriptive and clear. To get the most out of Veo, start with identifying your core idea, refine your idea by adding keywords and modifiers, and incorporate video-specific terminology into your prompts. The following elements should be included in your prompt: * **Subject**: The object, person, animal, or scenery that you want in your video, such as *cityscape*, *nature*, *vehicles*, or *puppies*. * **Action**: What the subject is doing (for example, *walking*, *running*, or *turning their head*). * **Style**: Specify creative direction using specific film style keywords, such as *sci-fi*, *horror film*, *film noir*, or animated styles like *cartoon*. * **Camera positioning and motion**: \[Optional\] Control the camera's location and movement using terms like *aerial view*, *eye-level*, *top-down shot*, *dolly shot*, or *worms eye*. * **Composition**: \[Optional\] How the shot is framed, such as *wide shot*, *close-up*, *single-shot* or *two-shot*. * **Focus and lens effects**: \[Optional\] Use terms like *shallow focus*, *deep focus*, *soft focus*, *macro lens*, and *wide-angle lens* to achieve specific visual effects. * **Ambiance**: \[Optional\] How the color and light contribute to the scene, such as *blue tones*, *night*, or *warm tones*. #### More tips for writing prompts {% id="more-tips" %} * **Use descriptive language**: Use adjectives and adverbs to paint a clear picture for Veo. * **Enhance the facial details**: Specify facial details as a focus of the photo like using the word *portrait* in the prompt. *For more comprehensive prompting strategies, visit [Introduction to prompt design](/docs/prompting-strategies).* ### Prompting for audio {% id="audio" %} You can provide Veo with cues for sound effects, ambient noise, and dialogue. The model captures the nuance of these cues to generate a synchronized soundtrack. * **Dialogue:** Use quotes for specific speech. (Example: "This must be the key," he murmured.) * **Sound Effects (SFX):** Explicitly describe sounds. (Example: tires screeching loudly, engine roaring.) * **Ambient Noise:** Describe the environment's soundscape. (Example: A faint, eerie hum resonates in the background.) These videos demonstrate prompting Veo 3's audio generation with increasing levels of detail. | Prompt | Generated output | | :--- | :--- | | **More detail (Dialogue and ambience)** A wide shot of a misty Pacific Northwest forest. Two exhausted hikers, a man and a woman, push through ferns when the man stops abruptly, staring at a tree. Close-up: Fresh, deep claw marks are gouged into the tree's bark. Man: (Hand on his hunting knife) "That's no ordinary bear." Woman: (Voice tight with fear, scanning the woods) "Then what is it?" A rough bark, snapping twigs, footsteps on the damp earth. A lone bird chirps. | | | **Less detail (Dialogue)** Paper Cut-Out Animation. New Librarian: "Where do you keep the forbidden books?" Old Curator: "We don't. They keep us." | |

Try out these prompts yourself to hear the audio! {% button href="https://deepmind.google/models/veo/" variant="primary" %}Try Veo{% /button %}

### Prompting with reference images {% id="use-reference-images" %} You can use one or more images as inputs to guide your generated videos, using Veo's [image-to-video](/docs/veo#generate-from-images) capabilities. Veo uses the input image as the initial frame. Select an image closest to what you envision as the first scene of your video to animate everyday objects, bring drawings and paintings to life, and add movement and sound to nature scenes. | Prompt | Generated output | | :--- | :--- | | **Input image (Generated by Nano Banana)** A hyperrealistic macro photo of tiny, miniature surfers riding ocean waves inside a rustic stone bathroom sink. A vintage brass faucet is running, creating the perpetual surf. Surreal, whimsical, bright natural lighting. | | | **Output Video (Generated by Veo 3.1)** A surreal, cinematic macro video. Tiny surfers ride perpetual, rolling waves inside a stone bathroom sink. A running vintage brass faucet generates the endless surf. The camera slowly pans across the whimsical, sunlit scene as the miniature figures expertly carve the turquoise water. | | Veo 3.1 lets you [reference images](/docs/veo#reference-images) or ingredients to direct your generated video's content. Provide up to three asset images of a single person, character, or product. Veo preserves the subject's appearance in the output video. | Prompt | Generated output | | :--- | :--- | | **Reference image (Generated by Nano Banana)** A deep sea angler fish lurks in the deep dark water, teeth bared and bait glowing. | | | **Reference image (Generated by Nano Banana)** A pink child's princess costume complete with a wand and tiara, on a plain product background. | | | **Output Video (Generated by Veo 3.1)** Create a silly cartoon version of the fish wearing the costume, swimming and waving the wand around. | | Using Veo 3.1, you can also generate videos by specifying the [first and last frames](/docs/veo#using-first-and-last-video-frames) of the video. | Prompt | Generated output | | :--- | :--- | | **First image (Generated by Nano Banana)** A high quality photorealistic front image of a ginger cat driving a red convertible racing car on the French riviera coast. | | | **Last image (Generated by Nano Banana)** Show what happens when the car takes off from a cliff. | | | **Output Video (Generated by Veo 3.1)** Optional | | This feature gives you precise control over your shot's composition by letting you define the starting and ending frame. Upload an image or use a frame from a previous video generation to make sure your scene begins and concludes exactly as you envision it. ### Prompting for extension {% id="extend-prompt" %} To [extend](/docs/veo#extending-veo-videos) your Veo-generated video with Veo 3.1 (not available for Veo 3.1 Lite), use the video as an input along with an optional text prompt. Extend finalizes the final second or 24 frames of your video and continues the action. Note that voice is not able to be effectively extended if it's not present in the last 1 second of video. | Prompt | Generated output | | :--- | :--- | | **Input video (Generated by Veo 3.1)** The paraglider takes off from the top of the mountain and starts gliding down the mountains overlooking the flower covered valleys below. | | | **Output Video (Generated by Veo 3.1)** Extend this video with the paraglider slowly descending. | | ### Example prompts and output {% id="examples" %} This section presents several prompts, highlighting how descriptive details can elevate the outcome of each video. #### Icicles {% id="icicles" %} This video demonstrates how you can use the elements of [prompt writing basics](/docs/veo#basics) in your prompt. | Prompt | Generated output | | :--- | :--- | | Close up shot (composition) of melting icicles (subject) on a frozen rock wall (context) with cool blue tones (ambiance), zoomed in (camera motion) maintaining close-up detail of water drips (action). | | #### Man on the phone {% id="man-on-the-phone" %} These videos demonstrate how you can revise your prompt with increasingly specific details to get Veo to refine the output to your liking. | Prompt | Generated output | | :--- | :--- | | **Less detail** The camera dollies to show a close up of a desperate man in a green trench coat. He's making a call on a rotary-style wall phone with a green neon light. It looks like a movie scene. | | | **More detail** A close-up cinematic shot follows a desperate man in a weathered green trench coat as he dials a rotary phone mounted on a gritty brick wall, bathed in the eerie glow of a green neon sign. The camera dollies in, revealing the tension in his jaw and the desperation etched on his face as he struggles to make the call. The shallow depth of field focuses on his furrowed brow and the black rotary phone, blurring the background into a sea of neon colors and indistinct shadows, creating a sense of urgency and isolation. | | #### Snow leopard {% id="snow-leopard" %} | Prompt | Generated output | | :--- | :--- | | **Simple prompt:** A cute creature with snow leopard-like fur is walking in winter forest, 3D cartoon style render. | | | **Detailed prompt:** Create a short 3D animated scene in a joyful cartoon style. A cute creature with snow leopard-like fur, large expressive eyes, and a friendly, rounded form happily prances through a whimsical winter forest. The scene should feature rounded, snow-covered trees, gentle falling snowflakes, and warm sunlight filtering through the branches. The creature's bouncy movements and wide smile should convey pure delight. Aim for an upbeat, heartwarming tone with bright, cheerful colors and playful animation. | | ### Examples by writing elements {% id="element-examples" %} These examples show you how to refine your prompts by each basic element. #### Subject and context {% id="subject" %} Specify the main focus (subject) and the background or environment (context). | Prompt | Generated output | | :--- | :--- | | An architectural rendering of a white concrete apartment building with flowing organic shapes, seamlessly blending with lush greenery and futuristic elements | | | A satellite floating through outer space with the moon and some stars in the background. | | #### Action {% id="action" %} Specify what the subject is doing (e.g., walking, running, or turning their head). | Prompt | Generated output | | :--- | :--- | | A wide shot of a woman walking along the beach, looking content and relaxed towards the horizon at sunset. | | #### Style {% id="style" %} Add keywords to steer the generation toward a specific aesthetic (e.g., surreal, vintage, futuristic, film noir). | Prompt | Generated output | | :--- | :--- | | Film noir style, man and woman walk on the street, mystery, cinematic, black and white. | | #### Camera motion and composition {% id="camera-motion" %} Specify how the camera moves (POV shot, aerial view, tracking drone view) and how the shot is framed (wide shot, close-up, low angle). | Prompt | Generated output | | :--- | :--- | | A POV shot from a vintage car driving in the rain, Canada at night, cinematic. | | | Extreme close-up of a an eye with city reflected in it. | | #### Ambiance {% id="ambiance" %} Color palettes and lighting influence the mood. Try terms like "muted orange warm tones," "natural light," "sunrise," or "cool blue tones." | Prompt | Generated output | | :--- | :--- | | A close-up of a girl holding adorable golden retriever puppy in the park, sunlight. | | | Cinematic close-up shot of a sad woman riding a bus in the rain, cool blue tones, sad mood. | | ### Aspect ratios {% id="aspect-ratios" %} Veo lets you specify the aspect ratio for your video. | Prompt | Generated output | | :--- | :--- | | **Widescreen (16:9)** Create a video with a tracking drone view of a man driving a red convertible car in Palm Springs, 1970s, warm sunlight, long shadows. | | | **Portrait (9:16)** Create a video highlighting the smooth motion of a majestic Hawaiian waterfall within a lush rainforest. Focus on realistic water flow, detailed foliage, and natural lighting to convey tranquility. Capture the rushing water, misty atmosphere, and dappled sunlight filtering through the dense canopy. Use smooth, cinematic camera movements to showcase the waterfall and its surroundings. Aim for a peaceful, realistic tone, transporting the viewer to the serene beauty of the Hawaiian rainforest. | | ## Model versions {% id="model-versions" %} Check out the [Pricing](/docs/pricing) page and [Rate limits](https://aistudio.google.com/rate-limit) for more Veo model-specific usage details. {% partial file="googledevai/en/gemini-api/docs/models/_includes/_veo.md" /%} Veo Fast versions allow developers to create videos with sound while maintaining high quality and optimizing for speed and business use cases. They're ideal for backend services that programmatically generate ads, tools for rapid A/B testing of creative concepts, or apps that need to quickly produce social media content. ## What's next {% id="whats-next" %} * Get started with the Veo 3.1 API by experimenting in the [Veo Quickstart Colab](https://colab.research.google.com/github/google-gemini/cookbook/blob/main/quickstarts/Get_started_Veo.ipynb) and the [Veo 3.1 applet](https://aistudio.google.com/apps/bundled/veo_studio). * Learn how to write even better prompts with our [Introduction to prompt design](/docs/prompting-strategies). # Generate and edit videos with Gemini Omni Flash Source: https://aistudio.google.com/docs/omni Description: Get started with Gemini Omni Flash for fast, conversational video generation and editing using the Interactions API. Gemini Omni Flash (`gemini-omni-1.1-flash`) is a high-performance multimodal model designed for high-speed video generation, editing, and cinematic control. Gemini Omni is built on the following core capabilities that distinguish it from previous video models: * **Native multimodality:** it processes text, image, audio, and video simultaneously, giving you more cohesive, consistent, and controllable output. * **Conversational editing:** enabled by the [Interactions API](/docs/interactions-overview), it lets you iteratively refine and edit your videos through natural language conversation. Describe what you want to change, and the model applies the edit while preserving the parts of the video you want to keep. * **World knowledge:** Gemini Omni combines an understanding of physics with Gemini's knowledge of history, science, and cultural context, bridging the gap from photorealism to meaningful storytelling. ## Text to video generation {% id="text-to-video-generation" %} Generate a video from a text prompt. The model generates a video with audio based on your text description. Write prompts with details like scene description, camera movement, lighting and mood for best results. {% tabs %} {% tab label="Python" %} ```python import base64 from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-omni-1.1-flash", input="A marble rolling fast on a chain reaction style track, continuous smooth shot." ) with open("marble.mp4", "wb") as f: f.write(base64.b64decode(interaction.output_video.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from '@google/genai'; import * as fs from 'fs'; const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: 'gemini-omni-1.1-flash', input: 'A marble rolling fast on a chain reaction style track, continuous smooth shot.', }); if (interaction.output_video?.data) { fs.writeFileSync('marble.mp4', Buffer.from(interaction.output_video.data, 'base64')); } ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Base64; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-omni-1.1-flash")) .input( InteractionsInput.of( "A marble rolling fast on a chain reaction style track, continuous smooth shot.")) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.outputVideo().isPresent() && interaction.outputVideo().get().data().isPresent()) { byte[] videoBytes = Base64.getDecoder().decode(interaction.outputVideo().get().data().get()); Files.write(Paths.get("marble.mp4"), videoBytes); } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-omni-1.1-flash"), Input: interactions.NewInteractionsInput( "A marble rolling fast on a chain reaction style track, continuous smooth shot.", ), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputVideo != nil && res.Interaction.OutputVideo.Data != nil { videoBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputVideo.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("marble.mp4", videoBytes, 0644); err != nil { log.Fatal(err) } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions?key=$API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gemini-omni-1.1-flash", "input": "A marble rolling fast on a chain reaction style track, continuous smooth shot." }' ``` {% /tab %} {% /tabs %} {% video id="6DRkXO9nM7g" title="Watch video (Reference)" /%} ### REST response schema {% id="rest-response-schema" %} The convenience field `interaction.output_video` is **SDK-only**. Get the video output from the `steps` array when using the REST API directly. **Raw REST JSON structure:** ```json { "steps": [ { "type": "user_input", "content": [{"type": "text", "text": "..."}] }, { "type": "thought", "content": [{"text": "...", "type": "thought"}] }, { "type": "model_output", "content": [ { "type": "video", "mime_type": "video/mp4", "data": "AAAAIGZ0eXBpc29t..." // Base64 encoded video data } ] } ], "id": "v1_...", "status": "completed", "model": "gemini-omni-1.1-flash", "object": "interaction" } ``` ### Control aspect ratio {% id="control-aspect-ratio" %} Set the `aspect_ratio` to `"9:16"` to create portrait videos. Landscape (16:9) is the default. {% tabs %} {% tab label="Python" %} ```python import base64 from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-omni-1.1-flash", input="A futuristic city with neon lights and flying cars, cyberpunk style", response_format={ "type": "video", # optional "aspect_ratio": "9:16" # Supported values: "9:16", "16:9" } ) with open("example.mp4", "wb") as f: f.write(base64.b64decode(interaction.output_video.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from '@google/genai'; import * as fs from 'fs'; const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: 'gemini-omni-1.1-flash', input: 'A futuristic city with neon lights and flying cars, cyberpunk style', response_format: { type: 'video', // optional aspect_ratio: '9:16' // Supported values: '9:16', '16:9' }, }); if (interaction.output_video?.data) { fs.writeFileSync('example.mp4', Buffer.from(interaction.output_video.data, 'base64')); } ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.CreateModelInteractionResponseFormat; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ResponseFormat; import com.google.genai.gaos.models.interactions.VideoResponseFormat; import com.google.genai.gaos.models.interactions.VideoResponseFormatAspectRatio; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Base64; Client client = new Client(); VideoResponseFormat videoFormat = VideoResponseFormat.builder() .aspectRatio(VideoResponseFormatAspectRatio.of("9:16")) .build(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-omni-1.1-flash")) .input( InteractionsInput.of( "A futuristic city with neon lights and flying cars, cyberpunk style")) .responseFormat(CreateModelInteractionResponseFormat.of(ResponseFormat.of(videoFormat))) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.outputVideo().isPresent() && interaction.outputVideo().get().data().isPresent()) { byte[] videoBytes = Base64.getDecoder().decode(interaction.outputVideo().get().data().get()); Files.write(Paths.get("example.mp4"), videoBytes); } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } videoFormat := interactions.VideoResponseFormat{ AspectRatio: interactions.VideoResponseFormatAspectRatioNineHundredAndSixteen.ToPointer(), } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-omni-1.1-flash"), Input: interactions.NewInteractionsInput( "A futuristic city with neon lights and flying cars, cyberpunk style", ), ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat( interactions.NewResponseFormat(videoFormat), )), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputVideo != nil && res.Interaction.OutputVideo.Data != nil { videoBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputVideo.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("example.mp4", videoBytes, 0644); err != nil { log.Fatal(err) } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions?key=$API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gemini-omni-1.1-flash", "input": "A futuristic city with neon lights and flying cars, cyberpunk style", "response_format": { "type": "video", "aspect_ratio": "9:16" } }' ``` {% /tab %} {% /tabs %} ### Output resolution {% id="output-resolution" %} Control the output resolution of your generated video using the `resolution` parameter in `response_format`. The default resolution is 720p. | Value | Description | | :---- | :---------- | | `360p` | 360p output resolution | | `720p` | 720p output resolution (default) | | `1080p` | 1080p output (upscaled) | | `4k` | 4K output (upscaled) | {% tabs %} {% tab label="Python" %} ```python import base64 from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-omni-1.1-flash", input="A drone shot of a mountain landscape at sunrise.", response_format={ "type": "video", "resolution": "1080p", }, ) with open("hires.mp4", "wb") as f: f.write(base64.b64decode(interaction.output_video.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from '@google/genai'; import * as fs from 'fs'; const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: 'gemini-omni-1.1-flash', input: 'A drone shot of a mountain landscape at sunrise.', response_format: { type: 'video', resolution: '1080p', }, }); if (interaction.output_video?.data) { fs.writeFileSync('hires.mp4', Buffer.from(interaction.output_video.data, 'base64')); } ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.CreateModelInteractionResponseFormat; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.Resolution; import com.google.genai.gaos.models.interactions.ResponseFormat; import com.google.genai.gaos.models.interactions.VideoResponseFormat; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Base64; Client client = new Client(); VideoResponseFormat videoFormat = VideoResponseFormat.builder() .resolution(Resolution.of("1080p")) .build(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-omni-1.1-flash")) .input(InteractionsInput.of("A drone shot of a mountain landscape at sunrise.")) .responseFormat(CreateModelInteractionResponseFormat.of(ResponseFormat.of(videoFormat))) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.outputVideo().isPresent() && interaction.outputVideo().get().data().isPresent()) { byte[] videoBytes = Base64.getDecoder().decode(interaction.outputVideo().get().data().get()); Files.write(Paths.get("hires.mp4"), videoBytes); } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } videoFormat := interactions.VideoResponseFormat{ Resolution: interactions.ResolutionOneThousandAndEightyp.ToPointer(), } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-omni-1.1-flash"), Input: interactions.NewInteractionsInput("A drone shot of a mountain landscape at sunrise."), ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat( interactions.NewResponseFormat(videoFormat), )), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputVideo != nil && res.Interaction.OutputVideo.Data != nil { videoBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputVideo.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("hires.mp4", videoBytes, 0644); err != nil { log.Fatal(err) } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions?key=$API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gemini-omni-1.1-flash", "input": "A drone shot of a mountain landscape at sunrise.", "response_format": { "type": "video", "resolution": "1080p" } }' ``` {% /tab %} {% /tabs %} {% video src="https://storage.googleapis.com/generativeai-downloads/videos/omni_misty_mountains_1080p.mp4" type="video/mp4" /%} ## Image to video generation {% id="image-to-video-generation" %} You can provide a reference image with your text prompt. Depending on your prompt, the model will decide how to use the image. This is useful for bringing product shots, illustrations, or photographs to life. The following example shows how to use the reference image of a drawing of a fish jumping out of water: ![Drawing of a fish jumping out of water](/googledevai/static/gemini-api/docs/images/fish-jumping-inputimage.png) With the following prompt: ```none turn this into realistic footage, using the drawing only as a guide for movement, do not show the drawing in the final video ``` To generate a realistic video of the drawing. {% tabs %} {% tab label="Python" %} ```python import base64 from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-omni-1.1-flash", input=[ {"type": "image", "data": base64_image, "mime_type": "image/jpeg"}, {"type": "text", "text": "turn this into realistic footage, using the drawing only as a guide for movement, do not show the drawing in the final video"} ], ) with open("clownfish.mp4", "wb") as f: f.write(base64.b64decode(interaction.output_video.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from '@google/genai'; import * as fs from 'fs'; const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: 'gemini-omni-1.1-flash', input: [ { type: 'image', data: base64Image, mime_type: 'image/jpeg' }, { type: 'text', text: 'turn this into realistic footage, using the drawing only as a guide for movement, do not show the drawing in the final video' } ] }); if (interaction.output_video?.data) { fs.writeFileSync('clownfish.mp4', Buffer.from(interaction.output_video.data, 'base64')); } ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.ImageContentMimeType; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; import java.util.List; Client client = new Client(); byte[] imageBytes = Files.readAllBytes(Paths.get("drawing.jpg")); String base64Image = Base64.getEncoder().encodeToString(imageBytes); Content imageContent = ImageContent.builder() .data(base64Image) .mimeType(ImageContentMimeType.IMAGE_JPEG) .build(); Content textContent = TextContent.builder() .text( "turn this into realistic footage, using the drawing only as a guide for movement, do not show the drawing in the final video") .build(); List contents = Arrays.asList(imageContent, textContent); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-omni-1.1-flash")) .input(InteractionsInput.ofContent(contents)) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.outputVideo().isPresent() && interaction.outputVideo().get().data().isPresent()) { byte[] videoBytes = Base64.getDecoder().decode(interaction.outputVideo().get().data().get()); Files.write(Paths.get("clownfish.mp4"), videoBytes); } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } imageBytes, err := os.ReadFile("drawing.jpg") if err != nil { log.Fatal(err) } base64Image := base64.StdEncoding.EncodeToString(imageBytes) contents := []interactions.Content{ interactions.NewContent(interactions.ImageContent{ Data: genai.Ptr(base64Image), MimeType: interactions.ImageContentMimeTypeImageJpeg.ToPointer(), }), interactions.NewContent(interactions.TextContent{ Text: "turn this into realistic footage, using the drawing only as a guide for movement, do not show the drawing in the final video", }), } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-omni-1.1-flash"), Input: interactions.NewInteractionsInput(contents), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputVideo != nil && res.Interaction.OutputVideo.Data != nil { videoBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputVideo.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("clownfish.mp4", videoBytes, 0644); err != nil { log.Fatal(err) } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions?key=$API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gemini-omni-1.1-flash", "input": [ {"type": "image", "data": "'"$BASE64_IMAGE"'", "mime_type": "image/jpeg"}, {"type": "text", "text": "turn this into realistic footage, using the drawing only as a guide for movement, do not show the drawing in the final video"} ] }' ``` {% /tab %} {% /tabs %} {% video id="zTNIIZ0X7mA" title="Watch video (Reference)" /%} {% callout type="note" %} For best results with image-to-video, use high-resolution images and provide specific motion descriptions. Vague prompts like "make it move" produce less compelling results than detailed descriptions of the camera movement, subject motion, and environmental effects. {% /callout %} ### First and last frame interpolation {% id="first-and-last-frame-interpolation" %} Gemini Omni Flash supports video interpolation, allowing you to generate a video that transitions smoothly between a starting image (first frame) and an ending image (last frame). Provide two images in the `input` list and describe the desired transition in your prompt. The model will animate the scene from the first frame to the ending frame. {% tabs %} {% tab label="Python" %} ```python import base64 from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-omni-1.1-flash", input=[ {"type": "image", "data": first_frame_b64, "mime_type": "image/jpeg"}, {"type": "image", "data": last_frame_b64, "mime_type": "image/jpeg"}, {"type": "text", "text": "A smooth cinematic transition from a lush green forest at sunrise to a snowy forest under a starry night sky."} ], ) with open("interpolation.mp4", "wb") as f: f.write(base64.b64decode(interaction.output_video.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from '@google/genai'; import * as fs from 'fs'; const ai = new GoogleGenAI({}); const firstFrameB64 = '...'; const lastFrameB64 = '...'; const interaction = await ai.interactions.create({ model: 'gemini-omni-1.1-flash', input: [ { type: 'image', data: firstFrameB64, mime_type: 'image/jpeg' }, { type: 'image', data: lastFrameB64, mime_type: 'image/jpeg' }, { type: 'text', text: 'A smooth cinematic transition from a lush green forest at sunrise to a snowy forest under a starry night sky.' } ] }); if (interaction.output_video?.data) { fs.writeFileSync('interpolation.mp4', Buffer.from(interaction.output_video.data, 'base64')); } ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.ImageContentMimeType; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; import java.util.List; Client client = new Client(); String firstFrameB64 = Base64.getEncoder().encodeToString(Files.readAllBytes(Paths.get("first_frame.jpg"))); String lastFrameB64 = Base64.getEncoder().encodeToString(Files.readAllBytes(Paths.get("last_frame.jpg"))); Content firstFrame = ImageContent.builder() .data(firstFrameB64) .mimeType(ImageContentMimeType.IMAGE_JPEG) .build(); Content lastFrame = ImageContent.builder() .data(lastFrameB64) .mimeType(ImageContentMimeType.IMAGE_JPEG) .build(); Content prompt = TextContent.builder() .text( "A smooth cinematic transition from a lush green forest at sunrise to a snowy forest under a starry night sky.") .build(); List contents = Arrays.asList(firstFrame, lastFrame, prompt); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-omni-1.1-flash")) .input(InteractionsInput.ofContent(contents)) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.outputVideo().isPresent() && interaction.outputVideo().get().data().isPresent()) { byte[] videoBytes = Base64.getDecoder().decode(interaction.outputVideo().get().data().get()); Files.write(Paths.get("interpolation.mp4"), videoBytes); } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } firstBytes, err := os.ReadFile("first_frame.jpg") if err != nil { log.Fatal(err) } lastBytes, err := os.ReadFile("last_frame.jpg") if err != nil { log.Fatal(err) } firstFrameB64 := base64.StdEncoding.EncodeToString(firstBytes) lastFrameB64 := base64.StdEncoding.EncodeToString(lastBytes) contents := []interactions.Content{ interactions.NewContent(interactions.ImageContent{ Data: genai.Ptr(firstFrameB64), MimeType: interactions.ImageContentMimeTypeImageJpeg.ToPointer(), }), interactions.NewContent(interactions.ImageContent{ Data: genai.Ptr(lastFrameB64), MimeType: interactions.ImageContentMimeTypeImageJpeg.ToPointer(), }), interactions.NewContent(interactions.TextContent{ Text: "A smooth cinematic transition from a lush green forest at sunrise to a snowy forest under a starry night sky.", }), } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-omni-1.1-flash"), Input: interactions.NewInteractionsInput(contents), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputVideo != nil && res.Interaction.OutputVideo.Data != nil { videoBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputVideo.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("interpolation.mp4", videoBytes, 0644); err != nil { log.Fatal(err) } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions?key=$API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gemini-omni-1.1-flash", "input": [ {"type": "image", "data": "'"$FIRST_FRAME_B64"'", "mime_type": "image/jpeg"}, {"type": "image", "data": "'"$LAST_FRAME_B64"'", "mime_type": "image/jpeg"}, {"type": "text", "text": "A smooth cinematic transition from a lush green forest at sunrise to a snowy forest under a starry night sky."} ] }' ``` {% /tab %} {% /tabs %} {% video src="https://storage.googleapis.com/generativeai-downloads/videos/omni_keyframe_interpolation.mp4" type="video/mp4" /%} ### Subject reference {% id="subject-reference" %} You can generate a video incorporating specific subjects provided as reference images. For example, the following code shows how to provide 2 images of a cat and yarn to generate a video of the cat playing with the yarn. {% tabs %} {% tab label="Python" %} ```python import base64 from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-omni-1.1-flash", input=[ {"type": "image", "data": cat_b64, "mime_type": "image/png"}, {"type": "image", "data": yarn_b64, "mime_type": "image/png"}, {"type": "text", "text": "A cat playfully batting at a ball of yarn."} ], ) with open("cat.mp4", "wb") as f: f.write(base64.b64decode(interaction.output_video.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from '@google/genai'; import * as fs from 'fs'; const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: 'gemini-omni-1.1-flash', input: [ { type: 'image', data: catData, mime_type: 'image/png' }, { type: 'image', data: yarnData, mime_type: 'image/png' }, { type: 'text', text: 'A cat playfully batting at a ball of yarn.' } ] }); if (interaction.output_video?.data) { fs.writeFileSync('cat.mp4', Buffer.from(interaction.output_video.data, 'base64')); } ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.ImageContentMimeType; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; import java.util.List; Client client = new Client(); String catB64 = Base64.getEncoder().encodeToString(Files.readAllBytes(Paths.get("cat.png"))); String yarnB64 = Base64.getEncoder().encodeToString(Files.readAllBytes(Paths.get("yarn.png"))); Content catImage = ImageContent.builder() .data(catB64) .mimeType(ImageContentMimeType.IMAGE_PNG) .build(); Content yarnImage = ImageContent.builder() .data(yarnB64) .mimeType(ImageContentMimeType.IMAGE_PNG) .build(); Content textContent = TextContent.builder() .text("A cat playfully batting at a ball of yarn.") .build(); List contents = Arrays.asList(catImage, yarnImage, textContent); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-omni-1.1-flash")) .input(InteractionsInput.ofContent(contents)) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.outputVideo().isPresent() && interaction.outputVideo().get().data().isPresent()) { byte[] videoBytes = Base64.getDecoder().decode(interaction.outputVideo().get().data().get()); Files.write(Paths.get("cat.mp4"), videoBytes); } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } catBytes, err := os.ReadFile("cat.png") if err != nil { log.Fatal(err) } yarnBytes, err := os.ReadFile("yarn.png") if err != nil { log.Fatal(err) } catB64 := base64.StdEncoding.EncodeToString(catBytes) yarnB64 := base64.StdEncoding.EncodeToString(yarnBytes) contents := []interactions.Content{ interactions.NewContent(interactions.ImageContent{ Data: genai.Ptr(catB64), MimeType: interactions.ImageContentMimeTypeImagePng.ToPointer(), }), interactions.NewContent(interactions.ImageContent{ Data: genai.Ptr(yarnB64), MimeType: interactions.ImageContentMimeTypeImagePng.ToPointer(), }), interactions.NewContent(interactions.TextContent{ Text: "A cat playfully batting at a ball of yarn.", }), } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-omni-1.1-flash"), Input: interactions.NewInteractionsInput(contents), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputVideo != nil && res.Interaction.OutputVideo.Data != nil { videoBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputVideo.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("cat.mp4", videoBytes, 0644); err != nil { log.Fatal(err) } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions?key=$API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gemini-omni-1.1-flash", "input": [ {"type": "image", "data": "'"$CAT_B64"'", "mime_type": "image/png"}, {"type": "image", "data": "'"$YARN_B64"'", "mime_type": "image/png"}, {"type": "text", "text": "A cat playfully batting at a ball of yarn."} ] }' ``` {% /tab %} {% /tabs %} ### Tasks parameter {% id="tasks-parameter" %} Use the `task` parameter in the `video_config` to explicitly specify the intended behavior, for example if you want the model to generate a video from an image, you can set the parameter to `image_to_video`. If this is not set, the model will infer what you want from the prompt. {% callout type="tip" %} We recommend relying primarily on prompting and using the `task` parameter only when prompting doesn't work and you need to help the model understand which mode it should use, as using the `task` field adds some constraints. {% /callout %} The following are allowed values: * `text_to_video` * `image_to_video` * `reference_to_video` * `edit` * `extend` The following example shows how to set this for the previously shown image to video example. {% tabs %} {% tab label="Python" %} ```python import base64 from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-omni-1.1-flash", input=[ {"type": "image", "data": base64_image, "mime_type": "image/jpeg"}, {"type": "text", "text": "turn this into realistic footage, using the drawing only as a guide for movement, do not show the drawing in the final video"} ], generation_config={ "video_config": { "task": "image_to_video", } }, ) with open("example.mp4", "wb") as f: f.write(base64.b64decode(interaction.output_video.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; import * as fs from 'fs'; const ai = new GoogleGenAI({}); const interaction = await ai.interactions.create({ model: 'gemini-omni-1.1-flash', input: [ { type: 'image', data: base64Image, mime_type: 'image/jpeg' }, { type: 'text', text: 'turn this into realistic footage, using the drawing only as a guide for movement, do not show the drawing in the final video' } ], generation_config: { video_config: { task: 'image_to_video', } } }); if (interaction.output_video?.data) { fs.writeFileSync('example.mp4', Buffer.from(interaction.output_video.data, 'base64')); } ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.GenerationConfig; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.ImageContentMimeType; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.Task; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.interactions.VideoConfig; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; import java.util.List; Client client = new Client(); byte[] imageBytes = Files.readAllBytes(Paths.get("drawing.jpg")); String base64Image = Base64.getEncoder().encodeToString(imageBytes); Content imageContent = ImageContent.builder() .data(base64Image) .mimeType(ImageContentMimeType.IMAGE_JPEG) .build(); Content textContent = TextContent.builder() .text( "turn this into realistic footage, using the drawing only as a guide for movement, do not show the drawing in the final video") .build(); List contents = Arrays.asList(imageContent, textContent); GenerationConfig generationConfig = GenerationConfig.builder() .videoConfig(VideoConfig.builder().task(Task.IMAGE_TO_VIDEO).build()) .build(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-omni-1.1-flash")) .input(InteractionsInput.ofContent(contents)) .generationConfig(generationConfig) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.outputVideo().isPresent() && interaction.outputVideo().get().data().isPresent()) { byte[] videoBytes = Base64.getDecoder().decode(interaction.outputVideo().get().data().get()); Files.write(Paths.get("example.mp4"), videoBytes); } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } imageBytes, err := os.ReadFile("drawing.jpg") if err != nil { log.Fatal(err) } base64Image := base64.StdEncoding.EncodeToString(imageBytes) contents := []interactions.Content{ interactions.NewContent(interactions.ImageContent{ Data: genai.Ptr(base64Image), MimeType: interactions.ImageContentMimeTypeImageJpeg.ToPointer(), }), interactions.NewContent(interactions.TextContent{ Text: "turn this into realistic footage, using the drawing only as a guide for movement, do not show the drawing in the final video", }), } generationConfig := &interactions.GenerationConfig{ VideoConfig: &interactions.VideoConfig{ Task: interactions.TaskImageToVideo.ToPointer(), }, } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-omni-1.1-flash"), Input: interactions.NewInteractionsInput(contents), GenerationConfig: generationConfig, }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputVideo != nil && res.Interaction.OutputVideo.Data != nil { videoBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputVideo.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("example.mp4", videoBytes, 0644); err != nil { log.Fatal(err) } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gemini-omni-1.1-flash", "input": [ { "type": "image", "data": "'"$BASE64_IMAGE"'", "mime_type": "image/jpeg" }, { "type": "text", "text": "turn this into realistic footage, using the drawing only as a guide for movement, do not show the drawing in the final video" } ], "generation_config": { "video_config": { "task": "image_to_video" } } }' ``` {% /tab %} {% /tabs %} ## Stateful video editing {% id="stateful-video-editing" %} Generate a video and edit it iteratively using follow-up prompts. Each turn builds on the previous result. The model remembers the video context, applying your changes while preserving elements you did not mention. Use the `previous_interaction_id` to track the conversation history and the generated video state without re-uploading the previous video. {% callout type="note" %} See [Limitations](/docs/omni#limitations) for detailed list of restrictions for video editing. {% /callout %} The following example demonstrates how to generate a first video then edit it: {% tabs %} {% tab label="Python" %} ```python import base64 from google import genai client = genai.Client() # Turn 1: Generate initial video res1 = client.interactions.create(model="gemini-omni-1.1-flash", input="A woman playing violin outdoors.") # Turn 2: Edit the previous video res2 = client.interactions.create( model="gemini-omni-1.1-flash", previous_interaction_id=res1.id, input="Make the violin invisible." ) with open("example.mp4", "wb") as f: f.write(base64.b64decode(res2.output_video.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from '@google/genai'; import * as fs from 'fs'; const ai = new GoogleGenAI({}); // Turn 1: Generate initial video const res1 = await ai.interactions.create({ model: 'gemini-omni-1.1-flash', input: 'A woman playing violin outdoors.', }); // Turn 2: Edit the previous video const res2 = await ai.interactions.create({ model: 'gemini-omni-1.1-flash', previous_interaction_id: res1.id, input: 'Make the violin invisible.', }); if (res2.output_video?.data) { if (interaction.output_video?.data) { fs.writeFileSync('example.mp4', Buffer.from(interaction.output_video.data, 'base64')); } } ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Base64; Client client = new Client(); // Turn 1: Generate initial video CreateModelInteraction turn1Params = CreateModelInteraction.builder() .model(Model.of("gemini-omni-1.1-flash")) .input(InteractionsInput.of("A woman playing violin outdoors.")) .build(); Interaction res1 = client.interactions.create(CreateInteractionRequestBody.of(turn1Params)).interaction().get(); // Turn 2: Edit the previous video CreateModelInteraction turn2Params = CreateModelInteraction.builder() .model(Model.of("gemini-omni-1.1-flash")) .previousInteractionId(res1.id().get()) .input(InteractionsInput.of("Make the violin invisible.")) .build(); Interaction res2 = client.interactions.create(CreateInteractionRequestBody.of(turn2Params)).interaction().get(); if (res2.outputVideo().isPresent() && res2.outputVideo().get().data().isPresent()) { byte[] videoBytes = Base64.getDecoder().decode(res2.outputVideo().get().data().get()); Files.write(Paths.get("example.mp4"), videoBytes); } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } // Turn 1: Generate initial video res1, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-omni-1.1-flash"), Input: interactions.NewInteractionsInput("A woman playing violin outdoors."), }), }) if err != nil { log.Fatal(err) } // Turn 2: Edit the previous video res2, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-omni-1.1-flash"), PreviousInteractionID: res1.Interaction.ID, Input: interactions.NewInteractionsInput("Make the violin invisible."), }), }) if err != nil { log.Fatal(err) } if res2.Interaction.OutputVideo != nil && res2.Interaction.OutputVideo.Data != nil { videoBytes, err := base64.StdEncoding.DecodeString(*res2.Interaction.OutputVideo.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("example.mp4", videoBytes, 0644); err != nil { log.Fatal(err) } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions?key=$API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gemini-omni-1.1-flash", "previous_interaction_id": "'"$PREVIOUS_ID"'", "input": "Make the violin invisible." }' ``` {% /tab %} {% /tabs %} Example of an initial video: {% video id="9yk4HuZmF0g" title="Watch video (Reference)" /%} Example of an edited video: {% video id="U5GXcvq6GZY" title="Watch video (Reference)" /%} Each turn in the conversation produces a new video. The model understands context from prior turns, letting you make incremental changes like adjusting lighting, and swapping backgrounds, without re-describing the entire scene. ### Edit your own videos {% id="edit-your-own-videos" %} Upload your videos using the [Files API](/docs/files) to edit them with Gemini Omni Flash. {% callout type="note" %} Editing uploaded videos is not available in all regions. See [Limitations](/docs/omni#limitations) section for details. {% /callout %} The following example shows how to edit the following original video: {% video id="lw9MJDx9Zas" title="Watch video (Reference)" /%} {% tabs %} {% tab label="Python" %} ```python import time import base64 from google import genai client = genai.Client() # Upload video using the file API video_file = client.files.upload(file="Video.mp4") while video_file.state == "PROCESSING": print('Waiting for video to be processed.') time.sleep(10) video_file = client.files.get(name=video_file.name) if video_file.state == "FAILED": raise ValueError(video_file.state) print(f'Video processing complete: ' + video_file.uri) # Edit your video interaction = client.interactions.create( model="gemini-omni-1.1-flash", input=[ {"type": "video", "uri": video_file.uri}, {"type": "text", "text": "When the person touches the mirror, make the mirror ripple beautifully like liquid, and the person's arm turns into reflective mirror material"} ], ) with open("example.mp4", "wb") as f: f.write(base64.b64decode(interaction.output_video.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from '@google/genai'; import * as fs from 'fs'; const ai = new GoogleGenAI({}); // Upload video using the file API let videoFile = await ai.files.upload({ file: 'Video.mp4', }); while (videoFile.state === 'PROCESSING') { console.log('Waiting for video to be processed.'); await new Promise(r => setTimeout(r, 10000)); videoFile = await ai.files.get({ name: videoFile.name || '' }); } if (videoFile.state === 'FAILED') { throw new Error(videoFile.state); } console.log('Video processing complete: ' + videoFile.uri); // Edit your video const interaction = await ai.interactions.create({ model: 'gemini-omni-1.1-flash', input: [ { type: 'video', uri: videoFile.uri }, { type: 'text', text: "When the person touches the mirror, make the mirror ripple beautifully like liquid, and the person's arm turns into reflective mirror material" } ], }); if (interaction.output_video?.data) { fs.writeFileSync('example.mp4', Buffer.from(interaction.output_video.data, 'base64')); } ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.interactions.VideoContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import com.google.genai.types.File; import com.google.genai.types.FileState; import com.google.genai.types.UploadFileConfig; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; import java.util.List; Client client = new Client(); // Upload video using the file API File videoFile = client.files.upload("Video.mp4", UploadFileConfig.builder().mimeType("video/mp4").build()); while (videoFile.state().isPresent() && videoFile.state().get().knownEnum() == FileState.Known.PROCESSING) { System.out.println("Waiting for video to be processed."); Thread.sleep(10000); videoFile = client.files.get(videoFile.name().get(), null); } if (videoFile.state().isPresent() && videoFile.state().get().knownEnum() == FileState.Known.FAILED) { throw new IllegalStateException("Video processing failed: " + videoFile.state().get()); } System.out.println("Video processing complete: " + videoFile.uri().orElse("")); // Edit your video Content videoContent = VideoContent.builder().uri(videoFile.uri().get()).build(); Content textContent = TextContent.builder() .text( "When the person touches the mirror, make the mirror ripple beautifully like liquid, and the person's arm turns into reflective mirror material") .build(); List contents = Arrays.asList(videoContent, textContent); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-omni-1.1-flash")) .input(InteractionsInput.ofContent(contents)) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.outputVideo().isPresent() && interaction.outputVideo().get().data().isPresent()) { byte[] videoBytes = Base64.getDecoder().decode(interaction.outputVideo().get().data().get()); Files.write(Paths.get("example.mp4"), videoBytes); } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "fmt" "log" "os" "time" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } // Upload video using the file API videoFile, err := client.Files.UploadFromPath(ctx, "Video.mp4", &genai.UploadFileConfig{ MIMEType: "video/mp4", }) if err != nil { log.Fatal(err) } for videoFile.State == genai.FileStateProcessing { fmt.Println("Waiting for video to be processed.") time.Sleep(10 * time.Second) videoFile, err = client.Files.Get(ctx, videoFile.Name, nil) if err != nil { log.Fatal(err) } } if videoFile.State == genai.FileStateFailed { log.Fatalf("Video processing failed: %s", videoFile.State) } fmt.Printf("Video processing complete: %s\n", videoFile.URI) // Edit your video contents := []interactions.Content{ interactions.NewContent(interactions.VideoContent{ URI: genai.Ptr(videoFile.URI), }), interactions.NewContent(interactions.TextContent{ Text: "When the person touches the mirror, make the mirror ripple beautifully like liquid, and the person's arm turns into reflective mirror material", }), } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-omni-1.1-flash"), Input: interactions.NewInteractionsInput(contents), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputVideo != nil && res.Interaction.OutputVideo.Data != nil { videoBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputVideo.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("example.mp4", videoBytes, 0644); err != nil { log.Fatal(err) } } } ``` {% /tab %} {% tab label="REST" %} ```bash #!/bin/bash VIDEO_B64=$(encode_file "$VIDEO_FILE") curl -sS -w "\n[HTTP %{http_code}]\n" "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: ${API_KEY}" \ -H "Content-Type: application/json" \ -d @- < video_editing_response.json { "model": "gemini-omni-1.1-flash", "input": [ { "type": "user_input", "content": [ { "type": "video", "mime_type": "video/mp4", "data": "$VIDEO_B64" }, { "type": "text", "text": "When the person touches the mirror, make the mirror ripple beautifully like liquid, and the person's arm turns into reflective mirror material" } ] } ], "response_format": { "type": "video" } } EOF ``` {% /tab %} {% /tabs %} Example of an edited video: {% video id="Bn-6vCl1wgQ" title="Watch video (Reference)" /%} {% callout type="note" %} You can also pass the data directly in base64, but since videos can be quite big we recommend using the File API. {% /callout %} ## Retrieving videos with an URI {% id="retrieving-videos-with-an-uri" %} Use the `delivery="uri"` parameter in `response_format` to retrieve generated videos that are larger than 4MB. This returns a Google-hosted URI that you can poll until the video is `ACTIVE` before downloading. {% tabs %} {% tab label="Python" %} ```python import time from google import genai client = genai.Client() # 1. Request video via URI delivery interaction = client.interactions.create( model="gemini-omni-1.1-flash", input="A beautiful sunset.", response_format={"type": "video", "delivery": "uri"} ) # 2. Extract file name and poll for ACTIVE state video_output = interaction.output_video file_name = video_output.uri.split("/")[-1] # Extract ID print("Waiting for video processing...") while True: f_info = client.files.get(name=f"files/{file_name}") if f_info.state.name == "ACTIVE": break elif f_info.state.name == "FAILED": raise RuntimeError("Generation failed.") time.sleep(5) # 3. Download the final video client.files.download(file=video_output.uri, destination="output.mp4") ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from '@google/genai'; const ai = new GoogleGenAI({}); // 1. Request video using URI delivery const interaction = await ai.interactions.create({ model: 'gemini-omni-1.1-flash', input: 'A beautiful sunset.', response_format: { type: 'video', delivery: 'uri' }, }); // 2. Extract filename and poll for ACTIVE state const videoOutput = interaction.output_video; const fileId = videoOutput?.uri?.match(/files\/([a-zA-Z0-9]+)/)?.[1] || ''; const name = `files/${fileId}`; console.log("Waiting for video processing..."); while (true) { const fInfo = await ai.files.get({ name }); if (fInfo.state === 'ACTIVE') break; if (fInfo.state === 'FAILED') throw new Error("Generation failed."); await new Promise(r => setTimeout(r, 5000)); } // 3. Download the final video await ai.files.download({ file: name, downloadPath: 'output.mp4', }); console.log("💾 Saved video to output.mp4"); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.CreateModelInteractionResponseFormat; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ResponseFormat; import com.google.genai.gaos.models.interactions.VideoContent; import com.google.genai.gaos.models.interactions.VideoResponseFormat; import com.google.genai.gaos.models.interactions.VideoResponseFormatDelivery; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import com.google.genai.types.File; import com.google.genai.types.FileState; Client client = new Client(); // 1. Request video using URI delivery VideoResponseFormat videoFormat = VideoResponseFormat.builder() .delivery(VideoResponseFormatDelivery.URI) .build(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-omni-1.1-flash")) .input(InteractionsInput.of("A beautiful sunset.")) .responseFormat(CreateModelInteractionResponseFormat.of(ResponseFormat.of(videoFormat))) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); // 2. Extract filename and poll for ACTIVE state VideoContent videoOutput = interaction.outputVideo().get(); String uri = videoOutput.uri().get(); String[] parts = uri.split("/"); String fileName = parts[parts.length - 1]; System.out.println("Waiting for video processing..."); while (true) { File fileInfo = client.files.get("files/" + fileName, null); if (fileInfo.state().isPresent() && fileInfo.state().get().knownEnum() == FileState.Known.ACTIVE) { break; } else if (fileInfo.state().isPresent() && fileInfo.state().get().knownEnum() == FileState.Known.FAILED) { throw new RuntimeException("Generation failed."); } Thread.sleep(5000); } // 3. Download the final video client.files.download(uri, "output.mp4", null); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "os" "strings" "time" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } // 1. Request video using URI delivery videoFormat := interactions.VideoResponseFormat{ Delivery: interactions.VideoResponseFormatDeliveryURI.ToPointer(), } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-omni-1.1-flash"), Input: interactions.NewInteractionsInput("A beautiful sunset."), ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat( interactions.NewResponseFormat(videoFormat), )), }), }) if err != nil { log.Fatal(err) } // 2. Extract filename and poll for ACTIVE state uri := *res.Interaction.OutputVideo.URI parts := strings.Split(uri, "/") fileName := parts[len(parts)-1] fmt.Println("Waiting for video processing...") var fileInfo *genai.File for { fileInfo, err = client.Files.Get(ctx, "files/"+fileName, nil) if err != nil { log.Fatal(err) } if fileInfo.State == genai.FileStateActive { break } else if fileInfo.State == genai.FileStateFailed { log.Fatal("Generation failed.") } time.Sleep(5 * time.Second) } // 3. Download the final video videoBytes, err := client.Files.Download(ctx, genai.NewDownloadURIFromFile(fileInfo), nil) if err != nil { log.Fatal(err) } if err := os.WriteFile("output.mp4", videoBytes, 0644); err != nil { log.Fatal(err) } } ``` {% /tab %} {% tab label="REST" %} ```bash #!/bin/bash # 1. Initial request to generate the video RESPONSE=$(curl -s -X POST "https://generativelanguage.googleapis.com/v1beta/interactions?key=$API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gemini-omni-1.1-flash", "input": "A beautiful sunset over a calm ocean.", "response_format": {"type": "video", "delivery": "uri"} }') # Extract FILE_ID from the URI (e.g., "files/abc-123" -> "abc-123") FILE_URI=$(echo $RESPONSE | jq -r '.output_video.uri') FILE_ID=$(echo $FILE_URI | cut -d'/' -f2) echo "Video requested (ID: $FILE_ID). Waiting for processing..." # 2. Polling loop while true; do # Get current file status STATUS_JSON=$(curl -s -X GET "https://generativelanguage.googleapis.com/v1beta/files/$FILE_ID?key=$API_KEY") STATE=$(echo $STATUS_JSON | jq -r '.state') if [ "$STATE" == "ACTIVE" ]; then echo "Processing complete! Downloading..." break elif [ "$STATE" == "FAILED" ]; then echo "Error: Generation failed." exit 1 else echo "Current state: $STATE... (waiting 5s)" sleep 5 fi done # 3. Final download curl -L -X GET "https://generativelanguage.googleapis.com/v1beta/files/$FILE_ID:download?alt=media&key=$API_KEY" \ --output "output.mp4" echo "Done! Video saved to output.mp4" ``` {% /tab %} {% /tabs %} **Raw REST JSON structure (URI):** ```json { "steps": [ { "type": "user_input", "content": [{"type": "text", "text": "..."}] }, { "type": "thought", "content": [{"text": "...", "type": "thought"}] }, { "type": "model_output", "content": [ { "type": "video", "mime_type": "video/mp4", "uri": "https://generativelanguage.googleapis.com/v1beta/files/...:download?alt=media" } ] } ], "id": "v1_...", "status": "completed", "model": "gemini-omni-1.1-flash", "object": "interaction" } ``` {% callout type="note" %} Currently, calling `GET /v1beta/interactions/{id}` returns the video as inline base64 data in the `data` field, even if the interaction was originally created with `delivery: "uri"`. The `uri` field is only guaranteed to be present in the initial creation response or Server-Sent Events (SSE) stream. {% /callout %} ## Video extension {% id="video-extension" %} Extend an existing video by generating a seamless continuation at the tail end of the clip. Describe how you want the video to continue in your prompt, for example `"Extend this video"` or `"Continue the scene: the camera pans across the mountains"`. The model analyzes the input video to generate a 3–10 second continuation. You can extend: * **Videos generated by the model (multi-turn)**: Extend a previously generated video by referencing its `previous_interaction_id`. * **Uploaded videos**: Provide an uploaded video file (via the Files API) along with your extension prompt. {% tabs %} {% tab label="Python" %} ```python import base64 from google import genai client = genai.Client() # Upload your video using the Files API video_file = client.files.upload(file="my_video.mp4") # Extend the video using prompt-based extension interaction = client.interactions.create( model="gemini-omni-1.1-flash", input=[ {"type": "video", "uri": video_file.uri}, {"type": "text", "text": "Continue the scene."} ], ) with open("extended.mp4", "wb") as f: f.write(base64.b64decode(interaction.output_video.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from '@google/genai'; import * as fs from 'fs'; const ai = new GoogleGenAI({}); // Upload your video using the Files API let videoFile = await ai.files.upload({ file: 'my_video.mp4', }); while (videoFile.state === 'PROCESSING') { await new Promise(r => setTimeout(r, 10000)); videoFile = await ai.files.get({ name: videoFile.name || '' }); } // Extend the video using prompt-based extension const interaction = await ai.interactions.create({ model: 'gemini-omni-1.1-flash', input: [ { type: 'video', uri: videoFile.uri }, { type: 'text', text: 'Continue the scene.' } ], }); if (interaction.output_video?.data) { fs.writeFileSync('extended.mp4', Buffer.from(interaction.output_video.data, 'base64')); } ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.interactions.VideoContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import com.google.genai.types.File; import com.google.genai.types.UploadFileConfig; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; import java.util.List; Client client = new Client(); // Upload your video using the Files API File videoFile = client.files.upload( "my_video.mp4", UploadFileConfig.builder().mimeType("video/mp4").build()); // Extend the video using prompt-based extension Content videoContent = VideoContent.builder().uri(videoFile.uri().get()).build(); Content textContent = TextContent.builder().text("Continue the scene.").build(); List contents = Arrays.asList(videoContent, textContent); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-omni-1.1-flash")) .input(InteractionsInput.ofContent(contents)) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.outputVideo().isPresent() && interaction.outputVideo().get().data().isPresent()) { byte[] videoBytes = Base64.getDecoder().decode(interaction.outputVideo().get().data().get()); Files.write(Paths.get("extended.mp4"), videoBytes); } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } // Upload your video using the Files API videoFile, err := client.Files.UploadFromPath(ctx, "my_video.mp4", &genai.UploadFileConfig{ MIMEType: "video/mp4", }) if err != nil { log.Fatal(err) } // Extend the video using prompt-based extension contents := []interactions.Content{ interactions.NewContent(interactions.VideoContent{ URI: genai.Ptr(videoFile.URI), }), interactions.NewContent(interactions.TextContent{ Text: "Continue the scene.", }), } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-omni-1.1-flash"), Input: interactions.NewInteractionsInput(contents), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputVideo != nil && res.Interaction.OutputVideo.Data != nil { videoBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputVideo.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("extended.mp4", videoBytes, 0644); err != nil { log.Fatal(err) } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions?key=$API_KEY" -H "Content-Type: application/json" -d '{ "model": "gemini-omni-1.1-flash", "input": [ {"type": "video", "uri": "'"$VIDEO_URI"'"}, {"type": "text", "text": "Continue the scene."} ] }' ``` {% /tab %} {% /tabs %} {% video src="https://storage.googleapis.com/generativeai-downloads/videos/omni_scene_extension_base.mp4" type="video/mp4" /%} {% video src="https://storage.googleapis.com/generativeai-downloads/videos/omni_scene_extension_extended.mp4" type="video/mp4" /%} ### Extending with reference media {% id="extending-with-reference-media" %} You can provide reference images in the `input` array along with your prompt to introduce new characters or elements into the extended video: {% tabs %} {% tab label="Python" %} ```python import base64 from google import genai client = genai.Client() # Upload base video and reference image using the Files API video_file = client.files.upload(file="my_video.mp4") character_img = client.files.upload(file="character.png") # Extend the video while introducing the reference character interaction = client.interactions.create( model="gemini-omni-1.1-flash", input=[ {"type": "video", "uri": video_file.uri}, {"type": "image", "uri": character_img.uri}, {"type": "text", "text": "Extend this video: have the character shown in enter the scene and wave."} ], ) with open("extended_with_character.mp4", "wb") as f: f.write(base64.b64decode(interaction.output_video.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from '@google/genai'; import * as fs from 'fs'; const ai = new GoogleGenAI({}); // Upload base video and reference image using the Files API let videoFile = await ai.files.upload({ file: 'my_video.mp4' }); let characterImg = await ai.files.upload({ file: 'character.png' }); while (videoFile.state === 'PROCESSING' || characterImg.state === 'PROCESSING') { await new Promise(r => setTimeout(r, 10000)); videoFile = await ai.files.get({ name: videoFile.name || '' }); characterImg = await ai.files.get({ name: characterImg.name || '' }); } // Extend the video while introducing the reference character const interaction = await ai.interactions.create({ model: 'gemini-omni-1.1-flash', input: [ { type: 'video', uri: videoFile.uri }, { type: 'image', uri: characterImg.uri }, { type: 'text', text: 'Extend this video: have the character shown in enter the scene and wave.' } ], }); if (interaction.output_video?.data) { fs.writeFileSync('extended_with_character.mp4', Buffer.from(interaction.output_video.data, 'base64')); } ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.interactions.VideoContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import com.google.genai.types.File; import com.google.genai.types.UploadFileConfig; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; import java.util.List; Client client = new Client(); // Upload base video and reference image using the Files API File videoFile = client.files.upload( "my_video.mp4", UploadFileConfig.builder().mimeType("video/mp4").build()); File characterImg = client.files.upload( "character.png", UploadFileConfig.builder().mimeType("image/png").build()); // Extend the video while introducing the reference character Content videoContent = VideoContent.builder().uri(videoFile.uri().get()).build(); Content imageContent = ImageContent.builder().uri(characterImg.uri().get()).build(); Content textContent = TextContent.builder() .text( "Extend this video: have the character shown in enter the scene and wave.") .build(); List contents = Arrays.asList(videoContent, imageContent, textContent); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-omni-1.1-flash")) .input(InteractionsInput.ofContent(contents)) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.outputVideo().isPresent() && interaction.outputVideo().get().data().isPresent()) { byte[] videoBytes = Base64.getDecoder().decode(interaction.outputVideo().get().data().get()); Files.write(Paths.get("extended_with_character.mp4"), videoBytes); } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } // Upload base video and reference image using the Files API videoFile, err := client.Files.UploadFromPath(ctx, "my_video.mp4", &genai.UploadFileConfig{ MIMEType: "video/mp4", }) if err != nil { log.Fatal(err) } characterImg, err := client.Files.UploadFromPath(ctx, "character.png", &genai.UploadFileConfig{ MIMEType: "image/png", }) if err != nil { log.Fatal(err) } // Extend the video while introducing the reference character contents := []interactions.Content{ interactions.NewContent(interactions.VideoContent{ URI: genai.Ptr(videoFile.URI), }), interactions.NewContent(interactions.ImageContent{ URI: genai.Ptr(characterImg.URI), }), interactions.NewContent(interactions.TextContent{ Text: "Extend this video: have the character shown in enter the scene and wave.", }), } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-omni-1.1-flash"), Input: interactions.NewInteractionsInput(contents), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputVideo != nil && res.Interaction.OutputVideo.Data != nil { videoBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputVideo.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("extended_with_character.mp4", videoBytes, 0644); err != nil { log.Fatal(err) } } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions?key=$API_KEY" -H "Content-Type: application/json" -d '{ "model": "gemini-omni-1.1-flash", "input": [ {"type": "video", "uri": "'$VIDEO_URI'"}, {"type": "image", "uri": "'$CHARACTER_IMG_URI'"}, {"type": "text", "text": "Extend this video: have the character shown in enter the scene and wave."} ] }' ``` {% /tab %} {% /tabs %} {% video src="https://storage.googleapis.com/generativeai-downloads/videos/omni_traveler_extension.mp4" type="video/mp4" /%} {% callout type="tip" %} Optionally, you can set `"task": "extend"` in `video_config` under `generation_config` if prompting alone does not produce the expected extension mode. However, we recommend relying primarily on prompting first, as using the `task` field adds strict constraints to the model. {% /callout %} ### Extension constraints and guidelines {% id="extension-constraints" %} Keep the following rules and constraints in mind when extending videos: * **Spoken dialogue on uploaded videos**: Currently, you cannot extend an uploaded video where someone is talking to add additional dialogue (it is supported if the character remains silent or if the prompt does not add dialogue). * **Multi-turn voice extension**: Generating spoken dialogue or speech is supported when extending previously generated videos via multi-turn (`previous_interaction_id`). * **End-of-clip only**: Extension is limited to appending to the end of the video. You cannot prepend content or extend the middle of a clip. * **Duration limit**: Input videos for extension must be 10 seconds or less in length when uploading (unless using multi-turn). * **Regional availability**: Extending uploaded videos is not currently available for users in the European Economic Area (EEA), Switzerland, and the United Kingdom (extending videos generated by the model is supported in all available regions). ## Best practices {% id="best-practices" %} * **Use URI delivery for large videos:** For videos larger than 4MB (>720p when available), use `delivery="uri"` in `response_format` to avoid payload size limits. * **Optimized performance:** Set `background=false`, `store=false`, and `stream=false` for faster, synchronous unary generation. Note that setting `store=false` means the generated video won't be editable in subsequent turns using the `previous_interaction_id`. * **Prompt precision:** See [prompt guidance](/docs/omni#prompt-guide) section for details. ## Limitations {% id="limitations" %} * Uploading and editing images containing minors is not supported in European Economic Area, Switzerland, and the United Kingdom. * Uploading and editing images containing certain recognizable people is not supported. * Editing or extending uploaded videos is not currently available for users in the European Economic Area (EEA), Switzerland, and the United Kingdom (editing or extending videos generated by the model is supported). * Input videos for editing and extension must be 10 seconds or less when uploading (unless extending videos generated by the model in multi-turn). * Video extension is limited to appending to the end of a video; prepending or extending the middle of a clip is not supported. * You cannot extend an uploaded video where someone is talking to add additional dialogue (characters can remain silent, or multi-turn extension with `previous_interaction_id` can be used). * Voice editing is not supported. * Uploading audio references is unsupported in the current version of the API. * Video references work best with likenesses; any audio in a video reference is ignored. Video references support a maximum of 3 clips, up to 3 seconds each. * Referencing or reasoning across multiple videos is not supported. Attempting multi-video prompting may result in degraded model performance or unexpected outputs. * Provisioned throughput is not supported. * System instructions, temperature, `top_p`, stop sequences, and negative prompts are not supported (you can put your negatives in the regular prompt: e.g., "Do not do X"). * Using YouTube videos as a media source is not supported. ## Technical details {% id="tech-details" %} * All generated videos include SynthID watermarking, which is invisible to viewers but can be detected programmatically for provenance verification. * Video generation times vary based on duration, resolution, and current API load. Longer and higher-resolution videos take more time to generate. * Omni applies content safety filters to both input prompts and generated video (which vary by region). Prompts that violate usage policies are blocked. * English (EN) is fully supported, but other languages have not been evaluated, so they may work but results can vary. ## Gemini Omni Flash prompt guide {% id="prompt-guide" %} This section contains tips and examples on how to prompt Gemini Omni Flash effectively. ### Single scene {% id="single-scene" %} By default Omni Flash will try to create a video with a few different shots. It'll attempt to craft an interesting narrative based on the prompt. If you need the output video to contain a single scene, you must prompt for that: * In a single unbroken scene * In a single continuous shot * No scene cuts For example: ```none Continuous, unbroken handheld shot of a fluffy tabby cat sitting on a sunny windowsill, looking out into a leafy garden. The cat's tail twitches slowly, and its ears rotate slightly toward ambient noises. Sunbeams illuminate dust motes in the air. Sound design: Gentle breeze, distant bird chirps. No dialogue. ``` ### Removing unwanted elements {% id="remove-unwanted-elements" %} If the generated video contains things you don't want, include simple negative prompts to avoid them: * No dialogue * No embellishments * No extra sound effects ### Prompts for editing {% id="prompts-for-editing" %} Simple prompts work best for video editing. Overly descriptive prompts can lead to unintended changes. The following are more examples of simple editing prompts: * Make this video anime * Put a fashionable hat on this person * Change the lighting to be more dramatic * Change the text on the sign to say "Omni Flash" When editing a specific aspect of the video, include `"Keep everything else the same"` to maintain visual consistency. The following are some examples to show how to apply this technique: * **Avoid:** `In the video of the man sitting on the sofa, please add a small black cat that runs from the right side of the screen, jumps onto his lap, and then he starts to stroke its head while looking down.` * **Simplify:** `Add a cat that jumps onto his lap, he begins to pet it. Keep everything else the same.` * **Avoid:** `Please remove the cell phone that the person is holding in their hand and fill in the background so it looks like they are just holding their hand empty.` * **Simplify:** `Make the phone invisible. Keep everything else the same.` ### Prompting the audio {% id="prompting-audio" %} By default the model will try to generate an appropriate audio track for a video. This might not always be what you want. You can use your prompt to describe the type of audio you want. This is especially important if you want music in your video: * Include calm background music * The video has a high energy techno beat * The audio is a low tinny radio broadcast in the background, playing a song ### Timing events {% id="timing-events" %} You can prompt for things to happen at specific times in the video, there is no precise syntax needed and you can use natural language. This is especially useful in creating your own scene cuts, rhythm or rapid fire sequences. See the following for examples: * After 3 seconds, a woman enters the scene. * At 5s the chorus starts in the background audio. * Every 2s cut to a new frame. * In a rapid fire sequence, every half a second (12 frames at 24fps) change the scene to a new location. You can also use a timecode syntax: ```none [0-3s] A person is walking [3-6s] They stop and turn around [6-10s] They start running ``` ### Meta prompting {% id="meta-prompting" %} You can ask Gemini Omni Flash to pay attention to general qualities or principles of video generation: * Consider micro-detail, expression and timing to create a very rich, detailed but entirely natural scene. * Be extremely detailed in your descriptions of characters and environments. Apply costume design principles to characters. Be very specific about the people, items and objects in the scene. * Include plenty of appropriate detail in the background elements to make the scene feel realistic and natural. * Make a rapid fire video that shows a different rare `[thing]` every 1s, upbeat music, include text to label the thing. ### Text in videos {% id="text-in-videos" %} You can prompt to include text in your video and Gemini Omni will render in a way that is correct and readable. If there will be naturally occurring text in your video, even in background elements, it can help to define what it should say. * One word on the screen at a time: "did, you, know, that, Omni, can, do, awesome, text?" Each word appears for 1s with a different animated style. No dialogue. * There is a street sign that says: "This is an AI generation by Omni", there is a storefront that says: "All you need AI", there's a car with the number plate: "OMNI1.1" ### Prompts for extending a video {% id="prompts-extending-video" %} With Gemini Omni 1.1 Flash you can extend videos with prompts like, `"Extend this video"` or `"The scene continues"`. You can extend videos by 10s, up to a total length of 40s. Omni creates an extension that keeps video, motion, characters and audio coherent by using the last 10s of your original video as context. Some of the final frames in your input video will be edited to make the transition seamless. When extending, all of this guide's Omni prompting tips still apply: * Describe the audio in your extended scene, especially if you need it to change: `"The music continues into the chorus"` * Describe if the scene continues, or if there is a shot cut to a new scene (perhaps with the same characters): `"Show the same characters in the next scene"` * Include images and videos as references when extending to help keep your outputs accurate, or to introduce new characters: `"The person shown in the reference image enters the scene"`, `"The dog in the reference video jumps onto the sofa"` * If using timestamps or a timecode syntax, 0s refers to the beginning of the extended part of the video. If extending a 10s video, the scene cut in this prompt will happen after 12s: `"After 2s cut to a new scene with the same characters"` ### Using tags in prompts to set image and video roles {% id="set-image-roles" %} You can use tags to bind uploaded media to specific generation roles. This lets you specify whether each image or video is a starting frame, a final frame, or a reference. #### 1. Simple tags (recommended) {% id="simple-tags" %} For simple cases where media roles are clear from the prompt, you can bind images and videos to roles directly: * **``**: use the image as the starting frame of the video, for example: ` a woman is walking` * **``**: use the image as the final frame of the video to transition to. Must be used with ``, for example: ` a woman is walking` * **``**: use the image as a reference, for example: `in the style of a woman is walking` (combines style reference from the first image and subject reference from the second image). Image references start from 0. * **``**: use the video as a character or object reference, for example: `the person in is playing the violin`. Video references also start from 0. The following is an example with 6 reference images: ```none [0-3s] A studio fashion sequence. Starting with woman , she is holding [3-6s] Then we see the man holding [6-10s] And finally another woman who is holding while walking. ``` #### 2. Declaring sources and references {% id="explicit-declarations" %} For more complex cases with multiple media inputs and multiple roles, you can use explicit prefix tags paired with natural language instructions. You should declare these sources and references at the start of your prompt. * `[# Sources @Image1]` will use the first image as the starting frame. * `[# Sources @Image1 @Image2]` will use the first image as the starting frame and the second image as the final frame. * `[# Sources @Image1 @Image1]` will use the first image as both the first frame and the last frame, creating a video that loops. * `[# Sources @Image1] [# References @Image2]` will use the first image as the starting frame and the second image as a reference. * `[# Sources @Video1]` will use the video as the primary source video to edit or modify. * `[# Sources @Video1]` will use the video from the previous turn to extend. * `[# References @Image1]` will use the first image as a reference. * `[# References @Image2]` will use the second image as a reference. * `[# References @Image1 @Image2]` will use both images as references. * `[# References @Video1]` will use the first video as a reference. * `[# References @Image1 @Video1]` will use both an image and a video as a reference. Add guiding instructions at the end of your prompt: * For a starting frame: `"Use this image as the starting frame."` * For a looping video via start and end frames: `"Use this image as the first frame and the last frame."` * For reference images: `"Use the given image(s) as references for video generation. The images should not be used as literal initial frames."` * For reference videos: `"Use the given video(s) as references. Do not use them as a source for video editing."` Some examples of prompts with source and reference declarations: **Starting frame combined with a reference image:** ```none [# Sources @Image1] [# References @Image2] a woman is walking. Use Image1 as the starting frame. Use Image2 as a reference for the video generation. ``` **Character reference video combined with an object reference image:** ```none [# References @Image1 @Video1] The woman in is playing the violin shown in . Use Video1 as a character reference and Image1 as an object reference. ``` ## What's next {% id="what-s-next" %} * Get started with the Gemini Omni Flash by experimenting in the [Omni Quickstart Colab](https://colab.sandbox.google.com/github/google-gemini/cookbook/blob/main/quickstarts/Get_started_Omni.ipynb). * Learn how to write even better prompts with our [Introduction to prompt design](/docs/prompting-strategies). # Generate music with Lyria 3.5 Source: https://aistudio.google.com/docs/music-generation Description: Generate music with the Gemini API using Lyria 3 Clip and Lyria 3.5. Lyria 3.5 is Google's family of music generation models, available through the Gemini API. With Lyria 3.5, you can generate high-quality, 44.1 kHz stereo audio from text prompts or from images. These models deliver structural coherence, including vocals, timed lyrics, and full instrumental arrangements. The Lyria family includes models: | Model | Model ID | Best for | Duration | Output | |---|---|---|---|---| | **Lyria 3 Clip** | `lyria-3-clip-preview` | Short clips, loops, previews | 30 seconds | MP3 | | **Lyria 3.5** | `lyria-3.5` | Full-length songs with verses, choruses, bridges | A couple of minutes (controllable using prompt) | MP3 | Both models can be used using the new [Interactions API](/docs/interactions-overview), supporting multimodal inputs (text and images), and produce **44.1 kHz high-fidelity stereo** audio. {% callout type="note" %} Looking for real-time, streaming music generation? See [Real-time music generation with Lyria RealTime](/docs/realtime-music-generation). {% /callout %} ## Generate a music clip {% id="generate-music" %} The Lyria 3 Clip model always generates a **30-second** clip. To generate a clip, call the `interactions.create` method with a text prompt. The response always includes the generated lyrics and song structure alongside the audio in the `steps` schema. {% tabs %} {% tab label="Python" %} ```python import base64 from google import genai client = genai.Client() interaction = client.interactions.create( model="lyria-3-clip-preview", input="A short instrumental acoustic guitar piece.", ) generated_audio = interaction.output_audio if generated_audio: with open("music.mp3", "wb") as f: f.write(base64.b64decode(generated_audio.data)) lyrics = interaction.output_text if lyrics: print(f"Lyrics:\n{lyrics}") ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from '@google/genai'; import * as fs from 'fs'; const client = new GoogleGenAI({}); const interaction = await client.interactions.create({ model: 'lyria-3-clip-preview', input: 'A short instrumental acoustic guitar piece.', }); const generatedAudio = interaction.output_audio; if (generatedAudio) { if (generatedAudio?.data) { fs.writeFileSync('music.mp3', Buffer.from(generatedAudio.data, 'base64')); } } const lyrics = interaction.output_text; if (lyrics) { console.log(`Lyrics:\n${lyrics}`); } ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Base64; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("lyria-3-clip-preview")) .input(InteractionsInput.of("A short instrumental acoustic guitar piece.")) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.outputAudio().isPresent() && interaction.outputAudio().get().data().isPresent()) { byte[] audioBytes = Base64.getDecoder().decode(interaction.outputAudio().get().data().get()); Files.write(Paths.get("music.mp3"), audioBytes); } interaction.outputText().ifPresent(lyrics -> System.out.println("Lyrics:\n" + lyrics)); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "fmt" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("lyria-3-clip-preview"), Input: interactions.NewInteractionsInput("A short instrumental acoustic guitar piece."), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputAudio != nil && res.Interaction.OutputAudio.Data != nil { audioBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputAudio.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("music.mp3", audioBytes, 0644); err != nil { log.Fatal(err) } } if res.Interaction.OutputText != nil { fmt.Printf("Lyrics:\n%s\n", *res.Interaction.OutputText) } } ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "Content-Type: application/json" \ -H "Api-Revision: 2026-05-20" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -d '{ "model": "lyria-3-clip-preview", "input": "A short instrumental acoustic guitar piece." }' ``` {% /tab %} {% /tabs %} You can retrieve generated music data by using the `interaction.output_audio` property, which returns the last generated audio block. You can also retrieve the song's lyrics and structure by using the `interaction.output_text` property. {% callout type="note" %} For complex, interleaved multimodal responses (such as music containing both raw structural breakdowns and audio blocks), convenience properties may not capture all parts. You must manually iterate over the steps instead-see [Interleaved lyrics and music](/docs/music-generation#interleaved-output) for an example. {% /callout %} ## Generate a full-length song {% id="full-song" %} Use the `lyria-3.5` model to generate full-length songs that last a couple of minutes. The Pro model understands musical structure and can create compositions with distinct verses, choruses, and bridges. You can influence the duration by specifying it in your prompt (e.g., "create a 2-minute song") or by using [timestamps](/docs/music-generation#timing) to define the structure. {% tabs %} {% tab label="Python" %} ```python interaction = client.interactions.create( model="lyria-3.5", input="An epic cinematic orchestral piece about a journey home. Starts with a solo piano intro, builds through sweeping strings, and climaxes with a massive wall of sound.", ) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript const interaction = await client.interactions.create({ model: 'lyria-3.5', input: 'A beautiful piano melody.', }); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("lyria-3.5")) .input( InteractionsInput.of( "An epic cinematic orchestral piece about a journey home. Starts with a solo piano intro, builds through sweeping strings, and climaxes with a massive wall of sound.")) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("lyria-3.5"), Input: interactions.NewInteractionsInput( "An epic cinematic orchestral piece about a journey home. Starts with a solo piano intro, builds through sweeping strings, and climaxes with a massive wall of sound.", ), }), }) if err != nil { log.Fatal(err) } _ = res } ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "Content-Type: application/json" \ -H "Api-Revision: 2026-05-20" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -d '{ "model": "lyria-3.5", "input": "A beautiful piano melody." }' ``` {% /tab %} {% /tabs %} ## Select output format {% id="output-format" %} By default, the Lyria 3.5 models generate audio in **MP3** format. For Lyria 3.5, you can also request the output in **WAV** format by setting the `response_format`. {% tabs %} {% tab label="Python" %} ```python interaction = client.interactions.create( model="lyria-3.5", input="A beautiful piano melody.", response_format={"type": "audio"}, ) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript const interaction = await client.interactions.create({ model: 'lyria-3.5', input: 'A beautiful piano melody.', response_format: { type: 'audio', }, }); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.AudioResponseFormat; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.CreateModelInteractionResponseFormat; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ResponseFormat; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("lyria-3.5")) .input(InteractionsInput.of("A beautiful piano melody.")) .responseFormat( CreateModelInteractionResponseFormat.of( ResponseFormat.of(AudioResponseFormat.builder().build()))) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("lyria-3.5"), Input: interactions.NewInteractionsInput("A beautiful piano melody."), ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat( interactions.NewResponseFormat(interactions.AudioResponseFormat{}), )), }), }) if err != nil { log.Fatal(err) } _ = res } ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Api-Revision: 2026-05-20" \ -H "Content-Type: application/json" \ -d '{ "model": "lyria-3.5", "input": "A beautiful piano melody.", "response_format": { "type": "audio" } }' ``` {% /tab %} {% /tabs %} ## Parse the response {% id="parse-response" %} The response from Lyria 3.5 contains multiple content blocks within the `steps` schema. Interactions return a sequence of steps, where `model_output` steps contain the generated content. Text content blocks contain the generated lyrics or a JSON description of the song structure. Content blocks with `audio` type contain the base64 encoded audio data. {% tabs %} {% tab label="Python" %} ```python lyrics = [] audio_data = None generated_audio = interaction.output_audio if generated_audio: with open("output.mp3", "wb") as f: f.write(base64.b64decode(generated_audio.data)) lyrics = interaction.output_text if lyrics: print(f"Lyrics:\n{lyrics}") ``` {% /tab %} {% tab label="JavaScript" %} ```javascript const lyrics = []; let audioData = null; const generatedAudio = interaction.output_audio; if (generatedAudio) { fs.writeFileSync("output.mp3", Buffer.from(generatedAudio.data, 'base64')); } const lyrics = interaction.output_text; if (lyrics) { console.log("Lyrics:\n" + lyrics); } ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Base64; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("lyria-3.5")) .input(InteractionsInput.of("A song about a starry night.")) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); if (interaction.outputAudio().isPresent() && interaction.outputAudio().get().data().isPresent()) { byte[] audioBytes = Base64.getDecoder().decode(interaction.outputAudio().get().data().get()); Files.write(Paths.get("output.mp3"), audioBytes); } if (interaction.outputText().isPresent()) { System.out.println("Lyrics:\n" + interaction.outputText().get()); } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "fmt" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("lyria-3.5"), Input: interactions.NewInteractionsInput("A song about a starry night."), }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputAudio != nil && res.Interaction.OutputAudio.Data != nil { audioBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputAudio.Data) if err != nil { log.Fatal(err) } if err := os.WriteFile("output.mp3", audioBytes, 0644); err != nil { log.Fatal(err) } } if res.Interaction.OutputText != nil { fmt.Printf("Lyrics:\n%s\n", *res.Interaction.OutputText) } } ``` {% /tab %} {% tab label="REST" %} ```bash curl ... | jq -r '.steps[] | select(.type=="model_output") | .content[] | select(.type=="audio") | .data' | base64 -d > output.mp3 ``` {% /tab %} {% /tabs %} #### Interleaved lyrics and music {% id="interleaved-output" %} Because the output from Lyria 3.5 is complex-containing separate steps and blocks for generated lyrics (text) and the song itself (audio)-convenience properties offer a fast and recommended shortcut. However, if you want full, programmatic control over the raw timeline of steps returned by the server (such as logging individual content blocks as they are received), you can manually iterate over `steps` instead: {% tabs %} {% tab label="Python" %} ```python lyrics = [] audio_data = None for step in interaction.steps: if step.type == "model_output": for content_block in step.content: if content_block.type == "audio": audio_data = base64.b64decode(content_block.data) elif content_block.type == "text": lyrics.append(content_block.text) if lyrics: print("Lyrics:\n" + "\n".join(lyrics)) if audio_data: with open("output.mp3", "wb") as f: f.write(audio_data) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript const lyrics = []; let audioData = null; for (const step of interaction.steps) { if (step.type === 'model_output') { for (const contentBlock of step.content || []) { if (contentBlock.type === 'audio') { audioData = Buffer.from(contentBlock.data, 'base64'); } else if (contentBlock.type === 'text') { lyrics.push(contentBlock.text); } } } } if (lyrics.length) { console.log("Lyrics:\n" + lyrics.join("\n")); } if (audioData) { fs.writeFileSync("output.mp3", audioData); } ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.AudioContent; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.ModelOutputStep; import com.google.genai.gaos.models.interactions.Step; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Base64; import java.util.List; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("lyria-3.5")) .input(InteractionsInput.of("A song about a starry night.")) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); List lyrics = new ArrayList<>(); byte[] audioData = null; if (interaction.steps().isPresent()) { for (Step step : interaction.steps().get()) { if (step instanceof ModelOutputStep) { ModelOutputStep outputStep = (ModelOutputStep) step; if (outputStep.content().isPresent()) { for (Content contentBlock : outputStep.content().get()) { if (contentBlock instanceof AudioContent) { AudioContent audioBlock = (AudioContent) contentBlock; if (audioBlock.data().isPresent()) { audioData = Base64.getDecoder().decode(audioBlock.data().get()); } } else if (contentBlock instanceof TextContent) { TextContent textBlock = (TextContent) contentBlock; textBlock.text().ifPresent(lyrics::add); } } } } } } if (!lyrics.isEmpty()) { System.out.println("Lyrics:\n" + String.join("\n", lyrics)); } if (audioData != null) { Files.write(Paths.get("output.mp3"), audioData); } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "fmt" "log" "os" "strings" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("lyria-3.5"), Input: interactions.NewInteractionsInput("A song about a starry night."), }), }) if err != nil { log.Fatal(err) } var lyrics []string var audioData []byte for _, step := range res.Interaction.Steps { if step.ModelOutputStep != nil { for _, contentBlock := range step.ModelOutputStep.Content { if contentBlock.AudioContent != nil && contentBlock.AudioContent.Data != nil { decoded, err := base64.StdEncoding.DecodeString(*contentBlock.AudioContent.Data) if err != nil { log.Fatal(err) } audioData = decoded } else if contentBlock.TextContent != nil { lyrics = append(lyrics, contentBlock.TextContent.Text) } } } } if len(lyrics) > 0 { fmt.Printf("Lyrics:\n%s\n", strings.Join(lyrics, "\n")) } if audioData != nil { if err := os.WriteFile("output.mp3", audioData, 0644); err != nil { log.Fatal(err) } } } ``` {% /tab %} {% /tabs %} ## Generate music from images {% id="image-to-music" %} Lyria 3.5 supports multimodal inputs - you can provide up to **10 images** alongside your text prompt in the `input` list and the model will compose music inspired by the visual content. {% tabs %} {% tab label="Python" %} ```python import base64 with open("desert_sunset.jpg", "rb") as f: image_bytes = f.read() image_b64 = base64.b64encode(image_bytes).decode("utf-8") response = client.interactions.create( model="lyria-3.5", input=[ { "type": "text", "text": "An atmospheric ambient track inspired by the mood and colors in this image.", }, { "type": "image", "mime_type": "image/jpeg", "data": image_b64, }, ], ) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import * as fs from "fs"; const imageBytes = fs.readFileSync("desert_sunset.jpg").toString("base64"); const interaction = await client.interactions.create({ model: "lyria-3.5", input: [ { type: "text", text: "An atmospheric ambient track inspired by the mood and colors in this image.", }, { type: "image", mime_type: "image/jpeg", data: imageBytes, }, ], }); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.ImageContentMimeType; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; import java.util.List; Client client = new Client(); byte[] imageBytes = Files.readAllBytes(Paths.get("desert_sunset.jpg")); String imageB64 = Base64.getEncoder().encodeToString(imageBytes); Content textContent = TextContent.builder() .text("An atmospheric ambient track inspired by the mood and colors in this image.") .build(); Content imageContent = ImageContent.builder() .mimeType(ImageContentMimeType.IMAGE_JPEG) .data(imageB64) .build(); List contents = Arrays.asList(textContent, imageContent); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("lyria-3.5")) .input(InteractionsInput.ofContent(contents)) .build(); Interaction response = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/base64" "log" "os" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } imageBytes, err := os.ReadFile("desert_sunset.jpg") if err != nil { log.Fatal(err) } imageB64 := base64.StdEncoding.EncodeToString(imageBytes) contents := []interactions.Content{ interactions.NewContent(interactions.TextContent{ Text: "An atmospheric ambient track inspired by the mood and colors in this image.", }), interactions.NewContent(interactions.ImageContent{ MimeType: interactions.ImageContentMimeTypeImageJpeg.ToPointer(), Data: genai.Ptr(imageB64), }), } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("lyria-3.5"), Input: interactions.NewInteractionsInput(contents), }), }) if err != nil { log.Fatal(err) } _ = res } ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Api-Revision: 2026-05-20" \ -H 'Content-Type: application/json' \ -d '{ "model": "lyria-3.5", "input": [ {"type": "text", "text": "An atmospheric ambient track inspired by the mood and colors in this image."}, {"type": "image", "mime_type": "image/jpeg", "data": "/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAP//////////////////////////////////////////////////////////////////////////////////////wgALCAABAAEBAREA/8QAFBABAAAAAAAAAAAAAAAAAAAAAP/aAAgBAQABPxA="} ] }' ``` {% /tab %} {% /tabs %} ## Provide custom lyrics {% id="custom-lyrics" %} You can write your own lyrics and include them in the prompt. Use section tags like `[Verse]`, `[Chorus]`, and `[Bridge]` to help the model understand the song structure: {% tabs %} {% tab label="Python" %} ```python prompt = """ Create a dreamy indie pop song with the following lyrics: [Verse 1] Walking through the neon glow, city lights reflect below, every shadow tells a story, every corner, fading glory. [Chorus] We are the echoes in the night, burning brighter than the light, hold on tight, don't let me go, we are the echoes down below. [Verse 2] Footsteps lost on empty streets, rhythms sync to heartbeats, whispers carried by the breeze, dancing through the autumn leaves. """ interaction = client.interactions.create( model="lyria-3.5", input=prompt, ) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript const prompt = ` Create a dreamy indie pop song with the following lyrics: [Verse 1] Walking through the neon glow, city lights reflect below, every shadow tells a story, every corner, fading glory. [Chorus] We are the echoes in the night, burning brighter than the light, hold on tight, don't let me go, we are the echoes down below. [Verse 2] Footsteps lost on empty streets, rhythms sync to heartbeats, whispers carried by the breeze, dancing through the autumn leaves. `; const interaction = await client.interactions.create({ model: 'lyria-3.5', input: prompt, }); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; Client client = new Client(); String prompt = "Create a dreamy indie pop song with the following lyrics:\n\n" + "[Verse 1]\n" + "Walking through the neon glow,\n" + "city lights reflect below,\n" + "every shadow tells a story,\n" + "every corner, fading glory.\n\n" + "[Chorus]\n" + "We are the echoes in the night,\n" + "burning brighter than the light,\n" + "hold on tight, don't let me go,\n" + "we are the echoes down below.\n\n" + "[Verse 2]\n" + "Footsteps lost on empty streets,\n" + "rhythms sync to heartbeats,\n" + "whispers carried by the breeze,\n" + "dancing through the autumn leaves."; CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("lyria-3.5")) .input(InteractionsInput.of(prompt)) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } prompt := "Create a dreamy indie pop song with the following lyrics:\n\n" + "[Verse 1]\n" + "Walking through the neon glow,\n" + "city lights reflect below,\n" + "every shadow tells a story,\n" + "every corner, fading glory.\n\n" + "[Chorus]\n" + "We are the echoes in the night,\n" + "burning brighter than the light,\n" + "hold on tight, don't let me go,\n" + "we are the echoes down below.\n\n" + "[Verse 2]\n" + "Footsteps lost on empty streets,\n" + "rhythms sync to heartbeats,\n" + "whispers carried by the breeze,\n" + "dancing through the autumn leaves." res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("lyria-3.5"), Input: interactions.NewInteractionsInput(prompt), }), }) if err != nil { log.Fatal(err) } _ = res } ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Api-Revision: 2026-05-20" \ -H "Content-Type: application/json" \ -d '{ "model": "lyria-3.5", "input": "Create a dreamy indie pop song with the following lyrics: ..." }' ``` {% /tab %} {% /tabs %} ## Control timing and structure {% id="timing" %} You can specify exactly what happens at specific moments in the song using timestamps. This is useful for controlling when instruments enter, when lyrics are delivered, and how the song progresses: {% tabs %} {% tab label="Python" %} ```python prompt = """ [0:00 - 0:10] Intro: Begin with a soft lo-fi beat and muffled vinyl crackle. [0:10 - 0:30] Verse 1: Add a warm Fender Rhodes piano melody and gentle vocals singing about a rainy morning. [0:30 - 0:50] Chorus: Full band with upbeat drums and soaring synth leads. The lyrics are hopeful and uplifting. [0:50 - 1:00] Outro: Fade out with the piano melody alone. """ interaction = client.interactions.create( model="lyria-3.5", input=prompt, ) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript const prompt = ` [0:00 - 0:10] Intro: Begin with a soft lo-fi beat and muffled vinyl crackle. [0:10 - 0:30] Verse 1: Add a warm Fender Rhodes piano melody and gentle vocals singing about a rainy morning. [0:30 - 0:50] Chorus: Full band with upbeat drums and soaring synth leads. The lyrics are hopeful and uplifting. [0:50 - 1:00] Outro: Fade out with the piano melody alone. `; const interaction = await client.interactions.create({ model: 'lyria-3.5', input: prompt, }); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; Client client = new Client(); String prompt = "[0:00 - 0:10] Intro: Begin with a soft lo-fi beat and muffled vinyl crackle.\n" + "[0:10 - 0:30] Verse 1: Add a warm Fender Rhodes piano melody and gentle vocals singing about a rainy morning.\n" + "[0:30 - 0:50] Chorus: Full band with upbeat drums and soaring synth leads. The lyrics are hopeful and uplifting.\n" + "[0:50 - 1:00] Outro: Fade out with the piano melody alone."; CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("lyria-3.5")) .input(InteractionsInput.of(prompt)) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } prompt := "[0:00 - 0:10] Intro: Begin with a soft lo-fi beat and muffled vinyl crackle.\n" + "[0:10 - 0:30] Verse 1: Add a warm Fender Rhodes piano melody and gentle vocals singing about a rainy morning.\n" + "[0:30 - 0:50] Chorus: Full band with upbeat drums and soaring synth leads. The lyrics are hopeful and uplifting.\n" + "[0:50 - 1:00] Outro: Fade out with the piano melody alone." res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("lyria-3.5"), Input: interactions.NewInteractionsInput(prompt), }), }) if err != nil { log.Fatal(err) } _ = res } ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Api-Revision: 2026-05-20" \ -H "Content-Type: application/json" \ -d '{ "model": "lyria-3.5", "input": "[0:00 - 0:10] Intro: ..." }' ``` {% /tab %} {% /tabs %} ## Generate instrumental tracks {% id="instrumental" %} For background music, game soundtracks, or any use case where vocals are not required, you can prompt the model to produce instrumental-only tracks: {% tabs %} {% tab label="Python" %} ```python interaction = client.interactions.create( model="lyria-3-clip-preview", input="A bright chiptune melody in C Major, retro 8-bit video game style. Instrumental only, no vocals.", ) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript const interaction = await client.interactions.create({ model: 'lyria-3-clip-preview', input: 'A bright chiptune melody in C Major, retro 8-bit video game style. Instrumental only, no vocals.', }); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("lyria-3-clip-preview")) .input( InteractionsInput.of( "A bright chiptune melody in C Major, retro 8-bit video game style. Instrumental only, no vocals.")) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("lyria-3-clip-preview"), Input: interactions.NewInteractionsInput( "A bright chiptune melody in C Major, retro 8-bit video game style. Instrumental only, no vocals.", ), }), }) if err != nil { log.Fatal(err) } _ = res } ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Api-Revision: 2026-05-20" \ -H "Content-Type: application/json" \ -d '{ "model": "lyria-3-clip-preview", "input": "A bright chiptune melody in C Major, retro 8-bit video game style. Instrumental only, no vocals." }' ``` {% /tab %} {% /tabs %} ## Generate music in different languages {% id="languages" %} Lyria 3.5 generates lyrics in the language of your prompt. To generate a song with French lyrics, write your prompt in French. The model adapts its vocal style and pronunciation to match the language. {% tabs %} {% tab label="Python" %} ```python interaction = client.interactions.create( model="lyria-3.5", input="Crée une chanson pop romantique en français sur un coucher de soleil à Paris. Utilise du piano et de la guitare acoustique.", ) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript const interaction = await client.interactions.create({ model: 'lyria-3.5', input: 'Crée une chanson pop romantique en français sur un coucher de soleil à Paris. Utilise du piano et de la guitare acoustique.', }); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; Client client = new Client(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("lyria-3.5")) .input( InteractionsInput.of( "Crée une chanson pop romantique en français sur un coucher de soleil à Paris. Utilise du piano et de la guitare acoustique.")) .build(); Interaction interaction = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("lyria-3.5"), Input: interactions.NewInteractionsInput( "Crée une chanson pop romantique en français sur un coucher de soleil à Paris. Utilise du piano et de la guitare acoustique.", ), }), }) if err != nil { log.Fatal(err) } _ = res } ``` {% /tab %} {% tab label="REST" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Api-Revision: 2026-05-20" \ -H "Content-Type: application/json" \ -d '{ "model": "lyria-3.5", "input": "Crée une chanson pop romantique en français sur un coucher de soleil à Paris. Utilise du piano et de la guitare acoustique." }' ``` {% /tab %} {% /tabs %} ## Model intelligence {% id="intelligence" %} Lyria 3.5 analyzes your prompt process where the model reasons through musical structure (intro, verse, chorus, bridge, etc.) based on your prompt. This happens before the audio is generated and ensures structural coherence and musicality. Important: While Lyria 3.5 uses a prompt rewriter internally to interpret natural language instructions, it does **not** expose intermediate "thought" blocks or thought signatures to the user. ## Prompting guide {% id="prompt-guide" %} To learn how to craft effective prompts for music genres, instruments, song structure, custom lyrics, and vocal delivery styles, see the [Lyria prompt guide](/docs/lyria-prompt-guide). ## Best practices {% id="best-practices" %} * **Iterate with Clip first.** Use the faster `lyria-3-clip-preview` model to experiment with prompts before committing to a full-length generation with `lyria-3.5`. * **Be specific.** Vague prompts produce generic results. Mention instruments, BPM, key, mood, and structure for the best output. * **Match your language.** Prompt in the language you want the lyrics in. * **Use section tags.** `[Verse]`, `[Chorus]`, `[Bridge]` tags give the model clear structure to follow. * **Separate lyrics from instructions.** When providing custom lyrics, clearly separate them from your musical direction instructions. ## Limitations {% id="limitations" %} * **Safety**: All prompts are checked by safety filters. Prompts that trigger the filters will be blocked. This includes prompts that request specific artist voices or the generation of copyrighted lyrics. * **Watermarking**: All generated audio includes a [SynthID audio watermark](https://ai.google.dev/responsible/docs/safeguards/synthid) for identification. This watermark is imperceptible to the human ear and does not affect the listening experience. * **Multi-turn editing**: Music generation is a single-turn process. Iterative editing or refining a generated clip through multiple prompts is not supported in the current version of Lyria 3.5. * **Length**: The Clip model always generates 30-second clips. The Pro model generates songs that last a couple of minutes; exact duration can be influenced through your prompt. * **Determinism**: Results may vary between calls, even with the same prompt. ## What's next {% id="next-steps" %} * See the [Lyria prompt guide](/docs/lyria-prompt-guide) for in-depth prompting strategies and keyword vocabularies, * Check [pricing](/docs/pricing) for Lyria 3.5 models, * Try [real-time, streaming music generation](/docs/realtime-music-generation) with Lyria RealTime, * Generate multi-speaker conversations with the [TTS models](/docs/speech-generation), * Discover how to generate [images](/docs/image-generation) or [videos](/docs/video), * Find out how Gemini can [understand audio files](/docs/audio), * Have a real-time conversation with Gemini using the [Live API](/docs/live-api). # Real-time music generation using Lyria RealTime Source: https://aistudio.google.com/docs/realtime-music-generation Description: Get started building with Lyria RealTime's real-time, streaming music generation in the Gemini API {% callout type="note" %} Lyria RealTime is an [experimental model](/docs/models#experimental). {% /callout %} The Gemini API, using [Lyria Realtime](https://deepmind.google/technologies/lyria/realtime/), provides access to a state-of-the-art, real-time, streaming music generation model. It allows developers to build applications where users can interactively create, continuously steer, and perform instrumental music. Lyria Realtime music generation uses a persistent, bidirectional, low-latency streaming connection using [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API). To experience what can be built using Lyria Realtime, try it on AI Studio using the [Prompt DJ](https://aistudio.google.com/apps/bundled/promptdj) or the [MIDI DJ](https://aistudio.google.com/apps/bundled/promptdj-midi) apps. {% callout type="note" %} Looking for non-streaming music generation? See [Generate music with Lyria 3.5](/docs/music-generation). {% /callout %} ## Generate and control music {% id="generate-music" %} Lyria Realtime works similarly to the [Multimodal Live API](/docs/live-api) in that it uses Websockets to maintain real-time communication with the model. The following code demonstrates how to generate music: {% tabs %} {% tab label="Python" filename="sample.py" %} This example initializes the Lyria Realtime session using `client.aio.live.music.connect()`, then sends an initial prompt with `session.set_weighted_prompts()` along with an initial configuration using `session.set_music_generation_config`, starts the music generation using `session.play()` and sets up `receive_audio()` to process the audio chunks it receives. ```python import asyncio from google import genai from google.genai import types client = genai.Client(http_options={'api_version': 'v1beta'}) async def main(): async def receive_audio(session): """Example background task to process incoming audio.""" while True: async for message in session.receive(): audio_data = message.server_content.audio_chunks[0].data # Process audio... await asyncio.sleep(10**-12) async with ( client.aio.live.music.connect(model='models/lyria-realtime-exp') as session, asyncio.TaskGroup() as tg, ): # Set up task to receive server messages. tg.create_task(receive_audio(session)) # Send initial prompts and config await session.set_weighted_prompts( prompts=[ types.WeightedPrompt(text='minimal techno', weight=1.0), ] ) await session.set_music_generation_config( config=types.LiveMusicGenerationConfig(bpm=90, temperature=1.0) ) # Start streaming music await session.play() if __name__ == "__main__": asyncio.run(main()) ``` Objective: For a more complete code sample, refer to the [Lyria RealTime - Get Started](https://colab.sandbox.google.com/github/google-gemini/cookbook/blob/main/quickstarts/Get_started_LyriaRealTime.ipynb) file in the cookbooks repository. {% /tab %} {% tab label="JavaScript" filename="sample.js" %} This example initializes the Lyria Realtime session using `client.live.music.connect()`, then sends an initial prompt with `session.setWeightedPrompts()` along with an initial configuration using `session.setMusicGenerationConfig`, starts the music generation using `session.play()` and sets up an `onMessage` callback to process the audio chunks it receives. ```javascript import { GoogleGenAI } from "@google/genai"; import Speaker from "speaker"; const client = new GoogleGenAI({ apiKey: GEMINI_API_KEY, apiVersion: "v1beta" , }); async function main() { const speaker = new Speaker({ channels: 2, // stereo bitDepth: 16, // 16-bit PCM sampleRate: 44100, // 44.1 kHz }); const session = await client.live.music.connect({ model: "models/lyria-realtime-exp", callbacks: { onmessage: (message) => { if (message.serverContent?.audioChunks) { for (const chunk of message.serverContent.audioChunks) { if (chunk.data) { const audioBuffer = Buffer.from(chunk.data, "base64"); speaker.write(audioBuffer); } } } }, onerror: (error) => console.error("music session error:", error), onclose: () => console.log("Lyria RealTime stream closed."), }, }); await session.setWeightedPrompts({ weightedPrompts: [ { text: "Minimal techno with deep bass, sparse percussion, and atmospheric synths", weight: 1.0 }, ], }); await session.setMusicGenerationConfig({ musicGenerationConfig: { bpm: 90, temperature: 1.0, }, }); await session.play(); } await main(); ``` Objective: For a more complete code sample, try the [Prompt DJ](https://aistudio.google.com/apps/bundled/promptdj) and [MIDI DJ](https://aistudio.google.com/apps/bundled/promptdj-midi) apps on AI Studio You can then use `session.play()`, `session.pause()`, `session.stop()` and `session.reset_context()` to start, pause, stop or reset the session. {% /tab %} {% /tabs %} ## Steer music in real-time {% id="steer-music" %} You can steer music generation in real-time by sending prompts and updating generation parameters in real time. ### Prompt Lyria Realtime {% id="prompting-lyria" %} While the stream is active, you can send new `WeightedPrompt` messages at any time to alter the generated music. The model will smoothly transition based on the new input. The prompts need to follow the right format with a `text` (the actual prompt), and a `weight`. The `weight` can take any value except `0`. `1.0` is usually a good starting point. {% tabs %} {% tab label="Python" filename="sample.py" %} ```python from google.genai import types await session.set_weighted_prompts( prompts=[ {"text": "Piano", "weight": 2.0}, types.WeightedPrompt(text="Meditation", weight=0.5), types.WeightedPrompt(text="Live Performance", weight=1.0), ] ) ``` {% /tab %} {% tab label="JavaScript" filename="sample.js" %} ```javaScript await session.setWeightedPrompts({ weightedPrompts: [ { text: 'Harmonica', weight: 0.3 }, { text: 'Afrobeat', weight: 0.7 } ], }); ``` Note that the model transitions can be a bit abrupt when drastically changing the prompts so it's recommended to implement some kind of cross-fading by sending intermediate weight values to the model. {% /tab %} {% /tabs %} ### Update the configuration {% id="steer-config" %} You can steer music generation by updating the music generation parameters in real time. You can't just update a parameter, you need to set the whole configuration otherwise the other fields will be reset back to their default values. Since updating the bpm or the scale is a drastic change for the model you'll also need to tell it to reset its context using `reset_context()` to take the new config into account. It won't stop the stream, but it will be a hard transition. You don't need to do it for the other parameters. {% tabs %} {% tab label="Python" filename="sample.py" %} ```python from google.genai import types await session.set_music_generation_config( config=types.LiveMusicGenerationConfig( bpm=128, scale=types.Scale.D_MAJOR_B_MINOR, music_generation_mode=types.MusicGenerationMode.QUALITY ) ) await session.reset_context(); ``` {% /tab %} {% tab label="JavaScript" filename="sample.js" %} ```javaScript await session.setMusicGenerationConfig({ musicGenerationConfig: { bpm: 120, density: 0.75, musicGenerationMode: MusicGenerationMode.QUALITY }, }); await session.reset_context(); ``` {% /tab %} {% /tabs %} ## Prompting Lyria RealTime {% id="prompting-lyria-realtime" %} Lyria RealTime uses weighted prompts to blend musical genres, instruments, and moods dynamically. To explore prompt steering strategies, keyword tag vocabularies, and full prompt examples, see the [Lyria prompt guide](/docs/lyria-prompt-guide#realtime-prompting). ## Best practices {% id="best-practices-music" %} * Client applications must implement robust audio buffering to ensure smooth playback. This helps account for network jitter and slight variations in generation latency. * Effective prompting: * Be descriptive. Use adjectives describing mood, genre, and instrumentation. * Iterate and steer gradually. Rather than completely changing the prompt, try adding or modifying elements to morph the music more smoothly. * Experiment with weight on `WeightedPrompt` to influence how strongly a new prompt affects the ongoing generation. ## Technical details {% id="technical-details-music" %} This section describes the specifics of how to use Lyria Realtime music generation. ### Specifications {% id="audio-specs" %} * Output format: Raw 16-bit PCM Audio * Sample rate: 48kHz * Channels: 2 (stereo) ### Controls {% id="controls" %} Music generation can be influenced in real time by sending messages containing: * `WeightedPrompt`: A text string describing a musical idea, genre, instrument, mood, or characteristic. Multiple prompts can potentially be supplied to blend influences. See [above](/docs/realtime-music-generation#steer-music) for more details on how to best prompt Lyria Realtime. * `MusicGenerationConfig`: Configuration for the music generation process, influencing the characteristics of the output audio.). Parameters include: * `guidance`: (float) Range: `[0.0, 6.0]`. Default: `4.0`. Controls how strictly the model follows the prompts. Higher guidance improves adherence to the prompt, but makes transitions more abrupt. * `bpm`: (int) Range: `[60, 200]`. Sets the Beats Per Minute you want for the generated music. You need to stop/play or reset the context for the model it take into account the new bpm. * `density`: (float) Range: `[0.0, 1.0]`. Controls the density of musical notes/sounds. Lower values produce sparser music; higher values produce "busier" music. * `brightness`: (float) Range: `[0.0, 1.0]`. Adjusts the tonal quality. Higher values produce "brighter" sounding audio, generally emphasizing higher frequencies. * `scale`: (Enum) Sets the musical scale (Key and Mode) for the generation. Use the [`Scale` enum values](/docs/realtime-music-generation#scale-enum) provided by the SDK. You need to stop/play or reset the context for the model it take into account the new scale. * `mute_bass`: (bool) Default: `False`. Controls whether the model reduces the outputs' bass. * `mute_drums`: (bool) Default: `False`. Controls whether the model outputs reduces the outputs' drums. * `only_bass_and_drums`: (bool) Default: `False`. Steer the model to try to only output bass and drums. * `music_generation_mode`: (Enum) Indicates to the model if it should focus on `QUALITY` (default value) or `DIVERSITY` of music. It can also be set to `VOCALIZATION` to let the model generate vocalizations as another instrument (add them as new pompts). * `PlaybackControl`: Commands to control playback aspects, such as play, pause, stop or reset the context. For `bpm`, `density`, `brightness` and `scale`, if no value is provided, the model will decide what's best according to your initial prompts. More classical parameters like `temperature` (0.0 to 3.0, default 1.1), `top_k` (1 to 1000, default 40), and `seed` (0 to 2 147 483 647, randomly selected by default) are also customizable in the `MusicGenerationConfig`. #### Scale Enum Values {% id="scale-enum" %} Here are all the scale values that the model can accept: | Enum Value | Scale / Key | | :--- | :--- | | `C_MAJOR_A_MINOR` | C major / A minor | | `D_FLAT_MAJOR_B_FLAT_MINOR`| D♭ major / B♭ minor | | `D_MAJOR_B_MINOR` | D major / B minor | | `E_FLAT_MAJOR_C_MINOR` | E♭ major / C minor | | `E_MAJOR_D_FLAT_MINOR` | E major / C♯/D♭ minor | | `F_MAJOR_D_MINOR` | F major / D minor | | `G_FLAT_MAJOR_E_FLAT_MINOR`| G♭ major / E♭ minor | | `G_MAJOR_E_MINOR` | G major / E minor | | `A_FLAT_MAJOR_F_MINOR` | A♭ major / F minor | | `A_MAJOR_G_FLAT_MINOR` | A major / F♯/G♭ minor | | `B_FLAT_MAJOR_G_MINOR` | B♭ major / G minor | | `B_MAJOR_A_FLAT_MINOR` | B major / G♯/A♭ minor | | `SCALE_UNSPECIFIED` | Default / The model decides | The model is capable of guiding the notes that are played, but does not distinguish between relative keys. Thus each enum corresponds both to the relative major and minor. For example, `C_MAJOR_A_MINOR` would correspond to all the white keys of a piano, and `F_MAJOR_D_MINOR` would be all the white keys except B flat. ### Limitations {% id="limitations" %} * Instrumental only: The model generates instrumental music only. * Safety: Prompts are checked by safety filters. Prompts triggering the filters will be ignored in which case an explanation will be written in the output's `filtered_prompt` field. * Watermarking: Output audio is always watermarked for identification following our [Responsible AI](https://ai.google/responsibility/principles/) principles. ## What's next {% id="next-steps" %} * See the [Lyria prompt guide](/docs/lyria-prompt-guide) for prompting strategies and keyword vocabularies, * Generate full songs and vocal tracks with [Lyria 3.5](/docs/music-generation), * Instead of music, learn how to generate multi-speakers conversation using the [TTS models](/docs/speech-generation), * Discover how to generate [images](/docs/image-generation) or [videos](/docs/video), * Instead of generation music or audio, find out how to Gemini can [understand Audio files](/docs/audio), * Have a real-time conversation with Gemini using the [Multimodal Live API](/docs/live-api). Explore the [Cookbook](https://github.com/google-gemini/cookbook) for more code examples and tutorials. # Lyria prompt guide Source: https://aistudio.google.com/docs/lyria-prompt-guide Description: Guide to prompt engineering for music generation with Lyria 3.5 and Lyria RealTime in the Gemini API. The Gemini API offers two ways to generate music with Lyria: * **Lyria 3.5 & Lyria 3 Clip**: Non-streaming generation for 30-second clips or full-length songs with lyrics and vocals. See [Generate music with Lyria 3.5](/docs/music-generation). * **Lyria RealTime**: Real-time, interactive music streaming and live steering over WebSockets. See [Real-time music generation with Lyria RealTime](/docs/realtime-music-generation). Both models respond to descriptive text prompts, musical terminology, and structural directions. This guide covers how to write effective prompts for both batch generation and real-time steering. ## Prompt fundamentals {% id="prompt-fundamentals" %} Your prompt can be a short phrase: ```none A folk song about cute cats avoiding puddles, female vocals, acoustic guitar, sound of rain ``` Or a structured, detailed description: ```none A 1980s-style synth-pop track with a driving beat, shimmering synthesizers, and a catchy, anthemic chorus. The song should have a retro-futuristic feel with modern production polish. Upbeat tempo around 120 BPM, clear verse-chorus structure, and a memorable instrumental hook. The lyrics describe getting ready for a party. ``` Both short and detailed prompts produce strong results. Use the following strategies to guide the model toward the exact sound you want. ## Genre and style {% id="genre-and-style" %} Lead your prompt with the primary genre. You can combine genres to create unique hybrids: * A fusion of metal and hip-hop * Death metal combined with operatic vocals * Classical chamber music with dark electronic drone elements * Modern electronic dance music (EDM) mixed with Europop You can also specify a musical era or regional variant: * Early 1990s boom-bap hip-hop * 1960s French yé-yé pop * 1980s post-punk and new wave * 2000s mainstream R&B * Berlin minimal techno or Bay Area hyphy ### Genre keywords {% id="genre-keywords" %} Use these recognized genre terms in your prompts for Lyria 3.5 and Lyria RealTime: * **Electronic & Dance**: `Acid House, Breakbeat, Chillout, Chiptune, Deep House, Drum & Bass, Dubstep, EDM, Electro Swing, Glitch Hop, Hyperpop, Minimal Techno, Moombahton, Psytrance, Synthpop, Techno, Trance, Trip Hop, Vaporwave` * **Hip-Hop & R&B**: `808 Hip Hop, Boom-Bap, Contemporary R&B, G-funk, Grime, Lo-Fi Hip Hop, Neo-Soul, New Jack Swing, Trap Beat` * **Rock & Alternative**: `Alternative Country, Blues Rock, Classic Rock, Funk Metal, Garage Rock, Indie Folk, Indie Pop, Post-Punk, 60s Psychedelic Rock, Shoegaze, Surf Rock` * **Jazz, Soul & Funk**: `Acid Jazz, Afrobeat, Bossa Nova, Disco Funk, Funk, Jazz Fusion, Latin Jazz` * **Folk & Traditional**: `Bengal Baul, Bhangra, Bluegrass, Celtic Folk, Cumbia, Indian Classical, Irish Folk, Merengue, Polka, Reggae, Reggaeton, Renaissance Music, Salsa` * **Classical & Acoustic**: `Baroque, Orchestral Score, Piano Ballad` ## Instruments and textures {% id="instruments-and-textures" %} Lyria selects appropriate instrumentation for the requested genre automatically. If you want specific instruments or unusual combinations, declare them explicitly: ```none A dance track with a driving beat, shimmering synthesizers, and a catchy, anthemic chorus. A saxophone solo enters during the bridge. ``` Describe how instruments sound and interact to set mood and texture: * A distorted 303 bassline cutting through crisp, tight hi-hats * Warm, analog synth pads swelling beneath a dry, intimate acoustic guitar * A wall of sound built from multiple layers of fuzz guitar, with distant, reverb-soaked vocals ### Instrument keywords {% id="instrument-keywords" %} * **Keyboards & Synths**: `Buchla Synths, Clavichord, Dirty Synths, Harpsichord, Mellotron, Moog Oscillations, Ragtime Piano, Rhodes Piano, Smooth Pianos, Spacey Synths, Synth Pads` * **Bass & Drums**: `303 Acid Bass, 808 Hip Hop Beat, Boomy Bass, Conga Drums, Drumline, Funk Drums, Precision Bass, Tabla, TR-909 Drum Machine` * **Guitars & Strings**: `Banjo, Balalaika, Bouzouki, Cello, Charango, Dulcimer, Fiddle, Flamenco Guitar, Guitar, Harp, Koto, Lyre, Mandolin, Pipa, Shamisen, Shredding Guitar, Sitar, Slide Guitar, Viola Ensemble, Warm Acoustic Guitar` * **Wind & Brass**: `Alto Saxophone, Bagpipes, Bass Clarinet, Didgeridoo, Harmonica, Ocarina, Trumpet, Tuba, Woodwinds` * **Percussion**: `Bongos, Djembe, Glockenspiel, Hang Drum, Kalimba, Maracas, Marimba, Mbira, Steel Drum, Vibraphone` ## Song structure and timing {% id="structure-and-timing" %} For Lyria 3.5, define song progression using tags or arrows: * `[Intro] -> [Verse 1] -> [Chorus] -> [Verse 2] -> [Chorus] -> [Bridge] -> [Outro]` * Start with a quiet piano intro, build into an energetic verse, pause for a moment of silence, then explode into the chorus. You can direct energy dynamics and transitions: * Build tension through the pre-chorus, then drop to silence before an explosive chorus * Gradual crescendo throughout the song, adding one instrument per section * A sudden stop after the bridge, followed by an a cappella chorus You can also prompt specific timing markers: * Build to a beat drop at 12 seconds * Vocal sample repeats every 4 bars * The chorus kicks in at 22 seconds ## Lyrics and vocals {% id="lyrics-and-vocals" %} Lyria 3.5 generates vocal tracks with lyrics by default. You can provide your own lyrics, ask the model to generate them, or request an instrumental track. ### Using your own lyrics {% id="own-lyrics" %} Include your lyrics directly in the prompt beneath a `Lyrics:` header. Tag each section to guide vocal delivery: ```none Lyrics: [Intro] Ooooh, yeah [Verse 1] Early morning rain on the window pane City lights wash away the pain Walking down this empty street again [Chorus] We keep moving on (moving on) Until the morning light Everything will be alright ``` Use parentheses for backing vocals, echoes, or ad-libs, like `(moving on)`. ### Directing generated lyrics {% id="generated-lyrics" %} When asking Lyria 3.5 to write lyrics, outline the narrative, emotion, or key phrases: ```none The lyrics describe driving down the Pacific Coast Highway at sunset. The mood is nostalgic and reflective. Include an uplifting, anthemic chorus about second chances and starting over. ``` For electronic and dance genres, request short repeating vocal hooks: ```none An upbeat dance-pop track with a repetitive, high-energy vocal hook: "Feel the rhythm all night long." ``` ### Vocal delivery and singer profiles {% id="vocal-delivery" %} Specify gender, vocal range, and timbre for precise delivery: * **Female Soprano**: Clear, crystalline timbre with an agile, soaring delivery. Bright tone capable of airy, breathy textures. * **Female Alto**: Rich, warm, and husky lower range. Smoky timbre with a soulful, resonant chest voice. * **Male Tenor**: Bright, piercing, and energetic. Youthful timbre with high belting power that cuts through dense mixes. * **Male Baritone**: Deep, velvet-smooth chest voice with a warm, soothing, crooning delivery. * **Weathered Rocker**: Raspy, gritty timbre reminiscent of 1990s alternative rock. Raw emotional intensity with strained upper notes. ### Non-lyrical vocal effects {% id="vocal-effects" %} You can also prompt for spoken dialogue, vocal chops, and sampling effects: * A vintage radio broadcast voice introduces the song before the beat kicks in * A spoken voice whispers right before the drop, followed by high-energy synths * Chopped, pitch-shifted vocal samples looping as an instrumental rhythm element ## Musical parameters {% id="musical-parameters" %} Refine your prompt with standard musical properties: * **Tempo (BPM)**: Set the tempo directly (e.g. `120 BPM`, `slow tempo around 72 BPM`, `fast 160 BPM`). * **Key and Scale**: Specify the root key and tonality (e.g. `in G major`, `in D minor`, `in C pentatonic`). * **Mood and Atmosphere**: Use descriptive emotional adjectives: `Ambient, Bright, Chill, Dark, Dreamy, Emotional, Ethereal, Euphoric, Funky, Groovy, Melancholic, Nostalgic, Ominous, Psychedelic, Relaxed, Soulful, Triumphant, Upbeat, Whimsical` ## Prompting Lyria RealTime {% id="realtime-prompting" %} Lyria RealTime uses **weighted prompts** rather than a single monolithic prompt string. This lets you blend multiple musical influences dynamically and steer music continuously over a WebSocket connection. ### Weighted prompt structure {% id="weighted-prompts" %} Each weighted prompt consists of a descriptive text phrase and a floating-point weight: ```python prompts = [ types.WeightedPrompt(text="minimal techno", weight=1.0), types.WeightedPrompt(text="deep sub bass", weight=0.6), types.WeightedPrompt(text="shimmering hi-hats", weight=0.4), ] ``` ### Real-time steering strategies {% id="steering-strategies" %} * **Blending genres**: Blend distinct styles by assigning balanced weights: * `ambient synth pads (weight: 0.8)` + `lo-fi hip-hop drums (weight: 0.6)` * `flamenco guitar (weight: 0.7)` + `deep house groove (weight: 0.5)` * **Dynamic transitions**: To transition the music smoothly, adjust prompt weights over time: 1. Start with `chill jazz piano (weight: 1.0)`. 2. Gradually add `electronic breakbeat (weight: 0.3)`. 3. Increase `electronic breakbeat` to `0.8` while lowering `chill jazz piano` to `0.3`. * **Layering elements**: Keep instrument tags and mood tags separate so you can adjust them independently: * Prompt 1: `bossa nova guitar (weight: 0.9)` * Prompt 2: `warm acoustic bass (weight: 0.7)` * Prompt 3: `subtle vinyl crackle (weight: 0.3)` ## Example prompts {% id="example-prompts" %} ### Lyria 3.5 examples * **Lo-Fi Study Beat**: ```none A 30-second lofi hip hop beat with dusty vinyl crackle, mellow Rhodes piano chords, a relaxed boom-bap drum groove at 82 BPM, and a warm upright bassline. Instrumental only. ``` * **Pop Anthem**: ```none An upbeat, feel-good indie-pop song in G major at 122 BPM. Bright acoustic guitar strumming, driving kick drum, handclaps, and warm female vocal harmonies. The lyrics describe an unforgettable summer road trip with friends. ``` * **Cinematic Cyberpunk**: ```none Dark, cinematic cyberpunk synthwave at 110 BPM in D minor. Heavy distorted bass, ominous arpeggiated analog synthesizers, distant metallic percussion, and an ethereal female vocalise swelling during the climax. ``` ### Lyria RealTime steering set ```python # Initial high-energy groove await session.set_weighted_prompts( prompts=[ types.WeightedPrompt(text="techno groove", weight=1.0), types.WeightedPrompt(text="acid 303 bass", weight=0.8), ] ) # Transition to a melodic breakdown await session.set_weighted_prompts( prompts=[ types.WeightedPrompt(text="ambient synth pads", weight=1.0), types.WeightedPrompt(text="subtle reverberant piano", weight=0.7), types.WeightedPrompt(text="techno groove", weight=0.2), ] ) ``` ## What's next {% id="whats-next" %} * [Generate music with Lyria 3.5](/docs/music-generation): Generate full songs and 30-second clips using the Interactions API. * [Real-time music generation with Lyria RealTime](/docs/realtime-music-generation): Build real-time, interactive music streaming applications over WebSockets. # Generate images using Imagen Source: https://aistudio.google.com/docs/imagen Description: Imagen models are shut down; migrate to Nano Banana for image generation. {% callout type="warning" %} Imagen models are shut down. Use Nano Banana for image generation. {% /callout %} Imagen is Google's legacy image generation model. It is now shut down and no longer available in the Gemini API. ## Migrate to Nano Banana {% id="migrate-to-nano-banana" %} Migrate to Nano Banana for image generation: - **Model name**: Use `gemini-2.5-flash-image` (or Nano Banana 2 models such as `gemini-3.1-flash-image`) instead of Imagen model names. - **Method**: Use `client.models.generate_content` instead of `client.models.generate_images`. - **Response handling**: Nano Banana returns content parts containing image data instead of a specific image response object. See the [Image generation guide](/docs/image-generation) for details and examples. # Text-to-speech generation (TTS) Source: https://aistudio.google.com/docs/speech-generation Description: Generate high-fidelity speech and multi-speaker audio with the Gemini API using gemini-3.8-flash-tts and gemini-3.8-flash-lite-tts. The Gemini API can transform text input into single-speaker or multi-speaker audio using Gemini text-to-speech (TTS) generation capabilities. Text-to-speech generation is *[controllable](/docs/speech-generation#controllable)*, meaning you can combine structured turn metadata (`speech_metadata`) and inline vocal tags to guide the *style*, *accent*, *pace*, and *tone* of the audio. The TTS capability differs from speech generation provided through the [Live API](/docs/live-api), which is designed for interactive, unstructured audio, and multimodal inputs and outputs. While the Live API excels in dynamic conversational contexts, TTS through the Gemini API is tailored for scenarios that require exact text recitation with fine-grained control over style and sound, such as podcast or audiobook generation. This guide shows you how to generate single-speaker and multi-speaker audio from text using [Gemini 3.8 Flash TTS](/docs/models/gemini-3.8-flash-tts) (`gemini-3.8-flash-tts`) and [Gemini 3.8 Flash-Lite TTS](/docs/models/gemini-3.8-flash-lite-tts) (`gemini-3.8-flash-lite-tts`). ## Before you begin {% class="hide-from-toc" id="before-you-begin" %} Ensure you use a Gemini TTS model listed in the [Supported models](/docs/speech-generation#supported-models) section, and upgrade to the latest Google GenAI SDK (`google-genai >= 2.25.0` for Python or `@google/genai >= 2.24.0` for JavaScript/TypeScript) or use the REST API. For optimal results, review [When to use which model](/docs/speech-generation#when-to-use-which-model) to select the best model for your workload. You may find it useful to [test the Gemini TTS models in AI Studio](https://aistudio.google.com/generate-speech) before you start building. {% callout type="note" %} TTS models accept text-only inputs and produce audio-only outputs. For a complete list of restrictions specific to TTS models, review the [Limitations](/docs/speech-generation#limitations) section. {% /callout %} ## Single-speaker TTS {% id="single-speaker" %} To convert text to single-speaker audio with Gemini 3.8 TTS models, pass the verbatim transcript in `input`, attach turn-level styling using a `speech_metadata` annotation, and configure your voice in `generation_config.speech_config`. You can choose a voice from the prebuilt [voice options](/docs/speech-generation#voices), the Extended Voice Library (`GET /v1beta/voices`), a custom [Voice design](/docs/voice-design) ID (`voice_...`), or a [Voice replication](/docs/voice-replication) ID (`voice_...`, or optional stateless `voicekey_...`). This example saves the output audio from the model in a WAV file: {% tabs %} {% tab label="Python" %} ```python import base64 from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-3.8-flash-tts", input=[{ "type": "user_input", "content": [{ "type": "text", "text": "Have a wonderful day!", "annotations": [{ "type": "speech_metadata", "style": "cheerful and friendly", }], }], }], response_format={"type": "audio"}, generation_config={ "speech_config": [ {"voice": "Kore"}, ] }, ) with open("out.wav", "wb") as f: f.write(base64.b64decode(interaction.output_audio.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```js import {GoogleGenAI} from '@google/genai'; import * as fs from 'node:fs'; async function main() { const client = new GoogleGenAI({}); const interaction = await client.interactions.create({ model: 'gemini-3.8-flash-tts', input: [{ type: 'user_input', content: [{ type: 'text', text: 'Have a wonderful day!', annotations: [{ type: 'speech_metadata', style: 'cheerful and friendly', }], }], }], response_format: { type: 'audio' }, generation_config: { speech_config: [ { voice: 'Kore' }, ], }, }); if (interaction.output_audio?.data) { const audioBuffer = Buffer.from(interaction.output_audio.data, 'base64'); fs.writeFileSync('out.wav', audioBuffer); } } await main(); ``` {% /tab %} {% tab label="REST" %} ```sh curl -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.8-flash-tts", "input": [{ "type": "user_input", "content": [{ "type": "text", "text": "Have a wonderful day!", "annotations": [{ "type": "speech_metadata", "style": "cheerful and friendly" }] }] }], "response_format": { "type": "audio" }, "generation_config": { "speech_config": [ { "voice": "Kore" } ] } }' | jq -r '[.steps[] | select(.type=="model_output") | .content[] | select(.type=="audio")] | last | .data' | base64 --decode > out.wav ``` {% /tab %} {% /tabs %} In the Python and JavaScript SDKs, you can retrieve generated audio data by using the `interaction.output_audio` convenience property, which returns the last generated audio block (in raw REST JSON responses, the base64-encoded audio is stored in `steps[].content[].data`). ## Multi-speaker TTS {% id="multi-speaker" %} For multi-speaker dialogue, configure two speakers in `speech_config.speakers` and pass each turn as a separate text item with a `speech_metadata` annotation specifying the `speaker` and optional turn-level `style`. Notice that `speech_config` accepts an array (`[{"voice": "..."}]`) for single-speaker generation and an object (`{"speakers": [...]}`) for multi-speaker generation: {% tabs %} {% tab label="Python" %} ```python import base64 from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-3.8-flash-tts", input=[{ "type": "user_input", "content": [ { "type": "text", "text": "How's it going today Jane?", "annotations": [{ "type": "speech_metadata", "speaker": "Joe", "style": "cheerful and friendly", }], }, { "type": "text", "text": "Not too bad, how about you? Ready to test these new voices?", "annotations": [{ "type": "speech_metadata", "speaker": "Jane", "style": "calm and relaxed", }], }, ], }], response_format={"type": "audio"}, generation_config={ "speech_config": { "speakers": [ {"speaker": "Joe", "voice": "Puck"}, {"speaker": "Jane", "voice": "Kore"}, ], } }, ) with open("out.wav", "wb") as f: f.write(base64.b64decode(interaction.output_audio.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```js import {GoogleGenAI} from '@google/genai'; import * as fs from 'node:fs'; async function main() { const client = new GoogleGenAI({}); const interaction = await client.interactions.create({ model: 'gemini-3.8-flash-tts', input: [{ type: 'user_input', content: [ { type: 'text', text: "How's it going today Jane?", annotations: [{ type: 'speech_metadata', speaker: 'Joe', style: 'cheerful and friendly', }], }, { type: 'text', text: 'Not too bad, how about you? Ready to test these new voices?', annotations: [{ type: 'speech_metadata', speaker: 'Jane', style: 'calm and relaxed', }], }, ], }], response_format: { type: 'audio' }, generation_config: { speech_config: { speakers: [ { speaker: 'Joe', voice: 'Puck' }, { speaker: 'Jane', voice: 'Kore' }, ], }, }, }); if (interaction.output_audio?.data) { const audioBuffer = Buffer.from(interaction.output_audio.data, 'base64'); fs.writeFileSync('out.wav', audioBuffer); } } await main(); ``` {% /tab %} {% tab label="REST" %} ```sh curl -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.8-flash-tts", "input": [{ "type": "user_input", "content": [ { "type": "text", "text": "How'\''s it going today Jane?", "annotations": [{ "type": "speech_metadata", "speaker": "Joe", "style": "cheerful and friendly" }] }, { "type": "text", "text": "Not too bad, how about you? Ready to test these new voices?", "annotations": [{ "type": "speech_metadata", "speaker": "Jane", "style": "calm and relaxed" }] } ] }], "response_format": { "type": "audio" }, "generation_config": { "speech_config": { "speakers": [ { "speaker": "Joe", "voice": "Puck" }, { "speaker": "Jane", "voice": "Kore" } ] } } }' ``` {% /tab %} {% /tabs %} ## Control speech style with metadata and tags {% id="controllable" %} Gemini 3.8 TTS treats the `text` field strictly as a verbatim transcript. To control delivery without having stage directions read aloud, split your instructions by scope: * **Sustained turn-level delivery (`speech_metadata.style`):** Put emotions, delivery style, prosody, pacing, and volume that apply across an entire turn in the `style` field (for example, `"style": "whispered urgently"`, `"style": "out of breath"`, or `"style": "warm and enthusiastic"`). * **Point-in-time events (inline tags):** Place momentary non-speech vocal bursts or pauses directly inside the transcript using angle brackets (for example, `"Wait... did you hear that? "` or `"Excuse me as I was saying..."`). See the [Prompting guide](/docs/speech-generation#prompting-guide) for comprehensive best practices. {% tabs %} {% tab label="Python" %} ```python import base64 from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-3.8-flash-tts", input=[{ "type": "user_input", "content": [ { "type": "text", "text": "Wait... look under that fallen log! Is that a blue-spotted salamander?", "annotations": [{ "type": "speech_metadata", "speaker": "Dr. Anya", "style": "whispered urgently", }], }, { "type": "text", "text": " No way! We've been searching for this species all season!", "annotations": [{ "type": "speech_metadata", "speaker": "Liam", "style": "warm and enthusiastic", }], }, ], }], response_format={"type": "audio"}, generation_config={ "speech_config": { "speakers": [ {"speaker": "Dr. Anya", "voice": "Kore"}, {"speaker": "Liam", "voice": "Puck"}, ], } }, ) with open("out.wav", "wb") as f: f.write(base64.b64decode(interaction.output_audio.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```js import * as fs from 'node:fs'; import {GoogleGenAI} from '@google/genai'; async function main() { const client = new GoogleGenAI({}); const interaction = await client.interactions.create({ model: 'gemini-3.8-flash-tts', input: [{ type: 'user_input', content: [ { type: 'text', text: 'Wait... look under that fallen log! Is that a blue-spotted salamander?', annotations: [{ type: 'speech_metadata', speaker: 'Dr. Anya', style: 'whispered urgently', }], }, { type: 'text', text: " No way! We've been searching for this species all season!", annotations: [{ type: 'speech_metadata', speaker: 'Liam', style: 'warm and enthusiastic', }], }, ], }], response_format: { type: 'audio' }, generation_config: { speech_config: { speakers: [ { speaker: 'Dr. Anya', voice: 'Kore' }, { speaker: 'Liam', voice: 'Puck' }, ], }, }, }); if (interaction.output_audio?.data) { const audioBuffer = Buffer.from(interaction.output_audio.data, 'base64'); fs.writeFileSync('out.wav', audioBuffer); } } await main(); ``` {% /tab %} {% tab label="REST" %} ```sh curl -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.8-flash-tts", "input": [{ "type": "user_input", "content": [ { "type": "text", "text": "Wait... look under that fallen log! Is that a blue-spotted salamander?", "annotations": [{ "type": "speech_metadata", "speaker": "Dr. Anya", "style": "whispered urgently" }] }, { "type": "text", "text": " No way! We'\''ve been searching for this species all season!", "annotations": [{ "type": "speech_metadata", "speaker": "Liam", "style": "warm and enthusiastic" }] } ] }], "response_format": { "type": "audio" }, "generation_config": { "speech_config": { "speakers": [ { "speaker": "Dr. Anya", "voice": "Kore" }, { "speaker": "Liam", "voice": "Puck" } ] } } }' ``` {% /tab %} {% /tabs %} ## Streaming speech generation {% id="streaming" %} You can stream the generated audio as it is being synthesized by setting `stream: true`. Unlike unary requests (which return a complete WAV file with a RIFF header), **streaming requests return headerless raw 16-bit signed little-endian linear PCM (`audio/l16`, 24 kHz, mono) chunks by default** so audio chunks can be played or concatenated continuously without container headers. {% tabs %} {% tab label="Python" %} ```python import base64 from google import genai client = genai.Client() stream = client.interactions.create( model="gemini-3.8-flash-tts", input=[{ "type": "user_input", "content": [{ "type": "text", "text": "Have a wonderful day!", "annotations": [{ "type": "speech_metadata", "style": "cheerful and friendly", }], }], }], response_format={"type": "audio"}, generation_config={ "speech_config": [ {"voice": "Kore"}, ] }, stream=True, ) for event in stream: if event.event_type == "step.delta": if event.delta.type == "audio": audio_data = base64.b64decode(event.delta.data) ``` {% /tab %} {% tab label="JavaScript" %} ```js import {GoogleGenAI} from '@google/genai'; async function main() { const client = new GoogleGenAI({}); const stream = await client.interactions.create({ model: 'gemini-3.8-flash-tts', input: [{ type: 'user_input', content: [{ type: 'text', text: 'Have a wonderful day!', annotations: [{ type: 'speech_metadata', style: 'cheerful and friendly', }], }], }], response_format: { type: 'audio' }, generation_config: { speech_config: [ { voice: 'Kore' }, ], }, stream: true, }); for await (const event of stream) { if (event.event_type === 'step.delta') { if (event.delta.type === 'audio' && event.delta.data) { const audioBuffer = Buffer.from(event.delta.data, 'base64'); // Process the audio buffer } } } } await main(); ``` {% /tab %} {% tab label="REST" %} ```sh curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ --no-buffer \ -d '{ "model": "gemini-3.8-flash-tts", "input": [{ "type": "user_input", "content": [{ "type": "text", "text": "Have a wonderful day!", "annotations": [{ "type": "speech_metadata", "style": "cheerful and friendly" }] }] }], "response_format": { "type": "audio" }, "generation_config": { "speech_config": [ { "voice": "Kore" } ] }, "stream": true }' ``` {% /tab %} {% /tabs %} ## Audio output formats {% id="audio-output-formats" %} Gemini 3.8 TTS models use different default audio formats depending on whether the request is unary or streaming: * **Unary requests (`stream=False`):** Return complete **WAV (`audio/wav`)** audio with a RIFF header (24 kHz, mono, 16-bit signed little-endian PCM). You can write the decoded base64 bytes directly to a `.wav` file without manually adding a WAV container. * **Streaming requests (`stream=True`):** Return **headerless raw Linear PCM (`audio/l16`)** chunks (24 kHz, mono, 16-bit signed little-endian PCM) by default so chunks can be streamed or concatenated continuously without container headers on each chunk. You can override the output audio encoding and sample rate in `response_format`: | `mime_type` value | Format | Description | | :--- | :--- | :--- | | `"audio/wav"` *(unary default)* | WAV | Complete WAV file with a RIFF header (24 kHz, mono, 16-bit PCM). | | `"audio/l16"` *(streaming default)* | Linear PCM | Headerless raw 16-bit signed little-endian linear PCM (24 kHz, mono). Default for streaming requests. | | `"audio/mulaw"` | μ-law | G.711 μ-law companded audio. Commonly used in North American and Japanese telephony (8 kHz). | | `"audio/alaw"` | A-law | G.711 A-law companded audio. Commonly used in European and international telephony (8 kHz). | You can also optionally specify `sample_rate` (for example, `24000`, `16000`, or `8000` Hz; defaults to `24000` Hz). The following example requests headerless raw 16-bit PCM (`audio/l16`) at 24 kHz: {% tabs %} {% tab label="Python" %} ```python import base64 from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-3.8-flash-tts", input=[{ "type": "user_input", "content": [{ "type": "text", "text": "Have a wonderful day!", "annotations": [{ "type": "speech_metadata", "style": "cheerful and friendly", }], }], }], response_format={ "type": "audio", "mime_type": "audio/l16", "sample_rate": 24000, }, generation_config={ "speech_config": [ {"voice": "Kore"}, ] }, ) with open("out.pcm", "wb") as f: f.write(base64.b64decode(interaction.output_audio.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```js import {GoogleGenAI} from '@google/genai'; import * as fs from 'node:fs'; async function main() { const client = new GoogleGenAI({}); const interaction = await client.interactions.create({ model: 'gemini-3.8-flash-tts', input: [{ type: 'user_input', content: [{ type: 'text', text: 'Have a wonderful day!', annotations: [{ type: 'speech_metadata', style: 'cheerful and friendly', }], }], }], response_format: { type: 'audio', mime_type: 'audio/l16', sample_rate: 24000, }, generation_config: { speech_config: [ { voice: 'Kore' }, ], }, }); if (interaction.output_audio?.data) { const audioBuffer = Buffer.from(interaction.output_audio.data, 'base64'); fs.writeFileSync('out.pcm', audioBuffer); } } await main(); ``` {% /tab %} {% tab label="REST" %} ```sh curl -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.8-flash-tts", "input": [{ "type": "user_input", "content": [{ "type": "text", "text": "Have a wonderful day!", "annotations": [{ "type": "speech_metadata", "style": "cheerful and friendly" }] }] }], "response_format": { "type": "audio", "mime_type": "audio/l16", "sample_rate": 24000 }, "generation_config": { "speech_config": [ { "voice": "Kore" } ] } }' ``` {% /tab %} {% /tabs %} ## Voice options {% id="voices" %} Gemini 3.8 TTS supports four ways to select or create voices: 1. **Prebuilt studio voices:** 30 curated voices listed in the following table. 2. **Extended Voice Library:** Hundreds of additional voices across languages, accents, and character archetypes accessible using `client.voices.list()` (`GET /v1beta/voices`). 3. **[Voice design](/docs/voice-design):** Generate a custom vocal persona from a natural-language description in [Google AI Studio](https://aistudio.google.com/generate-speech) or using `POST /v1beta/voices` (`type="prompted"`, which returns a persistent `voice_...` ID and a `sample_audio` WAV preview in `CreateVoice` and `GetVoice`). 4. **[Voice replication](/docs/voice-replication):** Replicate a speaker's voice from reference and consent audio in [Google AI Studio](https://aistudio.google.com/generate-speech) or using `POST /v1beta/voices` (`type="replicated"`, persistent `store=True` by default or optional stateless `store=False`). ### Custom voice limits and TTL {% id="custom-voice-limits" %} | Voice type | Storage mode | Quota / limit | Retention (TTL) | | :--- | :--- | :--- | :--- | | **Stateful voices** (`voice_...`, prompted or replicated) | `store=True` | **200 voices per project** (shared across prompted and replicated voices) | **1 year from last use**{% sup %}*{% /sup %} | | **Stateless voice keys** (`voicekey_...`, replicated) | `store=False` | Client-managed | **7 days** | {% sup %}*{% /sup %} **TTL extension:** The 1-year retention window resets each time the voice is actively used (either by synthesizing speech with the voice or using it as a base voice for remixing). Voices with no activity for 1 year are automatically deleted. ### Prebuilt voices {% id="prebuilt-voices" %} {% table %} * **Zephyr** -- *Bright* * **Puck** -- *Upbeat* * **Charon** -- *Informative* --- * **Kore** -- *Firm* * **Fenrir** -- *Excitable* * **Leda** -- *Youthful* --- * **Orus** -- *Firm* * **Aoede** -- *Breezy* * **Callirrhoe** -- *Easy-going* --- * **Autonoe** -- *Bright* * **Enceladus** -- *Breathy* * **Iapetus** -- *Clear* --- * **Umbriel** -- *Easy-going* * **Algieba** -- *Smooth* * **Despina** -- *Smooth* --- * **Erinome** -- *Clear* * **Algenib** -- *Gravelly* * **Rasalgethi** -- *Informative* --- * **Laomedeia** -- *Upbeat* * **Achernar** -- *Soft* * **Alnilam** -- *Firm* --- * **Schedar** -- *Even* * **Gacrux** -- *Mature* * **Pulcherrima** -- *Forward* --- * **Achird** -- *Friendly* * **Zubenelgenubi** -- *Casual* * **Vindemiatrix** -- *Gentle* --- * **Sadachbia** -- *Lively* * **Sadaltager** -- *Knowledgeable* * **Sulafat** -- *Warm* {% /table %} ### Extended Voice Library and filtering {% id="voice-library" %} Beyond the 30 featured studio voices in the preceding table, the **Extended Voice Library** provides hundreds of additional voices across languages, regional accents, character personas, and domains. You can browse, filter, and audition the full Voice Library interactively in [Google AI Studio](https://aistudio.google.com/generate-speech), or query it programmatically using `client.voices.list()` (`GET /v1beta/voices`, using `google-genai` 2.25.0+ / `@google/genai` 2.24.0+). `ListVoices` returns your custom stored voices (ordered newest first) followed by prebuilt catalog voices matching your filter criteria. When multiple values are passed for a list filter, voices matching **any** value in that filter are returned (`OR`), while distinct filter parameters combine with `AND`: | Parameter | Type | Description | | :--- | :--- | :--- | | `language_code` | `list[str]` | BCP-47 language tag(s) (for example, `["en-US", "en-GB"]`). Case-insensitive exact match. | | `region_code` | `list[str]` | ISO 3166-1 alpha-2 or UN M.49 region code(s) (for example, `["US", "GB"]`). | | `accent` | `list[str]` | Regional accent descriptor(s) (for example, `["American", "British"]`). | | `gender` | `list[str]` | Perceived gender presentation (`"female"`, `"male"`, or `"neutral"`). | | `pitch` | `list[str]` | Vocal pitch classification (`"low"`, `"medium"`, or `"high"`). | | `persona` | `list[str]` | Vocal persona or character archetype (for example, `["Warm, Friendly"]`, `["Narrator"]`). | | `contexts` (`context` in REST) | `list[str]` | Optimal usage domain (for example, `["Audiobook", "Conversational", "News"]`). | | `type` (`type_` in Python) | `list[str]` | Filter by voice source: `"prebuilt"`, `"prompted"` ([Voice design](/docs/voice-design)), or `"replicated"` ([Voice replication](/docs/voice-replication)). | | `search` | `str` | Free-text substring search matched case-insensitively against both `display_name` and `description`. | | `page_size` | `int` | Maximum number of voices returned per page (default `50`, maximum `1000`). | | `page_token` | `str` | Token from `response.next_page_token` to fetch the next page of results. | {% tabs %} {% tab label="Python" %} ```python from google import genai client = genai.Client() # Filter the Voice Library by language, gender, pitch, domain context, and keyword response = client.voices.list( language_code=["en-US", "en-GB"], gender=["female"], pitch=["medium", "low"], contexts=["Audiobook", "Conversational"], type_=["prebuilt"], search="warm", page_size=50, ) for voice in response.voices or []: print( f"{voice.id} | {voice.display_name} ({voice.language_code}," f" {voice.accent}, {voice.gender}, pitch={voice.pitch}):" f" {voice.description}" ) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI(); // Filter the Voice Library by language, gender, pitch, domain context, and keyword const response = await ai.voices.list({ language_code: ["en-US", "en-GB"], gender: ["female"], pitch: ["medium", "low"], contexts: ["Audiobook", "Conversational"], type: ["prebuilt"], search: "warm", page_size: 50, }); for (const voice of response.voices ?? []) { console.log( `${voice.id} | ${voice.display_name} (${voice.language_code}, ${voice.accent}, ${voice.gender}, pitch=${voice.pitch}): ${voice.description}` ); } ``` {% /tab %} {% tab label="REST" %} ```sh curl -G "https://generativelanguage.googleapis.com/v1beta/voices" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ --data-urlencode "language_code=en-US" \ --data-urlencode "language_code=en-GB" \ --data-urlencode "gender=female" \ --data-urlencode "pitch=medium" \ --data-urlencode "context=Audiobook" \ --data-urlencode "type=prebuilt" \ --data-urlencode "search=warm" \ --data-urlencode "page_size=50" ``` {% /tab %} {% /tabs %} ## Supported languages {% id="languages" %} The TTS models detect the input language automatically. [Gemini 3.8 Flash TTS](/docs/models/gemini-3.8-flash-tts) (`gemini-3.8-flash-tts`) supports **over 130 languages**, and [Gemini 3.8 Flash-Lite TTS](/docs/models/gemini-3.8-flash-lite-tts) (`gemini-3.8-flash-lite-tts`) supports **over 100 languages**: | Language | Gemini 3.8 Flash TTS | Gemini 3.8 Flash-Lite TTS | | :--- | :--- | :--- | | Acehnese (Arab script) | ✔️ | ✔️ | | Afrikaans | ✔️ | ✔️ | | Akan | ✔️ | ✔️ | | Amharic | ✔️ | ✔️ | | Armenian | ✔️ | ✔️ | | Assamese | ✔️ | ✔️ | | Awadhi | ✔️ | ✔️ | | Balinese | ✔️ | ✔️ | | Bangla | ✔️ | ✔️ | | Banjar (Arab script) | ✔️ | — | | Banjar (Latn script) | ✔️ | ✔️ | | Bashkir | ✔️ | — | | Basque | ✔️ | ✔️ | | Belarusian | ✔️ | ✔️ | | Bemba | ✔️ | — | | Bhojpuri | ✔️ | ✔️ | | Bosnian | ✔️ | ✔️ | | Buginese | ✔️ | ✔️ | | Bulgarian | ✔️ | ✔️ | | Burmese | ✔️ | — | | Cantonese | ✔️ | ✔️ | | Catalan | ✔️ | ✔️ | | Cebuano | ✔️ | ✔️ | | Central Kurdish | ✔️ | ✔️ | | Chhattisgarhi | ✔️ | ✔️ | | Chinese (Hans script) | ✔️ | ✔️ | | Chinese (Hant script) | ✔️ | ✔️ | | Crimean Tatar | ✔️ | — | | Croatian | ✔️ | ✔️ | | Czech | ✔️ | ✔️ | | Danish | ✔️ | ✔️ | | Dutch | ✔️ | ✔️ | | Dyula | ✔️ | — | | Dzongkha | ✔️ | — | | Egyptian Arabic | ✔️ | ✔️ | | English | ✔️ | ✔️ | | Estonian | ✔️ | ✔️ | | Filipino | ✔️ | ✔️ | | Finnish | ✔️ | — | | French | ✔️ | ✔️ | | Galician | ✔️ | ✔️ | | Ganda | ✔️ | ✔️ | | Georgian | ✔️ | ✔️ | | German | ✔️ | ✔️ | | Greek | ✔️ | ✔️ | | Guarani | ✔️ | — | | Gujarati | ✔️ | ✔️ | | Haitian Creole | ✔️ | ✔️ | | Halh Mongolian | ✔️ | ✔️ | | Hausa | ✔️ | ✔️ | | Hebrew | ✔️ | ✔️ | | Hindi | ✔️ | ✔️ | | Hungarian | ✔️ | ✔️ | | Icelandic | ✔️ | ✔️ | | Igbo | ✔️ | — | | Iloko | ✔️ | ✔️ | | Indonesian | ✔️ | ✔️ | | Iranian Persian | ✔️ | ✔️ | | Italian | ✔️ | ✔️ | | Japanese | ✔️ | ✔️ | | Javanese | ✔️ | ✔️ | | Kabyle | ✔️ | — | | Kamba | ✔️ | ✔️ | | Kannada | ✔️ | ✔️ | | Kashmiri (Arab script) | ✔️ | ✔️ | | Kashmiri (Deva script) | ✔️ | ✔️ | | Kazakh | ✔️ | ✔️ | | Khmer | ✔️ | ✔️ | | Kikuyu | ✔️ | ✔️ | | Kinyarwanda | ✔️ | ✔️ | | Kongo | ✔️ | ✔️ | | Korean | ✔️ | ✔️ | | Kyrgyz | ✔️ | ✔️ | | Lao | ✔️ | ✔️ | | Latgalian | ✔️ | — | | Lingala | ✔️ | ✔️ | | Lithuanian | ✔️ | — | | Luxembourgish | ✔️ | — | | Macedonian | ✔️ | ✔️ | | Magahi | ✔️ | ✔️ | | Maithili | ✔️ | ✔️ | | Malayalam | ✔️ | ✔️ | | Maltese | ✔️ | ✔️ | | Manipuri | ✔️ | ✔️ | | Marathi | ✔️ | ✔️ | | Minangkabau (Arab script) | ✔️ | ✔️ | | Minangkabau (Latn script) | ✔️ | — | | Mizo | ✔️ | ✔️ | | Nepali (individual language) | ✔️ | ✔️ | | Nigerian Fulfulde | ✔️ | ✔️ | | North Azerbaijani | ✔️ | ✔️ | | Northern Sotho | ✔️ | ✔️ | | Northern Uzbek | ✔️ | ✔️ | | Norwegian Bokmål | ✔️ | ✔️ | | Norwegian Nynorsk | ✔️ | ✔️ | | Nyanja | ✔️ | ✔️ | | Occitan | ✔️ | — | | Odia (individual language) | ✔️ | ✔️ | | Pangasinan | ✔️ | — | | Persian (Afghanistan) | ✔️ | ✔️ | | Polish | ✔️ | ✔️ | | Portuguese | ✔️ | ✔️ | | Punjabi | ✔️ | ✔️ | | Romanian | ✔️ | ✔️ | | Russian | ✔️ | ✔️ | | Santali | ✔️ | ✔️ | | Serbian | ✔️ | ✔️ | | Sindhi | ✔️ | — | | Sinhala | ✔️ | ✔️ | | Slovak | ✔️ | ✔️ | | Slovenian | ✔️ | — | | Somali | ✔️ | — | | South Azerbaijani | ✔️ | ✔️ | | Southern Pashto | ✔️ | ✔️ | | Southern Sotho | ✔️ | — | | Spanish | ✔️ | ✔️ | | Standard Arabic (Arab script) | ✔️ | ✔️ | | Standard Arabic (Latn script) | ✔️ | ✔️ | | Standard Latvian | ✔️ | ✔️ | | Standard Malay | ✔️ | ✔️ | | Swahili (individual language) | ✔️ | — | | Swati | ✔️ | — | | Swedish | ✔️ | — | | Tajik | ✔️ | — | | Tamil | ✔️ | ✔️ | | Telugu | ✔️ | ✔️ | | Thai | ✔️ | — | | Tigrinya | ✔️ | — | | Tosk Albanian | ✔️ | — | | Turkish | ✔️ | ✔️ | | Uyghur | ✔️ | — | | Vietnamese | ✔️ | ✔️ | ## Supported models {% id="supported-models" %} | Model | Single speaker | Multi-speaker | Voice design | Voice replication | | :---- | :---- | :---- | :---- | :---- | | [Gemini 3.8 Flash TTS](/docs/models/gemini-3.8-flash-tts) (`gemini-3.8-flash-tts`) | ✔️ | ✔️ | ✔️ | ✔️ | | [Gemini 3.8 Flash-Lite TTS](/docs/models/gemini-3.8-flash-lite-tts) (`gemini-3.8-flash-lite-tts`) | ✔️ | ✔️ | ✔️ | ✔️ | | [Gemini 3.1 Flash TTS Preview](/docs/models/gemini-3.1-flash-tts-preview) | ✔️ | ✔️ | — | — | | [Gemini 2.5 Pro Preview TTS](/docs/models/gemini-2.5-pro-preview-tts) | ✔️ | ✔️ | — | — | ### When to use which model {% id="when-to-use-which-model" %} Both Gemini 3.8 TTS models share the exact same API schema and prompting format, allowing you to switch between them with a single parameter change: * **Use [Gemini 3.8 Flash TTS](/docs/models/gemini-3.8-flash-tts) (`gemini-3.8-flash-tts`)** when maximum acoustic fidelity, nuanced acting, and expressive control are top priority. It is ideal for studio-grade creative work, complex multi-speaker dialogue, heavy vocal-burst tags, difficult pronunciations, regional or minority dialects, and long-form narrations requiring rock-solid voice and room-tone stability. * **Use [Gemini 3.8 Flash-Lite TTS](/docs/models/gemini-3.8-flash-lite-tts) (`gemini-3.8-flash-lite-tts`)** as your fast, cost-efficient workhorse replacement for `gemini-3.1-flash-tts-preview`. It is optimized for high-volume bulk production, conversational voice agent cascades, read-aloud features, reliable voice replication, and everyday single-speaker speech across major languages. ### Migration guide {% id="migration" %} When upgrading from earlier preview models (`gemini-3.1-flash-tts-preview` or `gemini-2.5-pro-preview-tts`) to Gemini 3.8 TTS (`gemini-3.8-flash-tts` or `gemini-3.8-flash-lite-tts`), review these five key changes: 1. **Separate style from transcript:** Move sustained acting, tone, prosody, and pacing instructions (such as `"whispering"`, `"out of breath"`, or `"speaking slowly"`) out of plain text and into `speech_metadata.style`. Keep `text` strictly as the verbatim transcript plus inline vocal tags. 2. **Design personas upfront with Voice design:** Replace multi-paragraph `"Audio Profile"` or `"Director's Notes"` blocks with a custom voice created in [Voice design](/docs/voice-design), then carry that `voice_...` ID through your TTS requests with minimal or empty `style` strings. 3. **Use structured dialogue turns:** For multi-speaker dialogue, pass one `content` item per speaker turn with `speech_metadata.speaker` instead of embedding `Speaker: ...` prefixes inside a single text block. 4. **Use angle brackets for inline vocal tags:** Use angle brackets (``, ``, ``, ``, ``) for point-in-time human vocalizations and pauses. Avoid non-vocal sound-effect tags (such as applause or thuds). 5. **Account for default WAV (`audio/wav`) output on unary requests:** Unlike `gemini-3.1-flash-tts-preview` (which returned headerless raw PCM `audio/l16` by default), Gemini 3.8 TTS models return complete **WAV (`audio/wav`)** audio with a RIFF header (24 kHz, mono, 16-bit PCM) on unary requests. You can write decoded audio bytes directly to a `.wav` file without manually wrapping them with Python's `wave` module or Node's `wav` package. If your existing pipeline expects headerless raw PCM, mu-law, or A-law audio, explicitly set `response_format.mime_type` to `"audio/l16"`, `"audio/mulaw"`, or `"audio/alaw"` (for example, `{"response_format": {"type": "audio", "mime_type": "audio/l16"}}` in the Interactions API, or `AUDIO_L16` in `generateContent`; see [Audio output formats](/docs/speech-generation#audio-output-formats)). ## Prompting guide {% id="prompting-guide" %} Gemini 3.8 TTS models treat input text strictly as a **verbatim transcript**. Unlike earlier preview models where stage directions were embedded in plain text, Gemini 3.8 TTS separates sustained turn-level directions (`speech_metadata`) from point-in-time inline vocal tags. ### Style field versus inline tags {% id="style-vs-inline-tags" %} Split your performance instructions by scope: * **Turn-level delivery (`speech_metadata.style`):** Put sustained delivery attributes—such as emotion, prosody, overall pace, or delivery style (like `"whispering"`, `"out of breath"`, `"muttering"`, or `"sarcastic"`)—into the `style` field of `speech_metadata`. To create a stable character and performance across turns, design the persona upfront in [Voice design](/docs/voice-design) and use `style` only for optional turn-level tweaks. * **Point-in-time events (inline tags):** Put momentary non-speech vocal bursts, breaths, or pauses inline inside the transcript using angle brackets (``, ``, ``, ``). Use angle brackets (`<...>`) for highest audio quality, and stick to human vocalizations rather than non-vocal sound effects. | Scope | Where to place | Examples | | :-------------------- | :---------------------- | :------------------------- | | **Turn-level** (sustained across the turn) | `speech_metadata.style` | `"angry tone"`, `"speaking rapidly"`, `"out of breath"`, `"whispers"`, `"sarcastic"` | | **Point-in-time** (occurs at a specific word) | Inline in `text` (`<...>`) | `" Thank you all for coming tonight! As I was saying..."` | ### Pacing and pauses {% id="pacing-and-pauses" %} You can control rhythm and silence at three levels of granularity: * **Punctuation and ellipses:** Use commas, dashes (`--`), and ellipses (`...`) for natural conversational hesitation. * **Inline pause tags:** Insert `` or `` at exact points in the script where a speaker should pause: ```text Hold on, let me think... Alright, I've got it. ``` * **Turn-level pace:** Set `"style": "speaking rapidly"` or `"style": "speaking slowly"` in `speech_metadata` to control the speaking rate across the whole turn. ### Prosody and pitch {% id="prosody-and-pitch" %} Use **`speech_metadata.style`** to control prosody, pitch, and inflection across a turn (for example, `"style": "high pitch, cheerful and excited inflection"` or `"style": "monotone and flat"`). If the emotion or prosody shifts mid-dialogue, split the script into separate turns with distinct `style` values for each turn. ### Emphasis {% id="emphasis" %} Capitalize specific words in the transcript, combined with punctuation and inline vocal tags, to place natural vocal stress on key words: ```text This is a VERY important point! It was a VERY long day ... nobody listens anymore. ``` ### Vocal bursts and non-speech sounds {% id="vocal-bursts" %} Place non-speech human vocalizations inline using angle brackets (`<...>`) at the exact point where the sound should occur. Recommended vocal tags include: {% table %} * `` * `` * `` * `` --- * `` * `` * `` / `` * `` --- * `` * `` * `` * `` --- * `` * `` * `` * `` --- * `` / `` * `` * `` * `` / `` --- * `` * `` * `` * `` / `` --- * `` * `` * `` * `` --- * `` * `` * `` * `` / `` --- * `` * `` * `` {% /table %} {% callout type="note" %} If your transcript is in a non-English language, continue to use English inline tags for best results. {% /callout %} ### Backchannels and overlapping speech {% id="backchannels" %} In multi-speaker dialogue, wrap listener reactions in pipe characters (`|reaction|`) inside a speaker's turn to create natural backchannels or overlapping speech without breaking into a separate turn per reaction. * **Short backchannel exchanges:** Layer brief listener reactions (`|oh hmm|`, `|oh really?|`, `|absolutely|`) inside the active speaker's turn: * **Turn 1 (Speaker A):** `"So the launch is Thursday |oh hmm| Are we actually ready?"` * **Turn 2 (Speaker B):** `"Ready enough |oh really?| The last blocker cleared this morning."` * **Turn 3 (Speaker A):** `"Then let's ship it |absolutely| and watch the dashboards."` * **Overlapping and interleaved speech:** Use multiple pipe segments to simulate simultaneous or interleaved speech between two speakers (works best with `gemini-3.8-flash-tts`): * **Simultaneous countdown/chorus:** `"Let's surprise him on three |ok| ready?"` followed by `"one. two. three. |happy| happy |birthday| birthday!"` * **Full speaker overlap:** `"Hello |oh| there |my| it |goodness| must |gracious| be |would| almost |you| time |look| for |at that| dinner"` ### Consistency across generations and what to avoid {% id="consistency-and-what-to-avoid" %} Follow these guidelines to keep vocal identity stable across turns: * **Design personas upfront in Voice design instead of long style blocks:** Long-form `"Audio Profile"` paragraphs and multi-bullet `"Director's Notes"` carried over from earlier models are the most common cause of voice drift. Use that same creative intuition upfront in [Voice design](/docs/voice-design) to generate a persistent custom `voice_...` persona, then carry that voice ID through your TTS calls. * **Rely on the voice reference for stability (omit meta-instructions):** Gemini 3.8 TTS models are trained to anchor on the audio reference first. Do not include instructions telling the model to hold the voice steady (such as `"do not switch speaker identity"` or `"maintain identical timbre"`)—extra prompt text increases drift. Drop unnecessary style instructions and let the model vary naturally around the stable point provided by the voice reference. * **Do not try to change immutable speaker traits in `style`:** Avoid putting age, gender, names, or permanent accent changes in `speech_metadata.style`. Instead, pick a regional voice from the Extended Voice Library or create one with [Voice design](/docs/voice-design). ### Recommended workflow {% id="recommended-workflow" %} 1. **Build the character once:** Create your character in [Voice design](/docs/voice-design) or select a regional voice from the Extended Voice Library that matches your target language and persona. 2. **Write natural spoken transcripts with disfluencies:** For maximum naturalness, write the `text` as a real spoken transcript—including natural conversational disfluencies and hesitations (for example, `"Oh uh yeah I think... hm, so that's interesting"`). 3. **Test plain TTS first:** Synthesize your transcript with an empty `style` field first—most requests need no `style` instruction at all. 4. **Add short `style` prompts only for tweaks:** Add a concise `style` string (such as `"casual, friendly"` or `"muttering, then reassuring"`) only for turns that need a specific delivery adjustment, and reuse that exact short string across turns when you want a consistent baseline. ### Multi-turn dialogue and voice agents {% id="multi-turn-and-voice-agents" %} When building real-time conversational voice agents or multi-turn applications: * Make **one TTS call per turn** as LLM text chunks arrive. * Let the configured `voice` (prebuilt, designed `voice_...`, or replicated `voice_...` / `voicekey_...`) carry the speaker's identity across turns—never re-send a long character persona on each turn. * Leave the per-turn `style` field empty, or send one short constant string (such as `"casual, friendly"`) for the whole conversation. * Split long agent responses into shorter turns rather than reaching for stronger style prompts. ## Limitations {% id="limitations" %} * TTS models accept text-only inputs and generate audio-only outputs. * Single-request multi-speaker generation (`speech_config.speakers`) supports up to 2 speakers using prebuilt voices. To combine custom designed (`voice_...`) or replicated (`voice_...` / `voicekey_...`) voices in multi-character dialogue, synthesize each speaker's turn individually. Because unary requests return `audio/wav` with a 44-byte RIFF header by default, request raw PCM (`{"type": "audio", "mime_type": "audio/l16"}`) or strip the WAV header from each turn before concatenating the 24kHz PCM audio frames. * **Custom voice storage limits and TTL:** * **Stateful voices (`store=True`, prompted or replicated):** Maximum of **200 voices per project** with a **1-year TTL** (time-to-live). * **Stateless voice keys (`store=False`, `voicekey_...`):** **7-day TTL** (time-to-live). * Review the [Supported languages](/docs/speech-generation#languages) section for language coverage. ## What's next {% id="whats-next" %} * Create custom vocal personas from natural language with [Voice design](/docs/voice-design). * Replicate an existing speaker's voice in [Voice replication](/docs/voice-replication). * Compare model specifications on the [Gemini 3.8 Flash TTS](/docs/models/gemini-3.8-flash-tts) and [Gemini 3.8 Flash-Lite TTS](/docs/models/gemini-3.8-flash-lite-tts) model pages. * Explore interactive bidirectional audio with the [Live API](/docs/live-api). # Voice design Source: https://aistudio.google.com/docs/voice-design Description: Create persistent custom vocal personas from natural-language descriptions with Gemini 3.8 TTS. Voice design lets you create a brand-new, persistent vocal persona from a natural-language description using the Gemini API Voices endpoint (`POST /v1beta/voices`). Instead of being limited to prebuilt voices or recording reference audio, you can describe a character's age, vocal timbre, accent, and baseline delivery, and receive a reusable `voice_...` ID saved to your project. The fastest way to design, audition, and iterate on custom voices is with the interactive **Voice Design** studio in [Google AI Studio](https://aistudio.google.com/generate-speech). You can generate custom personas from text prompts, test them with sample scripts, and copy the resulting `voice_...` ID directly into your application code. {% button href="https://aistudio.google.com/generate-speech" variant="primary" %}Try in Google AI Studio{% /button %} Both [Gemini 3.8 Flash TTS](/docs/models/gemini-3.8-flash-tts) (`gemini-3.8-flash-tts`) and [Gemini 3.8 Flash-Lite TTS](/docs/models/gemini-3.8-flash-lite-tts) (`gemini-3.8-flash-lite-tts`) support Voice design. ## Create a designed voice {% id="create-a-designed-voice" %} Use the Google GenAI SDK (`google-genai` 2.25.0+ / `@google/genai` 2.24.0+) or REST API to create a custom voice from a text description. For `"prompted"` voices, both `voices.create` (`CreateVoice`) and `voices.get` (`GetVoice`) return an output-only `sample_audio` field (`mime_type: "audio/wav"`, base64-encoded `data`) so you can immediately audition the generated voice: {% tabs %} {% tab label="Python" %} ```python import base64 from google import genai client = genai.Client() # 1. Design a custom voice persona from natural language created_voice = client.voices.create( store=True, voice={ "model": "gemini-3.8-flash-tts", "type": "prompted", "display_name": "Warm British Astronomer", "gender": "male", "language_code": "en-GB", "prompted": { "input": ( "A warm, thoughtful astronomer in his late 60s with a gentle" " British accent, speaking with quiet wonder." ) }, }, ) print(f"Created voice ID: {created_voice.id}") # Save the generated sample_audio preview (audio/wav) returned by CreateVoice if created_voice.sample_audio and created_voice.sample_audio.data: with open("voice_preview.wav", "wb") as f: f.write(base64.b64decode(created_voice.sample_audio.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import * as fs from "node:fs"; import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI(); // 1. Design a custom voice persona from natural language const createdVoice = await ai.voices.create({ store: true, voice: { model: "gemini-3.8-flash-tts", type: "prompted", display_name: "Warm British Astronomer", gender: "male", language_code: "en-GB", prompted: { input: "A warm, thoughtful astronomer in his late 60s with a gentle British accent, speaking with quiet wonder.", }, }, }); console.log(`Created voice ID: ${createdVoice.id}`); // Save the generated sample_audio preview (audio/wav) returned by CreateVoice if (createdVoice.sample_audio?.data) { fs.writeFileSync( "voice_preview.wav", Buffer.from(createdVoice.sample_audio.data, "base64") ); } ``` {% /tab %} {% tab label="REST" %} ```bash curl "https://generativelanguage.googleapis.com/v1beta/voices" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -X POST \ -d '{ "store": true, "voice": { "model": "gemini-3.8-flash-tts", "type": "prompted", "display_name": "Warm British Astronomer", "gender": "male", "language_code": "en-GB", "prompted": { "input": "A warm, thoughtful astronomer in his late 60s with a gentle British accent, speaking with quiet wonder." } } }' | tee created_voice.json | jq -r '.sample_audio.data' | base64 --decode > voice_preview.wav ``` {% /tab %} {% /tabs %} ## How Voice design works {% id="how-voice-design-works" %} 1. **Create a prompted voice:** Call `voices.create` (`POST /v1beta/voices`) with `type="prompted"` and `store=True`. 2. **Receive a persistent `voice_id` and `sample_audio` preview:** The API generates the vocal identity, stores it in your project, and returns a permanent ID (for example, `voice_abc123...`) along with `sample_audio` (`mime_type: "audio/wav"`, base64-encoded `data`) containing the generated preview audio for the voice. 3. **Synthesize speech:** Pass the `voice_id` anywhere a voice name is accepted in your synthesis requests. ## Synthesize speech with your designed voice {% id="synthesize-speech-with-your-designed-voice" %} Once you have created a voice, pass its `id` (`voice_...`) to the Interactions API to generate speech: {% tabs %} {% tab label="Python" %} ```python import base64 from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-3.8-flash-tts", input=[{ "type": "user_input", "content": [{ "type": "text", "text": ( "Look out past the rings of Saturn. Those faint photons left" " their source millions of years ago." ), "annotations": [{ "type": "speech_metadata", "style": "reflective and awe-inspired", }], }], }], response_format={"type": "audio"}, generation_config={ "speech_config": [ {"voice": created_voice.id}, ] }, ) with open("designed_voice.wav", "wb") as f: f.write(base64.b64decode(interaction.output_audio.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import * as fs from "node:fs"; import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI(); const interaction = await ai.interactions.create({ model: "gemini-3.8-flash-tts", input: [{ type: "user_input", content: [{ type: "text", text: "Look out past the rings of Saturn. Those faint photons left their source millions of years ago.", annotations: [{ type: "speech_metadata", style: "reflective and awe-inspired", }], }], }], response_format: { type: "audio" }, generation_config: { speech_config: [ { voice: createdVoice.id }, ], }, }); if (interaction.output_audio?.data) { fs.writeFileSync("designed_voice.wav", Buffer.from(interaction.output_audio.data, "base64")); } ``` {% /tab %} {% tab label="REST" %} ```bash curl "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -X POST \ -d '{ "model": "gemini-3.8-flash-tts", "input": [{ "type": "user_input", "content": [{ "type": "text", "text": "Look out past the rings of Saturn. Those faint photons left their source millions of years ago.", "annotations": [{ "type": "speech_metadata", "style": "reflective and awe-inspired" }] }] }], "response_format": {"type": "audio"}, "generation_config": { "speech_config": [ {"voice": "voice_YOUR_DESIGNED_VOICE_ID"} ] } }' | jq -r '[.steps[] | select(.type=="model_output") | .content[] | select(.type=="audio")] | last | .data' | base64 --decode > out.wav ``` {% /tab %} {% /tabs %} ## Manage your voices {% id="manage-your-voices" %} You can list, filter, inspect, and delete your stored voices at any time using the Voices API (see [Extended Voice Library and filtering](/docs/speech-generation#voice-library) for all filter parameters). * **Storage limits and TTL:** Stateful voices (`store=True`, shared across prompted and replicated voices) have a limit of **200 voices per project** and a **1-year TTL** (time-to-live). * **`sample_audio` availability:** `voices.create()` (`CreateVoice`) and `voices.get()` (`GetVoice`) populate `sample_audio` (`mime_type: "audio/wav"`, base64-encoded `data`) for `"prompted"` voices. To keep listing lightweight, `voices.list()` (`ListVoices`) omits `sample_audio` (and `sample_audio` is unset for `"replicated"` and `"prebuilt"` voices). {% tabs %} {% tab label="Python" %} ```python from google import genai client = genai.Client() # List stored prompted voices in your project filtered by language response = client.voices.list( type_=["prompted"], language_code=["en-US", "en-GB"], ) for voice in response.voices or []: print(voice.id, voice.display_name, voice.type) # Retrieve a specific voice by ID voice_details = client.voices.get(id=created_voice.id) # Delete a stored custom voice client.voices.delete(id=created_voice.id) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI(); // List stored prompted voices in your project filtered by language const response = await ai.voices.list({ type: ["prompted"], language_code: ["en-US", "en-GB"], }); for (const voice of response.voices ?? []) { console.log(voice.id, voice.display_name, voice.type); } // Retrieve a specific voice by ID const voiceDetails = await ai.voices.get(createdVoice.id); // Delete a stored custom voice await ai.voices.delete(createdVoice.id); ``` {% /tab %} {% tab label="REST" %} ```bash # List stored prompted voices filtered by language curl -G "https://generativelanguage.googleapis.com/v1beta/voices" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ --data-urlencode "type=prompted" \ --data-urlencode "language_code=en-US" \ --data-urlencode "language_code=en-GB" # Retrieve a specific voice by ID curl "https://generativelanguage.googleapis.com/v1beta/voices/voice_YOUR_DESIGNED_VOICE_ID" \ -H "x-goog-api-key: $GEMINI_API_KEY" # Delete a stored custom voice curl -X DELETE "https://generativelanguage.googleapis.com/v1beta/voices/voice_YOUR_DESIGNED_VOICE_ID" \ -H "x-goog-api-key: $GEMINI_API_KEY" ``` {% /tab %} {% /tabs %} ## Prompting best practices for Voice design {% id="prompting-best-practices-for-voice-design" %} * **Put permanent vocal traits in Voice design, not `style`:** Define immutable characteristics—such as age, gender, timbre, vocal texture, and regional accent—when creating the voice in `voices.create`. * **Reserve `speech_metadata.style` for situational emotion:** Once your custom voice is created, use short `style` prompts (for example, `"whispered urgently"` or `"cheerful and energetic"`) to steer turn-by-turn acting without altering the speaker's core identity. * **Be specific and concise:** A clear 1–2 sentence description (such as *"A crisp, energetic sports announcer in her 30s with a slight Midwestern accent"*) produces cleaner, more consistent results than contradictory or overly long paragraphs. ## What's next {% id="whats-next" %} * Learn how to replicate an existing speaker's voice in [Voice replication](/docs/voice-replication). * Explore turn-level styling, inline tags, and multi-speaker dialogue in the [Text-to-speech guide](/docs/speech-generation). # Voice replication Source: https://aistudio.google.com/docs/voice-replication Description: Replicate a speaker's voice with persistent voice IDs or stateless client keys in the Gemini API. Voice replication lets you replicate a speaker's vocal characteristics from a short audio sample using the Gemini API Voices endpoint (`POST /v1beta/voices`). Both [Gemini 3.8 Flash TTS](/docs/models/gemini-3.8-flash-tts) (`gemini-3.8-flash-tts`) and [Gemini 3.8 Flash-Lite TTS](/docs/models/gemini-3.8-flash-lite-tts) (`gemini-3.8-flash-lite-tts`) support Voice replication. The fastest way to replicate, verify consent, and audition a replicated voice is with the interactive **Voice Replication** experience in [Google AI Studio](https://aistudio.google.com/generate-speech). You can record or upload reference and consent clips directly in the browser, preview the voice, and copy the resulting `voice_...` ID directly into your application code. {% button href="https://aistudio.google.com/generate-speech" variant="primary" %}Try in Google AI Studio{% /button %} ![Voice replication workflow](/googledevai/static/gemini-api/docs/images/voice-replication-overview.svg) ## Stateful versus stateless storage modes {% id="storage-modes" %} Voice replication supports two storage modes when calling `voices.create` (`POST /v1beta/voices`), with stateful storage enabled by default: * **Stateful storage (`store=True`, recommended default):** Google stores your verified voice profile in your project and returns a lightweight, persistent `voice_id` (`replicated_voice.id`, such as `voice_abc123...`). You can pass this `voice_id` across requests and manage it with `voices.list()`, `voices.get()`, and `voices.delete()`. * **Stateless client-managed keys (`store=False`, optional):** For workloads requiring zero server-side persistence of biometric voice profiles, set `store=False`. The API returns an encrypted, self-contained `voice_key` (`replicated_voice.key`, starting with `voicekey_...`) that your application stores locally and passes directly in synthesis requests. | Storage mode | Identifier | Project limit | Retention (TTL) | | :--- | :--- | :--- | :--- | | **Stateful voices** (`store=True`) | `voice_...` | **200 voices per project** (shared across prompted and replicated voices) | **1 year** | | **Stateless voice keys** (`store=False`) | `voicekey_...` | Client-managed | **7 days** | ## Audio and consent requirements {% id="audio-and-consent-requirements" %} Every `CreateVoice` replication request requires two real human audio recordings from the **same adult speaker** (24kHz mono 16-bit WAV recommended): 1. **Reference audio (`source_audio`):** A 10–30 second clip of clean, natural speech from the speaker whose voice you want to replicate. 2. **Consent audio (`consent_audio`):** A recording of the same speaker clearly reciting the mandatory consent statement in one of the [supported languages](/docs/voice-replication#consent-phrases-by-language) (for example, in English): > *"I am the owner of this voice and I consent to Google using this voice to > create a synthetic voice model."* ## Create a replicated voice (stateful default) {% id="create-a-replicated-voice" %} Use the Google GenAI SDK (`google-genai` 2.25.0+ / `@google/genai` 2.24.0+) or REST API with `store=True` to create and save a replicated voice profile in your project: {% tabs %} {% tab label="Python" %} ```python import base64 from google import genai client = genai.Client() with open("reference_speaker.wav", "rb") as f: source_b64 = base64.b64encode(f.read()).decode("utf-8") with open("speaker_consent.wav", "rb") as f: consent_b64 = base64.b64encode(f.read()).decode("utf-8") # Create a persistent replicated voice (store=True) replicated_voice = client.voices.create( store=True, voice={ "model": "gemini-3.8-flash-tts", "type": "replicated", "display_name": "Custom Replicated Speaker", "replicated": { "source_audio": { "mime_type": "audio/wav", "data": source_b64, }, "consent_audio": { "mime_type": "audio/wav", "data": consent_b64, }, }, }, ) print(f"Created voice ID: {replicated_voice.id}") ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import * as fs from "node:fs"; import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI(); const sourceB64 = fs.readFileSync("reference_speaker.wav").toString("base64"); const consentB64 = fs.readFileSync("speaker_consent.wav").toString("base64"); // Create a persistent replicated voice (store: true) const replicatedVoice = await ai.voices.create({ store: true, voice: { model: "gemini-3.8-flash-tts", type: "replicated", display_name: "Custom Replicated Speaker", replicated: { source_audio: { mime_type: "audio/wav", data: sourceB64, }, consent_audio: { mime_type: "audio/wav", data: consentB64, }, }, }, }); console.log(`Created voice ID: ${replicatedVoice.id}`); ``` {% /tab %} {% tab label="REST" %} ```bash SOURCE_B64=$(base64 -w 0 reference_speaker.wav) CONSENT_B64=$(base64 -w 0 speaker_consent.wav) curl "https://generativelanguage.googleapis.com/v1beta/voices" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -X POST \ -d "{ \"store\": true, \"voice\": { \"model\": \"gemini-3.8-flash-tts\", \"type\": \"replicated\", \"display_name\": \"Custom Replicated Speaker\", \"replicated\": { \"source_audio\": { \"mime_type\": \"audio/wav\", \"data\": \"$SOURCE_B64\" }, \"consent_audio\": { \"mime_type\": \"audio/wav\", \"data\": \"$CONSENT_B64\" } } } }" ``` {% /tab %} {% /tabs %} ## Synthesize speech with your replicated voice {% id="synthesize-speech-with-your-replicated-voice" %} Pass the returned `id` (`voice_...`) in your synthesis request: {% tabs %} {% tab label="Python" %} ```python import base64 from google import genai client = genai.Client() interaction = client.interactions.create( model="gemini-3.8-flash-tts", input=[{ "type": "user_input", "content": [{ "type": "text", "text": ( "Hello! This audio was synthesized using a replicated" " speaker voice." ), "annotations": [{ "type": "speech_metadata", "style": "warm and conversational", }], }], }], response_format={"type": "audio"}, generation_config={ "speech_config": [ {"voice": replicated_voice.id}, ] }, ) with open("replicated_speech.wav", "wb") as f: f.write(base64.b64decode(interaction.output_audio.data)) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import * as fs from "node:fs"; import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI(); const interaction = await ai.interactions.create({ model: "gemini-3.8-flash-tts", input: [{ type: "user_input", content: [{ type: "text", text: "Hello! This audio was synthesized using a replicated speaker voice.", annotations: [{ type: "speech_metadata", style: "warm and conversational", }], }], }], response_format: { type: "audio" }, generation_config: { speech_config: [ { voice: replicatedVoice.id }, ], }, }); if (interaction.output_audio?.data) { fs.writeFileSync("replicated_speech.wav", Buffer.from(interaction.output_audio.data, "base64")); } ``` {% /tab %} {% tab label="REST" %} ```bash curl "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -X POST \ -d '{ "model": "gemini-3.8-flash-tts", "input": [{ "type": "user_input", "content": [{ "type": "text", "text": "Hello! This audio was synthesized using a replicated speaker voice.", "annotations": [{ "type": "speech_metadata", "style": "warm and conversational" }] }] }], "response_format": {"type": "audio"}, "generation_config": { "speech_config": [ {"voice": "voice_YOUR_REPLICATED_VOICE_ID"} ] } }' | jq -r '[.steps[] | select(.type=="model_output") | .content[] | select(.type=="audio")] | last | .data' | base64 --decode > out.wav ``` {% /tab %} {% /tabs %} ## Manage stored replicated voices {% id="manage-stored-replicated-voices" %} When created with `store=True`, your replicated voices can be listed, filtered, inspected, and deleted through the Voices API (see [Extended Voice Library and filtering](/docs/speech-generation#voice-library) for all filter parameters): {% tabs %} {% tab label="Python" %} ```python from google import genai client = genai.Client() # List stored replicated voices in your project response = client.voices.list(type_=["replicated"]) for voice in response.voices or []: print(voice.id, voice.display_name, voice.type) # Retrieve a specific voice by ID voice_details = client.voices.get(id=replicated_voice.id) # Delete a stored replicated voice client.voices.delete(id=replicated_voice.id) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI(); // List stored replicated voices in your project const response = await ai.voices.list({ type: ["replicated"] }); for (const voice of response.voices ?? []) { console.log(voice.id, voice.display_name, voice.type); } // Retrieve a specific voice by ID const voiceDetails = await ai.voices.get(replicatedVoice.id); // Delete a stored replicated voice await ai.voices.delete(replicatedVoice.id); ``` {% /tab %} {% tab label="REST" %} ```bash # List stored replicated voices in your project curl -G "https://generativelanguage.googleapis.com/v1beta/voices" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ --data-urlencode "type=replicated" # Retrieve a specific voice by ID curl "https://generativelanguage.googleapis.com/v1beta/voices/voice_YOUR_REPLICATED_VOICE_ID" \ -H "x-goog-api-key: $GEMINI_API_KEY" # Delete a stored replicated voice curl -X DELETE "https://generativelanguage.googleapis.com/v1beta/voices/voice_YOUR_REPLICATED_VOICE_ID" \ -H "x-goog-api-key: $GEMINI_API_KEY" ``` {% /tab %} {% /tabs %} ## Option: Stateless client-managed voice keys (`store=False`) {% id="stateless-client-managed-keys" %} If your application requires zero server-side persistence of voice profiles, set `store=False` when creating the replicated voice. The API returns an encrypted `voice_key` (`replicated_voice.key`, starting with `voicekey_...`) that you store client-side and pass directly anywhere a `voice` ID is accepted: {% tabs %} {% tab label="Python" %} ```python import base64 from google import genai client = genai.Client() with open("reference_speaker.wav", "rb") as f: source_b64 = base64.b64encode(f.read()).decode("utf-8") with open("speaker_consent.wav", "rb") as f: consent_b64 = base64.b64encode(f.read()).decode("utf-8") # Create a stateless client-managed voice key (store=False) replicated_voice = client.voices.create( store=False, voice={ "model": "gemini-3.8-flash-tts", "type": "replicated", "replicated": { "source_audio": {"mime_type": "audio/wav", "data": source_b64}, "consent_audio": {"mime_type": "audio/wav", "data": consent_b64}, }, }, ) # Pass replicated_voice.key ("voicekey_...") directly as the speaker voice interaction = client.interactions.create( model="gemini-3.8-flash-tts", input=[{ "type": "user_input", "content": [{ "type": "text", "text": "Hello! This audio uses a stateless client-managed voice key.", "annotations": [{ "type": "speech_metadata", "style": "warm and conversational", }], }], }], response_format={"type": "audio"}, generation_config={ "speech_config": [ {"voice": replicated_voice.key}, ] }, ) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import * as fs from "node:fs"; import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI(); const sourceB64 = fs.readFileSync("reference_speaker.wav").toString("base64"); const consentB64 = fs.readFileSync("speaker_consent.wav").toString("base64"); // Create a stateless client-managed voice key (store: false) const replicatedVoice = await ai.voices.create({ store: false, voice: { model: "gemini-3.8-flash-tts", type: "replicated", replicated: { source_audio: { mime_type: "audio/wav", data: sourceB64 }, consent_audio: { mime_type: "audio/wav", data: consentB64 }, }, }, }); // Pass replicatedVoice.key ("voicekey_...") directly as the speaker voice const interaction = await ai.interactions.create({ model: "gemini-3.8-flash-tts", input: [{ type: "user_input", content: [{ type: "text", text: "Hello! This audio uses a stateless client-managed voice key.", annotations: [{ type: "speech_metadata", style: "warm and conversational", }], }], }], response_format: { type: "audio" }, generation_config: { speech_config: [ { voice: replicatedVoice.key }, ], }, }); ``` {% /tab %} {% tab label="REST" %} ```bash SOURCE_B64=$(base64 -w 0 reference_speaker.wav) CONSENT_B64=$(base64 -w 0 speaker_consent.wav) curl "https://generativelanguage.googleapis.com/v1beta/voices" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -X POST \ -d "{ \"store\": false, \"voice\": { \"model\": \"gemini-3.8-flash-tts\", \"type\": \"replicated\", \"replicated\": { \"source_audio\": {\"mime_type\": \"audio/wav\", \"data\": \"$SOURCE_B64\"}, \"consent_audio\": {\"mime_type\": \"audio/wav\", \"data\": \"$CONSENT_B64\"} } } }" ``` {% /tab %} {% /tabs %} ## Supported consent phrases by language {% id="consent-phrases-by-language" %} The consent audio must clearly recite the exact statement in one of the 30 supported language locales: | Language | Locale (`lang_id`) | Verbatim Consent Statement | | :--- | :--- | :--- | | **Arabic** | `ar-XA` | أنا مالك هذا الصوت وأوافق على أن تستخدم Google هذا الصوت لإنشاء نموذج صوتي اصطناعي. | | **Bengali** | `bn-IN` | আমি এই ভয়েসের মালিক এবং আমি একটি সিন্থেটিক ভয়েস মডেল তৈরি করতে এই ভয়েস ব্যবহার করে Google-এর সাথে সম্মতি দিচ্ছি। | | **Chinese (Simplified)** | `zh-CN` | 我是此声音的拥有者并授权谷歌使用此声音创建语音合成模型 | | **Dutch** | `nl-NL` | Ik ben de eigenaar van deze stem en ik geef Google toestemming om deze stem te gebruiken om een synthetisch stemmodel te maken. | | **English (US)** | `en-US` | I am the owner of this voice and I consent to Google using this voice to create a synthetic voice model. | | **English (UK)** | `en-GB` | I am the owner of this voice and I consent to Google using this voice to create a synthetic voice model. | | **English (India)** | `en-IN` | I am the owner of this voice and I consent to Google using this voice to create a synthetic voice model. | | **English (Australia)** | `en-AU` | I am the owner of this voice and I consent to Google using this voice to create a synthetic voice model. | | **French (France)** | `fr-FR` | Je suis le propriétaire de cette voix et j'autorise Google à utiliser cette voix pour créer un modèle de voix synthétique. | | **French (Canada)** | `fr-CA` | Je suis le propriétaire de cette voix et j'autorise Google à utiliser cette voix pour créer un modèle de voix synthétique. | | **German** | `de-DE` | Ich bin der Eigentümer dieser Stimme und bin damit einverstanden, dass Google diese Stimme zur Erstellung eines synthetischen Stimmmodells verwendet. | | **Gujarati** | `gu-IN` | હું આ વોઈસનો માલિક છું અને સિન્થેટિક વોઈસ મોડલ બનાવવા માટે આ વોઈસનો ઉપયોગ કરીને google ને હું સંમતિ આપું છું | | **Hindi** | `hi-IN` | मैं इस आवाज का मालिक हूं और मैं सिंथेटिक आवाज मॉडल बनाने के लिए Google को इस आवाज का उपयोग करने की सहमति देता हूं | | **Indonesian** | `id-ID` | Saya pemilik suara ini dan saya menyetujui Google menggunakan suara ini untuk membuat model suara sintetis. | | **Italian** | `it-IT` | Sono il proprietario di questa voce e acconsento che Google la utilizzi per creare un modello di voce sintetica. | | **Japanese** | `ja-JP` | 私はこの音声の所有者であり、Googleがこの音声を使用して音声合成モデルを作成することを承認します。 | | **Kannada** | `kn-IN` | ನಾನು ಈ ಧ್ವನಿಯ ಮಾಲಿಕ ಮತ್ತು ಸಂಶ್ಲೇಷಿತ ಧ್ವನಿ ಮಾದರಿಯನ್ನು ರಚಿಸಲು ಈ ಧ್ವನಿಯನ್ನು ಬಳಸಿಕೊಂಡುಗೂಗಲ್ ಗೆ ನಾನು ಸಮ್ಮತಿಸುತ್ತೇನೆ. | | **Korean** | `ko-KR` | 나는 이 음성의 소유자이며 구글이 이 음성을 사용하여 음성 합성 모델을 생성할 것을 허용합니다. | | **Malayalam** | `ml-IN` | ഈ ശബ്ദത്തിന്റെ ഉടമ ഞാനാണ്, ഒരു സിന്തറ്റിക് വോയ്സ് മോഡൽ സൃഷ്ടിക്കാൻ ഈ ശബ്ദം ഉപയോഗിക്കുന്നതിന് ഞാൻ Google-ന് സമ്മതം നൽകുന്നു. | | **Marathi** | `mr-IN` | मी या आवाजाचा मालक आहे आणि सिंथेटिक व्हॉइस मॉडेल तयार करण्यासाठी हा आवाज वापरण्यासाठी मी Google ला संमती देतो | | **Polish** | `pl-PL` | Jestem właścicielem tego głosu i wyrażam zgodę na wykorzystanie go przez Google w celu utworzenia syntetycznego modelu głosu. | | **Portuguese (Brazil)** | `pt-BR` | Eu sou o proprietário desta voz e autorizo o Google a usá-la para criar um modelo de voz sintética. | | **Russian** | `ru-RU` | Я являюсь владельцем этого голоса и даю согласие Google на использование этого голоса для создания модели синтетического голоса. | | **Spanish (Spain)** | `es-ES` | Soy el propietario de esta voz y doy mi consentimiento para que Google la utilice para crear un modelo de voz sintética. | | **Spanish (US)** | `es-US` | Soy el propietario de esta voz y doy mi consentimiento para que Google la utilice para crear un modelo de voz sintética. | | **Tamil** | `ta-IN` | நான் இந்த குரலின் உரிமையாளர் மற்றும் செயற்கை குரல் மாதிரியை உருவாக்க இந்த குரலை பயன்படுத்த குகல்க்கு நான் ஒப்புக்கொள்கிறேன். | | **Telugu** | `te-IN` | నేను ఈ వాయిస్ యజమానిని మరియు సింతటిక్ వాయిస్ మోడల్ ని రూపొందించడానికి ఈ వాయిస్ ని ఉపయోగించడానికి googleకి నేను సమ్మతిస్తున్నాను. | | **Thai** | `th-TH` | ฉันเป็นเจ้าของเสียงนี้ และฉันยินยอมให้ Google ใช้เสียงนี้เพื่อสร้างแบบจำลองเสียงสังเคราะห์ | | **Turkish** | `tr-TR` | Bu sesin sahibi benim ve Google'ın bu sesi kullanarak sentetik bir ses modeli oluşturmasına izin veriyorum. | | **Vietnamese** | `vi-VN` | Tôi là chủ sở hữu giọng nói này và tôi đồng ý cho Google sử dụng giọng nói này để tạo mô hình giọng nói tổng hợp. | ## Best practices for recording reference audio {% id="best-practices" %} * **Record in a quiet environment:** Minimize room echo, background noise, music, and overlapping voices. * **Match recording conditions:** Record both `source_audio` and `consent_audio` on the same microphone in the same acoustic setting so the speaker verification check succeeds reliably. * **Convert to 24kHz mono WAV:** For best results, resample input audio to 24kHz mono 16-bit PCM WAV before encoding. ## What's next {% id="whats-next" %} * Learn how to create custom personas from text descriptions in [Voice design](/docs/voice-design). * Explore turn-level styling, inline tags, and multi-speaker dialogue in the [Text-to-speech guide](/docs/speech-generation). # Audio transcription Source: https://aistudio.google.com/docs/transcribe Description: Get started transcribing audio with the Gemini 3.5 Transcribe model in the Gemini API The Gemini API converts speech in audio files into text using the Gemini 3.5 Transcribe model (`gemini-3.5-transcribe`). Based on Gemini's audio understanding capabilities, it delivers accurate transcription with automatic language identification, speaker diarization, word-level timestamps, and custom vocabulary hints. It also provides a [smart transcription](/docs/transcribe#transcription-modes) mode featuring disfluency removal and smart formatting. To transcribe an audio file, upload the audio and pass it to `gemini-3.5-transcribe`: {% tabs %} {% tab label="Python" filename="transcribe_quickstart.py" %} ```python from google import genai client = genai.Client() audio_file = client.files.upload(file="path/to/sample.mp3") response = client.interactions.create( model="gemini-3.5-transcribe", input=[audio_file], ) print(response.output_text) ``` {% /tab %} {% tab label="JavaScript" filename="transcribe_quickstart.js" %} ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({}); const audioFile = await ai.files.upload({ file: "path/to/sample.mp3", config: { mimeType: "audio/mp3" }, }); const response = await ai.interactions.create({ model: "gemini-3.5-transcribe", input: [ { type: "audio", uri: audioFile.uri, mime_type: audioFile.mimeType, }, ], }); console.log(response.output_text); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } audioFile, err := client.Files.UploadFromPath(ctx, "path/to/sample.mp3", nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.5-transcribe"), Input: interactions.NewInteractionsInput([]interactions.Content{ interactions.NewContent(interactions.AudioContent{ URI: genai.Ptr(audioFile.URI), MimeType: interactions.AudioContentMimeType(audioFile.MIMEType).ToPointer(), }), }), }), }) if err != nil { log.Fatal(err) } fmt.Println(res.Interaction.GetOutputText()) } ``` {% /tab %} {% tab label="REST" filename="transcribe_quickstart.sh" %} ```bash # First upload the file via the Files API, then pass its URI: curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "models/gemini-3.5-transcribe", "input": [ { "type": "file", "file_uri": "YOUR_FILE_URI" } ] }' ``` {% /tab %} {% /tabs %} {% callout type="note" %} For real-time, low-latency streaming speech recognition from a microphone or live audio stream, see [Live transcription](/docs/live-api/live-transcribe) using the Live API and `gemini-3.5-transcribe-live`. {% /callout %} ## Overview {% id="overview" %} Gemini 3.5 Transcribe is optimized for speech-to-text tasks. It handles diverse accents, background noise, and multi-language conversations. Key capabilities include: * **Automatic speech recognition (ASR):** Automatically detects languages across [85+ locales](/docs/transcribe#supported-languages). Handles intra-sentence and inter-sentential code-switching without manual configuration. * **Custom vocabulary:** Biases recognition toward domain-specific terms, acronyms, and proper names by passing up to 1,000 phrases. * **Speaker diarization:** Distinguishes between multiple speakers and attributes spoken segments to distinct labels. * **Word-level timestamps:** Generates precise start and end time offsets for each recognized word. * **Smart transcription:** Cleans up disfluencies, filler words, repetitions, and applies structured formatting. * **Formatting and normalization:** Applies capitalization, punctuation, and inverse text normalization, such as converting "twenty six million dollars" to "$26M". For general audio reasoning or question answering over audio content, use [Audio understanding](/docs/audio). For text-to-speech audio synthesis, use [Text-to-speech](/docs/speech-generation). ## Language detection and hints {% id="language-detection" %} By default, the model detects the spoken language automatically. It switches between languages dynamically when speakers code-switch. To use automatic detection, omit `language_codes` or provide an empty list: {% tabs %} {% tab label="Python" filename="transcribe_language_auto.py" %} ```python from google import genai client = genai.Client() response = client.interactions.create( model="gemini-3.5-transcribe", input=[audio_file], generation_config={ "transcription_config": { "language_codes": [], } }, ) ``` {% /tab %} {% tab label="JavaScript" filename="transcribe_language_auto.js" %} ```javascript const response = await ai.interactions.create({ model: "gemini-3.5-transcribe", input: [audioFile], generationConfig: { transcriptionConfig: { languageCodes: [], }, }, }); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } audioFile, err := client.Files.UploadFromPath(ctx, "path/to/sample.mp3", nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.5-transcribe"), Input: interactions.NewInteractionsInput([]interactions.Content{ interactions.NewContent(interactions.AudioContent{ URI: genai.Ptr(audioFile.URI), MimeType: interactions.AudioContentMimeType(audioFile.MIMEType).ToPointer(), }), }), GenerationConfig: &interactions.GenerationConfig{ TranscriptionConfig: &interactions.TranscriptionConfig{ LanguageCodes: []string{}, }, }, }), }) if err != nil { log.Fatal(err) } fmt.Println(res.Interaction.GetOutputText()) } ``` {% /tab %} {% tab label="REST" filename="transcribe_language_auto.sh" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "models/gemini-3.5-transcribe", "input": [ { "type": "file", "file_uri": "YOUR_FILE_URI" } ], "generation_config": { "transcription_config": { "language_codes": [] } } }' ``` {% /tab %} {% /tabs %} If you know the language in advance, specify BCP-47 language codes in `language_codes` to improve transcription accuracy (see [Supported languages](/docs/transcribe#supported-languages)): {% tabs %} {% tab label="Python" filename="transcribe_language_hint.py" %} ```python generation_config = { "transcription_config": { "language_codes": ["es-ES"], } } ``` {% /tab %} {% tab label="JavaScript" filename="transcribe_language_hint.js" %} ```javascript const generationConfig = { transcriptionConfig: { languageCodes: ["es-ES"], }, }; ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "google.golang.org/genai/interactions/models/interactions" ) func main() { generationConfig := &interactions.GenerationConfig{ TranscriptionConfig: &interactions.TranscriptionConfig{ LanguageCodes: []string{"es-ES"}, }, } _ = generationConfig } ``` {% /tab %} {% tab label="REST" filename="transcribe_language_hint.json" %} ```json { "generation_config": { "transcription_config": { "language_codes": ["es-ES"] } } } ``` {% /tab %} {% /tabs %} ## Custom vocabulary {% id="custom-vocabulary" %} You can steer the speech model toward uncommon words, technical jargon, brand names, or proper nouns. Supply up to 1,000 terms in the `custom_vocabulary` array (best results are typically achieved with up to 100 terms): {% callout type="note" %} You cannot combine `custom_vocabulary` with speaker diarization or word-level timestamps. The API rejects requests that include `custom_vocabulary` with either feature. {% /callout %} {% tabs %} {% tab label="Python" filename="transcribe_custom_vocab.py" %} ```python from google import genai client = genai.Client() response = client.interactions.create( model="gemini-3.5-transcribe", input=[audio_file], generation_config={ "transcription_config": { "custom_vocabulary": ["Gemini", "Kubernetes", "BigQuery"], } }, ) ``` {% /tab %} {% tab label="JavaScript" filename="transcribe_custom_vocab.js" %} ```javascript const response = await ai.interactions.create({ model: "gemini-3.5-transcribe", input: [audioFile], generationConfig: { transcriptionConfig: { customVocabulary: ["Gemini", "Kubernetes", "BigQuery"], }, }, }); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } audioFile, err := client.Files.UploadFromPath(ctx, "path/to/sample.mp3", nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.5-transcribe"), Input: interactions.NewInteractionsInput([]interactions.Content{ interactions.NewContent(interactions.AudioContent{ URI: genai.Ptr(audioFile.URI), MimeType: interactions.AudioContentMimeType(audioFile.MIMEType).ToPointer(), }), }), GenerationConfig: &interactions.GenerationConfig{ TranscriptionConfig: &interactions.TranscriptionConfig{ CustomVocabulary: []string{"Gemini", "Kubernetes", "BigQuery"}, }, }, }), }) if err != nil { log.Fatal(err) } fmt.Println(res.Interaction.GetOutputText()) } ``` {% /tab %} {% tab label="REST" filename="transcribe_custom_vocab.sh" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "models/gemini-3.5-transcribe", "input": [ { "type": "file", "file_uri": "YOUR_FILE_URI" } ], "generation_config": { "transcription_config": { "custom_vocabulary": ["Gemini", "Kubernetes", "BigQuery"] } } }' ``` {% /tab %} {% /tabs %} ## Speaker diarization {% id="speaker-diarization" %} Speaker diarization identifies different voices in the recording and tags each segment with a speaker identifier like `spk_1` or `spk_2`. Up to 8 speakers are supported (attribution for 3 or more speakers is experimental). Enable diarization by setting `diarization_mode` to `"speaker"` within `mode`: {% tabs %} {% tab label="Python" filename="transcribe_diarization.py" %} ```python from google import genai client = genai.Client() response = client.interactions.create( model="gemini-3.5-transcribe", input=[audio_file], generation_config={ "transcription_config": { "mode": { "type": "verbatim", "diarization_mode": "speaker", } } }, ) ``` {% /tab %} {% tab label="JavaScript" filename="transcribe_diarization.js" %} ```javascript const response = await ai.interactions.create({ model: "gemini-3.5-transcribe", input: [audioFile], generationConfig: { transcriptionConfig: { mode: { type: "verbatim", diarizationMode: "speaker", }, }, }, }); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } audioFile, err := client.Files.UploadFromPath(ctx, "path/to/sample.mp3", nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.5-transcribe"), Input: interactions.NewInteractionsInput([]interactions.Content{ interactions.NewContent(interactions.AudioContent{ URI: genai.Ptr(audioFile.URI), MimeType: interactions.AudioContentMimeType(audioFile.MIMEType).ToPointer(), }), }), GenerationConfig: &interactions.GenerationConfig{ TranscriptionConfig: &interactions.TranscriptionConfig{ Mode: genai.Ptr(interactions.NewTranscriptionConfigMode(interactions.NewTranscriptionMode(interactions.VerbatimTranscriptionMode{ DiarizationMode: genai.Ptr("speaker"), }))), }, }, }), }) if err != nil { log.Fatal(err) } fmt.Println(res.Interaction.GetOutputText()) } ``` {% /tab %} {% tab label="REST" filename="transcribe_diarization.sh" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "models/gemini-3.5-transcribe", "input": [ { "type": "file", "file_uri": "YOUR_FILE_URI" } ], "generation_config": { "transcription_config": { "mode": { "type": "verbatim", "diarization_mode": "speaker" } } } }' ``` {% /tab %} {% /tabs %} ## Word-level timestamps {% id="word-timestamps" %} Word-level timestamps provide exact start and end offsets for every recognized word in the audio stream. {% callout type="note" %} Enabling word-level timestamps may degrade overall transcription accuracy. {% /callout %} Enable timestamps by setting `timestamp_granularities` to `["word"]` within `mode`: {% tabs %} {% tab label="Python" filename="transcribe_timestamps.py" %} ```python from google import genai client = genai.Client() response = client.interactions.create( model="gemini-3.5-transcribe", input=[audio_file], generation_config={ "transcription_config": { "mode": { "type": "verbatim", "timestamp_granularities": ["word"], } } }, ) ``` {% /tab %} {% tab label="JavaScript" filename="transcribe_timestamps.js" %} ```javascript const response = await ai.interactions.create({ model: "gemini-3.5-transcribe", input: [audioFile], generationConfig: { transcriptionConfig: { mode: { type: "verbatim", timestampGranularities: ["word"], }, }, }, }); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } audioFile, err := client.Files.UploadFromPath(ctx, "path/to/sample.mp3", nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.5-transcribe"), Input: interactions.NewInteractionsInput([]interactions.Content{ interactions.NewContent(interactions.AudioContent{ URI: genai.Ptr(audioFile.URI), MimeType: interactions.AudioContentMimeType(audioFile.MIMEType).ToPointer(), }), }), GenerationConfig: &interactions.GenerationConfig{ TranscriptionConfig: &interactions.TranscriptionConfig{ Mode: genai.Ptr(interactions.NewTranscriptionConfigMode(interactions.NewTranscriptionMode(interactions.VerbatimTranscriptionMode{ TimestampGranularities: []string{"word"}, }))), }, }, }), }) if err != nil { log.Fatal(err) } fmt.Println(res.Interaction.GetOutputText()) } ``` {% /tab %} {% tab label="REST" filename="transcribe_timestamps.sh" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "models/gemini-3.5-transcribe", "input": [ { "type": "file", "file_uri": "YOUR_FILE_URI" } ], "generation_config": { "transcription_config": { "mode": { "type": "verbatim", "timestamp_granularities": ["word"] } } } }' ``` {% /tab %} {% /tabs %} You can combine `diarization_mode` and `timestamp_granularities` in a single request to receive both speaker labels and word timestamps: {% tabs %} {% tab label="Python" filename="transcribe_diarization_timestamps.py" %} ```python generation_config = { "transcription_config": { "mode": { "type": "verbatim", "diarization_mode": "speaker", "timestamp_granularities": ["word"], }, } } ``` {% /tab %} {% tab label="JavaScript" filename="transcribe_diarization_timestamps.js" %} ```javascript const generationConfig = { transcriptionConfig: { mode: { type: "verbatim", diarizationMode: "speaker", timestampGranularities: ["word"], }, }, }; ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" ) func main() { generationConfig := &interactions.GenerationConfig{ TranscriptionConfig: &interactions.TranscriptionConfig{ Mode: genai.Ptr(interactions.NewTranscriptionConfigMode(interactions.NewTranscriptionMode(interactions.VerbatimTranscriptionMode{ DiarizationMode: genai.Ptr("speaker"), TimestampGranularities: []string{"word"}, }))), }, } _ = generationConfig } ``` {% /tab %} {% tab label="REST" filename="transcribe_diarization_timestamps.json" %} ```json { "generation_config": { "transcription_config": { "mode": { "type": "verbatim", "diarization_mode": "speaker", "timestamp_granularities": ["word"] } } } } ``` {% /tab %} {% /tabs %} ## Transcription modes {% id="transcription-modes" %} Gemini 3.5 Transcribe supports two transcription modes via the `mode` parameter: * **`verbatim` (default)**: Returns an exact word-for-word transcript of everything spoken, preserving raw filler words ("um", "uh", "like", "you know"), repetitions, pauses, and false starts. Required when using timestamps or speaker diarization. * **`smart` (Smart transcription)**: Optimizes the transcript for reading by applying intelligent post-processing: * **Disfluency removal**: Strips conversational filler words, stuttering, and false starts. * **Inline self-corrections**: Resolves spoken corrections directly (for example, *"Let's meet on Tuesday, actually no, Wednesday at two"* becomes *"Let's meet on Wednesday at 2:00 PM"*). * **Automatic structured formatting**: Automatically structures spoken thoughts into paragraphs, numbered lists, bullet points, formatted dates, currencies, and numbers. * **Grammatical cleanup**: Applies natural punctuation, sentence casing, and flow. {% table %} * Spoken audio * `verbatim` output * `smart` (Smart transcription) output --- * "Um, so for the meeting, I think we should, uh, invite Alice and, wait no, Bob and Carol." * "Um so for the meeting I think we should uh invite Alice and wait no Bob and Carol." * "For the meeting, I think we should invite Bob and Carol." --- * "First item review budget second item finalize timeline third item send recap" * "first item review budget second item finalize timeline third item send recap" * 1. Review budget 2. Finalize timeline 3. Send recap {% /table %} {% tabs %} {% tab label="Python" filename="transcribe_smart_mode.py" %} ```python from google import genai client = genai.Client() response = client.interactions.create( model="gemini-3.5-transcribe", input=[audio_file], generation_config={ "transcription_config": { "mode": "smart", } }, ) print(response.output_text) ``` {% /tab %} {% tab label="JavaScript" filename="transcribe_smart_mode.js" %} ```javascript const response = await ai.interactions.create({ model: "gemini-3.5-transcribe", input: [audioFile], generationConfig: { transcriptionConfig: { mode: "smart", }, }, }); console.log(response.outputText); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } audioFile, err := client.Files.UploadFromPath(ctx, "path/to/sample.mp3", nil) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-3.5-transcribe"), Input: interactions.NewInteractionsInput([]interactions.Content{ interactions.NewContent(interactions.AudioContent{ URI: genai.Ptr(audioFile.URI), MimeType: interactions.AudioContentMimeType(audioFile.MIMEType).ToPointer(), }), }), GenerationConfig: &interactions.GenerationConfig{ TranscriptionConfig: &interactions.TranscriptionConfig{ Mode: genai.Ptr(interactions.NewTranscriptionConfigMode(interactions.TranscriptionConfigModeEnumSmart)), }, }, }), }) if err != nil { log.Fatal(err) } fmt.Println(res.Interaction.GetOutputText()) } ``` {% /tab %} {% tab label="REST" filename="transcribe_smart_mode.sh" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "models/gemini-3.5-transcribe", "input": [ { "type": "file", "file_uri": "YOUR_FILE_URI" } ], "generation_config": { "transcription_config": { "mode": "smart" } } }' ``` {% /tab %} {% /tabs %} {% callout type="note" %} Smart transcription (`"smart"`) is incompatible with `timestamp_granularities` and `diarization_mode`. If you need word timestamps or speaker diarization, use verbatim mode (default). {% /callout %} ## Parsing transcription output {% id="parsing-output" %} The complete transcript text is returned in `response.output_text`. When `timestamp_granularities` or `diarization_mode` is enabled, the API also returns detailed word-level annotations attached to the interaction content. Here is how to extract and iterate over word timestamps and speaker turns: {% tabs %} {% tab label="Python" filename="transcribe_parse_output.py" %} ```python def extract_word_annotations(response): words = [] for step in getattr(response, "steps", []) or []: for content in getattr(step, "content", []) or []: for annotation in getattr(content, "annotations", []) or []: if getattr(annotation, "type", None) == "word_info": words.append(annotation) return words words = extract_word_annotations(response) for w in words: speaker = f"[{w.speaker}] " if getattr(w, "speaker", None) else "" start = getattr(w, "start_offset", "") end = getattr(w, "end_offset", "") timing = f"({start} -> {end}) " if start and end else "" print(f"{speaker}{timing}{w.text}") ``` {% /tab %} {% tab label="JavaScript" filename="transcribe_parse_output.js" %} ```javascript function extractWordAnnotations(response) { const words = []; for (const step of response.steps ?? []) { for (const content of step.content ?? []) { for (const annotation of content.annotations ?? []) { if (annotation.type === "word_info") { words.push(annotation); } } } } return words; } const words = extractWordAnnotations(response); for (const w of words) { const speaker = w.speaker ? `[${w.speaker}] ` : ""; const timing = (w.start_offset && w.end_offset) ? `(${w.start_offset} -> ${w.end_offset}) ` : ""; console.log(`${speaker}${timing}${w.text}`); } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "fmt" "google.golang.org/genai/interactions/models/interactions" ) func extractWordAnnotations(interaction *interactions.Interaction) []*interactions.WordInfo { var words []*interactions.WordInfo if interaction == nil { return words } for _, step := range interaction.Steps { if step.ModelOutputStep != nil { for _, content := range step.ModelOutputStep.Content { if content.TextContent != nil { for _, annotation := range content.TextContent.Annotations { if annotation.WordInfo != nil { words = append(words, annotation.WordInfo) } } } } } } return words } func main() { var interaction *interactions.Interaction words := extractWordAnnotations(interaction) for _, w := range words { speaker := "" if w.Speaker != nil && *w.Speaker != "" { speaker = fmt.Sprintf("[%s] ", *w.Speaker) } timing := "" if w.StartOffset != nil && w.EndOffset != nil { timing = fmt.Sprintf("(%s -> %s) ", *w.StartOffset, *w.EndOffset) } fmt.Printf("%s%s%s\n", speaker, timing, w.GetText()) } } ``` {% /tab %} {% tab label="REST" filename="transcribe_parse_output.json" %} ```json { "id": "interactions/abc123xyz", "status": "completed", "steps": [ { "id": "step_001", "type": "model_output", "content": [ { "type": "text", "text": "Hello world", "annotations": [ { "type": "word_info", "text": "Hello", "speaker": "spk_1", "start_offset": "0.100s", "end_offset": "0.400s" }, { "type": "word_info", "text": "world", "speaker": "spk_1", "start_offset": "0.500s", "end_offset": "0.800s" } ] } ] } ] } ``` {% /tab %} {% /tabs %} ## Supported languages {% id="supported-languages" %} The following languages and BCP-47 language codes are supported for Gemini 3.5 Transcribe: | Language | BCP-47 Code | Language | BCP-47 Code | | :--- | :--- | :--- | :--- | | Afrikaans | `af-ZA` | Japanese | `ja-JP` | | Amharic | `am-ET` | Javanese | `jv-ID` | | Arabic (Egypt) | `ar-EG` | Kabuverdianu | `kea-CV` | | Armenian | `hy-AM` | Kannada | `kn-IN` | | Assamese | `as-IN` | Kazakh | `kk-KZ` | | Azerbaijani | `az-AZ` | Korean | `ko-KR` | | Belarusian | `be-BY` | Kyrgyz | `ky-KG` | | Bengali (Bangladesh) | `bn-BD` | Latvian | `lv-LV` | | Bengali (India) | `bn-IN` | Lingala | `ln-CD` | | Bosnian | `bs-BA` | Lithuanian | `lt-LT` | | Bulgarian | `bg-BG` | Macedonian | `mk-MK` | | Bulgarian (Aromanian) | `rup-BG` | Malay | `ms-MY` | | Burmese | `my-MM` | Malayalam | `ml-IN` | | Cantonese (Traditional) | `yue-Hant-HK` | Maltese | `mt-MT` | | Catalan | `ca-ES` | Mandarin Chinese (Simplified) | `cmn-Hans-CN` | | Cebuano | `ceb` | Marathi | `mr-IN` | | Central Khmer | `km-KH` | Mongolian | `mn-MN` | | Croatian | `hr-HR` | Nepali | `ne-NP` | | Czech | `cs-CZ` | Norwegian | `nb-NO` | | Danish | `da-DK` | Oriya | `or-IN` | | Dutch | `nl-NL` | Polish | `pl-PL` | | English (Great Britain) | `en-GB` | Portuguese (Brazil) | `pt-BR` | | English (India) | `en-IN` | Portuguese (Portugal) | `pt-PT` | | English (United States) | `en-US` | Punjabi | `pa-IN` | | Estonian | `et-EE` | Punjabi (Gurmukhi script) | `pa-Guru-IN` | | Farsi | `fa-IR` | Romanian | `ro-RO` | | Filipino | `fil-PH` | Russian | `ru-RU` | | Finnish | `fi-FI` | Serbian | `sr-RS` | | French | `fr-FR` | Sindhi (Arabic script) | `sd-Arab-IN` | | Galician | `gl-ES` | Slovak | `sk-SK` | | Georgian | `ka-GE` | Slovenian | `sl-SI` | | German | `de-DE` | Spanish (Latin America) | `es-419` | | Greek | `el-GR` | Spanish (United States) | `es-US` | | Gujarati | `gu-IN` | Swahili (Kenya) | `sw-KE` | | Hausa | `ha-NG` | Swedish | `sv-SE` | | Hebrew | `he-IL` | Tajik | `tg-TJ` | | Hindi | `hi-IN` | Telugu | `te-IN` | | Hungarian | `hu-HU` | Thai | `th-TH` | | Icelandic | `is-IS` | Turkish | `tr-TR` | | Indian English | `en-IN` | Ukrainian | `uk-UA` | | Indonesian | `id-ID` | Uzbek | `uz-UZ` | | Italian | `it-IT` | Vietnamese | `vi-VN` | ## Supported audio formats {% id="supported-formats" %} Gemini 3.5 Transcribe supports the following audio format MIME types: * WAV - `audio/wav` * MP3 - `audio/mp3` * AIFF - `audio/aiff` * AAC - `audio/aac` * OGG - `audio/ogg` * FLAC - `audio/flac` * MPEG - `audio/mpeg` * M4A - `audio/m4a` * L16 - `audio/l16` * Opus - `audio/opus` * ALAW - `audio/alaw` * MULAW - `audio/mulaw` * WebM - `audio/webm` For the complete list of supported MIME types and parameter schemas, see the [Interactions API reference](https://ai.google.dev/api/interactions-api#Resource:Content). ## Parameter reference {% id="parameter-reference" %} Configure transcription by setting fields within the `transcription_config` object in `generation_config`: | Field | Type | Description | | :--- | :--- | :--- | | `language_codes` | Array of strings | BCP-47 language codes (e.g., `["en-US"]`). If omitted or empty (`[]`), the model automatically detects the language and handles code-switching. | | `custom_vocabulary` | Array of strings | Up to 1,000 custom terms, acronyms, or proper names to bias speech recognition. Incompatible with speaker diarization and word-level timestamps. | | `mode` | Object or String | Transcription mode configuration. Accepts `"smart"` or a verbatim mode object (`{"type": "verbatim", ...}`). Defaults to verbatim transcription. | | `mode.type` | String | *(Verbatim mode only)* Mode identifier. Always set to `"verbatim"`. | | `mode.timestamp_granularities` | Array of strings | *(Verbatim mode only)* Granularity of timestamps to return. Pass `["word"]` to enable word start and end offsets. Incompatible with custom vocabulary. | | `mode.diarization_mode` | String | *(Verbatim mode only)* Diarization mode. Pass `"speaker"` to identify and label distinct speakers. Incompatible with custom vocabulary. | ## Best practices {% id="best-practices" %} * **Provide clean audio:** Ensure audio recordings have clear voice separation and avoid severe clipping. * **Provide language hints when known:** If you know the audio language in advance, specify `language_codes` to maximize accuracy. * **Target custom vocabulary:** Include only distinct domain terms, brand names, or proper nouns in `custom_vocabulary` rather than common everyday words. * **Use the Files API for large recordings:** For files longer than a few seconds, upload the file using `client.files.upload` and pass the returned file URI to the model. ## Limitations {% id="limitations" %} * **Audio duration:** Standard unary requests support audio files up to 1 hour. Audio processing is limited to 30 minutes when features like speaker diarization or word-level timestamps are enabled. * **Word-level timestamps:** Enabling word-level timestamps may degrade overall transcription accuracy. * **Speaker diarization:** Speaker diarization supports up to 8 speakers. Speaker attribution for 3 or more speakers is experimental. * **Custom vocabulary:** You can provide up to 1,000 terms in `custom_vocabulary`, but best results are typically achieved with up to 100 terms. You cannot combine `custom_vocabulary` with speaker diarization or word-level timestamps; the API rejects requests that specify `custom_vocabulary` alongside either feature. * **Mode compatibility:** Smart transcription (`"smart"`) cannot be combined with `timestamp_granularities` or `diarization_mode`. ## What's next {% id="whats-next" %} * Stream real-time audio with the [Live transcription guide](/docs/live-api/live-transcribe) using the Live API. * Explore [Audio understanding](/docs/audio) to analyze, summarize, or query audio content. * Learn how to synthesize audio from text using [Text-to-speech](/docs/speech-generation). * Check the [Pricing page](/docs/pricing#gemini-3.5-transcribe) for model pricing and token limits. * Check the [Files API](/docs/files) guide for details on uploading and managing media files. # Gemini Live API overview Source: https://aistudio.google.com/docs/live-api Description: Enable low-latency, real-time voice and video interactions with the Live API. The Live API enables low-latency, real-time voice and vision interactions with Gemini. It processes continuous streams of audio, images, and text to deliver immediate, human-like spoken responses, creating a natural conversational experience for your users. ![Live API Overview](/googledevai/static/gemini-api/docs/images/live-api-overview.png) {% button href="https://aistudio.google.com/live" variant="primary" icon="mic" %}Try the Live API in Google AI Studio{% /button %} {% button href="https://github.com/google-gemini/gemini-live-api-examples" variant="primary" icon="code" %}Clone example apps from GitHub{% /button %} {% button href="/docs/coding-agents" variant="primary" icon="terminal" %}Use coding agent skills{% /button %} ## Use cases {% id="use-cases" %} Live API can be used to build real-time voice agents for a variety of industries, including: * **E-commerce and retail:** Shopping assistants that offer personalized recommendations and support agents that resolve customer issues. * **Gaming:** Interactive non-player characters (NPCs), in-game help assistants, and real-time translation of in-game content. * **Next-gen interfaces:** Voice- and video-enabled experiences in robotics, smart glasses, and vehicles. * **Healthcare:** Health companions for patient support and education. * **Financial services:** AI advisors for wealth management and investment guidance. * **Education:** AI mentors and learner companions that provide personalized instruction and feedback. * **Translation and localization:** Real-time, low-latency translation of spoken conversations, enabling seamless multilingual communication. * **Live transcription and captioning:** Real-time speech-to-text streaming for live subtitles, meeting transcription, voice dictation, and customer call logging. ## Key features {% id="key-features" %} Live API offers a comprehensive set of features for building robust voice agents: * [**Multilingual support**](/docs/live-api/capabilities#supported-languages): Converse in 70 supported languages. * [**Barge-in**](/docs/live-api/capabilities#interruptions): Users can interrupt the model at any time for responsive interactions. * [**Tool use**](/docs/live-api/tools): Integrates tools like function calling and Google Search for dynamic interactions. * [**Audio transcriptions**](/docs/live-api/capabilities#audio-transcription): Provides text transcripts of both user input and model output. * [**Proactive audio**](/docs/live-api/capabilities#proactive-audio): Lets you control when the model responds and in what contexts. * [**Affective dialog**](/docs/live-api/capabilities#affective-dialog): Adapts response style and tone to match the user's input expression. * [**Live Transcription**](/docs/live-api/live-transcribe): Real-time, continuous speech-to-text streaming with automatic language detection and custom vocabulary. * [**Live Translation**](/docs/live-api/live-translate): Real-time voice-to-voice translation in 70+ languages. ## Technical specifications {% id="technical-specifications" %} The following table outlines the technical specifications for the Live API: {% table %} * Category * Details --- * Input modalities * Audio (raw 16-bit PCM audio, 16kHz, little-endian), images (JPEG <= 1FPS), text --- * Output modalities * Audio (raw 16-bit PCM audio, 24kHz, little-endian) --- * Protocol * Stateful WebSocket connection (WSS) {% /table %} ## Choose an implementation approach {% id="implementation-approach" %} When integrating with Live API, you'll need to choose one of the following implementation approaches: - **Server-to-server**: Your backend connects to the Live API using [WebSockets][websocket]. Typically, your client sends stream data (audio, video, text) to your server, which then forwards it to the Live API. - **Client-to-server**: Your frontend code connects directly to the Live API using [WebSockets][websocket] to stream data, bypassing your backend. {% callout type="note" %} Note: Client-to-server generally offers better performance for streaming audio and video, since it bypasses the need to send the stream to your backend first. It's also easier to set up since you don't need to implement a proxy that sends data from your client to your server and then your server to the API. However, for production environments, in order to mitigate security risks, we recommend using [ephemeral tokens](/docs/live-api/ephemeral-tokens) instead of standard API keys. {% /callout %} ## Get started {% id="get-started" %} Select the guide that matches your development environment: {% card-grid %} {% card href="/docs/live-api/get-started-sdk" title="GenAI SDK tutorial" badge="Server-to-server" description="Connect to the Gemini Live API using the GenAI SDK to build a real-time multimodal application with a Python backend." /%} {% card href="/docs/live-api/get-started-websocket" title="WebSocket tutorial" badge="Client-to-server" description="Connect to the Gemini Live API using WebSockets to build a real-time multimodal application with a JavaScript frontend and ephemeral tokens." /%} {% card href="https://google.github.io/adk-docs/streaming/" title="ADK tutorial" badge="Agent Development Kit" description="Create an agent and use the Agent Development Kit (ADK) Streaming to enable voice and video communication." /%} {% /card-grid %} ## Partner integrations {% id="partner-integrations" %} To streamline the development of real-time audio and video apps, you can use a third-party integration that supports the Gemini Live API over WebRTC or WebSockets. {% card-grid %} {% card href="https://docs.livekit.io/agents/models/realtime/plugins/gemini/" title="LiveKit" description="Use the Gemini Live API with LiveKit Agents." /%} {% card href="https://docs.pipecat.ai/guides/features/gemini-live" title="Pipecat by Daily" description="Create a real-time AI chatbot using Gemini Live and Pipecat." /%} {% card href="https://docs.fishjam.io/tutorials/gemini-live-integration" title="Fishjam by Software Mansion" description="Create live video and audio streaming applications with Fishjam." /%} {% card href="https://visionagents.ai/integrations/gemini" title="Vision Agents by Stream" description="Build real-time voice and video AI applications with Vision Agents." /%} {% card href="https://voximplant.com/products/gemini-client" title="Voximplant" description="Connect inbound and outbound calls to Live API with Voximplant." /%} {% card href="https://docs.agora.io/en/conversational-ai/models/mllm/gemini" title="Agora" description="Build real-time conversational AI applications with Agora." /%} {% card href="https://firebase.google.com/docs/ai-logic/live-api?api=dev" title="Firebase AI SDK" description="Get started with the Gemini Live API using Firebase AI Logic." /%} {% /card-grid %} [WebSocket]: https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API # Live translation with Gemini Live API Source: https://aistudio.google.com/docs/live-api/live-translate Description: Perform low-latency, real-time speech-to-speech translation with Live API. The Gemini Live API supports low-latency, real-time speech to speech translation between 70+ languages using the [`gemini-3.5-live-translate-preview`](/docs/models/gemini-3.5-live-translate-preview) model. By configuring the Live API with translation settings, you can stream audio in one language and receive translated audio output in another language, enabling seamless real-time voice-to-voice translation. {% button href="https://aistudio.google.com/live?model=gemini-3.5-live-translate-preview" variant="primary" icon="mic" %} Try Live Translate in Google AI Studio {% /button %} {% button href="https://github.com/google-gemini/gemini-live-api-examples" variant="primary" icon="code" %} Clone the example app from GitHub {% /button %} {% button href="/docs/coding-agents#gemini-live-api-dev" variant="primary" icon="terminal" %} Use coding agent skills {% /button %} ## Live Agent vs. Live Translation {% id="live-agent-vs-live-translation" %} While both use the Live API, the mental model for Live Translation is different from conversational real-time agent interactions. | Live Agent | Live Translation | | :--- | :--- | | **The model acts as an assistant.** It listens, reasons, and takes actions on your behalf. | **The model acts as an interpreter.** It behaves as a real-time translator pipeline. | | **Uses turn-based interactions.** Relies on pauses, intent detection, and handles interruptions. | **Uses continuous stream processing.** Translates as the speaker talks without waiting for turns. | | **Supports tools and agents.** Native support for function calling, Google Search, and instructions. | **Supports translation only.** Pure low-latency translation; no support for tools or instructions. | | **Fully multimodal.** Supports text, audio, video, and image inputs. | **Audio restricted.** Input is limited to audio to ensure strict real-time latency thresholds. | | **Granular configuration.** Uses generation, speech, tools, and system instructions. | **Simplified configuration.** Set `target_language_code` and toggles like `echo_target_language`. | ## Get started {% id="get-started" %} The following examples demonstrate how to initialize a client and connect to the Live API with a translation configuration. {% tabs %} {% tab label="Python" filename="live_translate.py" %} ```python import asyncio from google import genai from google.genai import types client = genai.Client() model = "gemini-3.5-live-translate-preview" config = types.LiveConnectConfig( response_modalities=["AUDIO"], input_audio_transcription=types.AudioTranscriptionConfig(), output_audio_transcription=types.AudioTranscriptionConfig(), translation_config=types.TranslationConfig( target_language_code="pl", echo_target_language=True ) ) async def main(): async with client.aio.live.connect(model=model, config=config) as session: print("Session started with translation") # Start receiving the translated audio stream async for response in session.receive(): if response.server_content: if response.server_content.input_transcription: print(f"Input transcript: {response.server_content.input_transcription.text}") if response.server_content.output_transcription: print(f"Output transcript: {response.server_content.output_transcription.text}") if response.server_content.model_turn: for part in response.server_content.model_turn.parts: if part.inline_data: audio_data = part.inline_data.data # Play or process the translated audio chunk print(f"Received audio chunk ({len(audio_data)} bytes)") if __name__ == "__main__": asyncio.run(main()) ``` {% /tab %} {% tab label="JavaScript" filename="live_translate.js" %} ```javascript import { GoogleGenAI, Modality } from '@google/genai'; const ai = new GoogleGenAI({}); const model = 'gemini-3.5-live-translate-preview'; const config = { responseModalities: [Modality.AUDIO], inputAudioTranscription: {}, outputAudioTranscription: {}, translationConfig: { targetLanguageCode: 'pl', echoTargetLanguage: true } }; async function main() { const session = await ai.live.connect({ model: model, config: config, callbacks: { onopen: () => console.debug('Opened'), onmessage: (message) => { const content = message.serverContent; if (content?.inputTranscription) { console.log('Input transcript:', content.inputTranscription.text); } if (content?.outputTranscription) { console.log('Output transcript:', content.outputTranscription.text); } if (content?.modelTurn?.parts) { for (const part of content.modelTurn.parts) { if (part.inlineData) { const audioData = part.inlineData.data; // Play or process the translated audio chunk (base64 encoded) console.debug(`Received audio chunk (${audioData.length} bytes)`); } } } }, onerror: (e) => console.debug('Error:', e.message), onclose: (e) => console.debug('Close:', e.reason), }, }); console.debug("Session started with translation"); } await main(); ``` {% /tab %} {% tab label="WebSockets" filename="live_translate.js" %} ```javascript const API_KEY = "YOUR_API_KEY"; const MODEL_NAME = "gemini-3.5-live-translate-preview"; const WS_URL = `wss://generativelanguage.googleapis.com/ws/google.ai.generativelanguage.v1beta.GenerativeService.BidiGenerateContent?key=${API_KEY}`; const websocket = new WebSocket(WS_URL); websocket.onopen = () => { console.log('WebSocket Connected'); const setupMessage = { setup: { model: `models/${MODEL_NAME}`, generationConfig: { responseModalities: ['AUDIO'], inputAudioTranscription: {}, outputAudioTranscription: {}, translationConfig: { targetLanguageCode: 'pl', echoTargetLanguage: true } } } }; websocket.send(JSON.stringify(setupMessage)); }; websocket.onmessage = (event) => { const response = JSON.parse(event.data); if (response.serverContent) { const content = response.serverContent; if (content.inputTranscription) { console.log('Input transcript:', content.inputTranscription.text, `(${content.inputTranscription.languageCode})`); } if (content.outputTranscription) { console.log('Output transcript:', content.outputTranscription.text, `(${content.outputTranscription.languageCode})`); } if (content.modelTurn?.parts) { for (const part of content.modelTurn.parts) { if (part.inlineData) { const audioData = part.inlineData.data; // Play or process the translated audio chunk (base64 encoded) console.debug(`Received audio chunk (${audioData.length} bytes)`); } } } } }; ``` {% /tab %} {% /tabs %} ## Sending audio {% id="sending-audio" %} To stream voice inputs for translation, you send raw, little-endian, 16-bit PCM audio. * **Input audio format**: Raw 16-bit PCM at 16kHz (mono, little-endian). * **Output audio format**: Raw 16-bit PCM at 24kHz (mono, little-endian). * **Chunk Size and Latency**: Send audio in chunks of 100ms. {% callout type="note" %} Only audio input is supported for translation. Text input is not supported. {% /callout %} The following examples show how to send audio chunks to the session. {% tabs %} {% tab label="Python" filename="live_translate.py" %} ```python # Assuming 'chunk' is your raw PCM audio bytes await session.send_realtime_input( audio=types.Blob( data=chunk, mime_type="audio/pcm;rate=16000" ) ) ``` {% /tab %} {% tab label="JavaScript" filename="live_translate.js" %} ```js // Assuming 'chunk' is a Buffer of raw PCM audio session.sendRealtimeInput({ audio: { data: chunk.toString('base64'), mimeType: 'audio/pcm;rate=16000' } }); ``` {% /tab %} {% tab label="WebSockets" filename="live_translate.js" %} ```javascript // Assuming 'chunk' is a Buffer of raw PCM audio function sendAudioChunk(chunk) { if (websocket.readyState === WebSocket.OPEN) { const audioMessage = { realtimeInput: { audio: { data: chunk.toString('base64'), mimeType: 'audio/pcm;rate=16000' } } }; websocket.send(JSON.stringify(audioMessage)); } } ``` {% /tab %} {% /tabs %} ## Configuration {% id="configuration" %} To enable translation, you must specify the `translationConfig` within the `generationConfig` during the session setup. ### Setup message configuration {% id="setup-message-configuration" %} The `generationConfig` supports the following fields to enable transcripts: * **`inputAudioTranscription`**: An object that, when present, enables the model to send text transcripts of the input audio. * **`outputAudioTranscription`**: An object that, when present, enables the model to send text transcripts of the output (translated) audio. The `translationConfig` supports the following fields: * **`targetLanguageCode`**: The [BCP-47 language code](/docs/live-api/live-translate#supported-languages) of the language you want the model to translate into (e.g., `"pl"` for Polish, `"es"` for Spanish). Defaults to `"en"`. * **`echoTargetLanguage`**: A boolean indicating how input audio that is already in the target language should be handled. If set to `true`, the model will echo (parrot) input audio that is already in the target language. If set to `false`, the model will stay silent when the input speech is already in the target language. Defaults to `false`. Here is an example of the setup message structure: ```json "setup": { "model": "models/gemini-3.5-live-translate-preview", "generationConfig": { "responseModalities": [ "AUDIO" ], "inputAudioTranscription": {}, "outputAudioTranscription": {}, "translationConfig": { "targetLanguageCode": "pl", "echoTargetLanguage": true } } } ``` ## Use ephemeral tokens in client-side applications {% id="ephemeral-tokens-for-client-side-applications" %} For client-to-server applications, you can use [ephemeral tokens](/docs/live-api/ephemeral-tokens) (currently in `v1beta`) to avoid exposing your API key. When using ephemeral tokens with Live Translation: 1. You must use the `v1beta` endpoint. 2. **Locking configuration:** By default, you should specify the `translationConfig` in the token creation constraints on your server. This ensures the translation configuration is locked and cannot be tampered with by the client. 3. **Unlocking configuration:** If you want to be able to set the `translationConfig` on the client-side (for example, to let a user choose their own target language), you must omit it from the token creation request and set `"lock_additional_fields": []` instead. This will unlock `translationConfig` to be set on the client-side. ### Create a constrained ephemeral token {% id="creating-a-constrained-ephemeral-token" %} The following examples demonstrate how to create an ephemeral token with translation constraints. {% tabs %} {% tab label="Python" filename="live_translate.py" %} ```python import datetime from google import genai now = datetime.datetime.now(tz=datetime.timezone.utc) client = genai.Client() token = client.auth_tokens.create( config = { 'uses': 1, 'expire_time': now + datetime.timedelta(minutes=30), 'live_connect_constraints': { 'model': 'gemini-3.5-live-translate-preview', 'config': { 'translation_config': { 'target_language_code': 'pl', 'echo_target_language': True } } }, } ) ``` {% /tab %} {% tab label="JavaScript" filename="live_translate.js" %} ```javascript import { GoogleGenAI } from "@google/genai"; const client = new GoogleGenAI({}); const expireTime = new Date(Date.now() + 30 * 60 * 1000).toISOString(); const token = await client.authTokens.create({ config: { uses: 1, expireTime: expireTime, liveConnectConstraints: { model: 'gemini-3.5-live-translate-preview', config: { responseModalities: ['AUDIO'], inputAudioTranscription: {}, outputAudioTranscription: {}, translationConfig: { targetLanguageCode: 'pl', echoTargetLanguage: true } } }, }, }); ``` {% /tab %} {% tab label="REST" filename="live_translate.sh" %} ```bash curl -X POST "https://generativelanguage.googleapis.com/v1beta/auth_tokens" \ -H "x-goog-api-key: ${GEMINI_API_KEY}" \ -H "Content-Type: application/json" \ -d '{ "uses": 1, "expireTime": "YYYY-MM-DDTHH:MM:SSZ", "liveConnectConstraints": { "model": "models/gemini-3.5-live-translate-preview", "config": { "responseModalities": ["AUDIO"], "inputAudioTranscription": {}, "outputAudioTranscription": {}, "translationConfig": { "targetLanguageCode": "pl", "echoTargetLanguage": true } } } }' ``` {% /tab %} {% /tabs %} ## Limitations {% id="limitations" %} * **Input Modalities**: Only audio input is supported for translation. Text input is not supported. * **Voice Replication**: Voice replication can be inconsistent. Voices might shift after long pauses, assign the wrong gender based on how the speech starts, or get stuck on one voice during rapid multi-speaker conversations. * **Language Detection**: Language detection struggles with heavy accents, similar languages (e.g., Spanish vs. Portuguese), or rapid language switches. **Note:** This should only impact the input transcript. Language codes and the final translation should still be accurate. * **Background Audio**: The model is designed to filter out noise and music to produce clean speech, but not all background audio may be ignored. * **Echo Target Language**: When `echoTargetLanguage: true`, background noise or music may introduce artifacts in the translated audio when input audio is already in the target language. ## Supported languages {% id="supported-languages" %} The following languages are supported for Live Translation. | Language | BCP-47 Code | Language | BCP-47 Code | | :---- | :---- | :---- | :---- | | Afrikaans | af | Kazakh | kk | | Akan | ak | Khmer | km | | Albanian | sq | Kinyarwanda | rw | | Amharic | am | Korean | ko | | Arabic | ar | Lao | lo | | Armenian | hy | Latvian | lv | | Azerbaijani | az | Lithuanian | lt | | Basque | eu | Macedonian | mk | | Belarusian | be | Malay | ms | | Bengali | bn | Malayalam | ml | | Bulgarian | bg | Marathi | mr | | Burmese (Myanmar) | my | Mongolian | mn | | Catalan | ca | Nepali | ne | | Chinese (Simplified) | zh-Hans | Norwegian | no, nb | | Chinese (Traditional) | zh-Hant | Persian | fa | | Croatian | hr | Polish | pl | | Czech | cs | Portuguese (Brazil) | pt-BR | | Danish | da | Portuguese (Portugal) | pt-PT | | Dutch | nl | Punjabi | pa | | English | en | Romanian | ro | | Estonian | et | Russian | ru | | Filipino | fil | Serbian | sr | | Finnish | fi | Sindhi | sd | | French | fr | Sinhala | si | | Galician | gl | Slovak | sk | | Georgian | ka | Slovenian | sl | | German | de | Spanish | es | | Greek | el | Sundanese | su | | Gujarati | gu | Swahili | sw | | Hausa | ha | Swedish | sv | | Hebrew | he | Tamil | ta | | Hindi | hi | Telugu | te | | Hungarian | hu | Thai | th | | Icelandic | is | Turkish | tr | | Indonesian | id | Ukrainian | uk | | Italian | it | Urdu | ur | | Japanese | ja | Uzbek | uz | | Javanese | jv | Vietnamese | vi | | Kannada | kn | Zulu | zu | ## What's next {% id="whats-next" %} * Read the full Live API [Capabilities](/docs/live-api/capabilities) guide. * Read the [Get started with the SDK](/docs/live-api/get-started-sdk) guide. * Read the [Get started with WebSockets](/docs/live-api/get-started-websocket) guide. * Read the [Ephemeral tokens](/docs/live-api/ephemeral-tokens) guide for secure authentication in client-to-server applications. * Clone the [Live API examples](https://github.com/google-gemini/gemini-live-api-examples) from GitHub. # Embeddings Source: https://aistudio.google.com/docs/embeddings Description: Generate vector embeddings for semantic search and classification using Gemini. The Gemini API offers embedding models to generate embeddings for text, images, video, and other content. These resulting embeddings can then be used for tasks such as semantic search, classification, and clustering, providing more accurate, context-aware results than keyword-based approaches. The latest model, `gemini-embedding-2`, is the first multimodal embedding model in the Gemini API. It maps text, images, video, audio, and documents into a unified embedding space, enabling cross-modal search, classification, and clustering across over 100 languages. See the [multimodal embeddings section](/docs/embeddings#multimodal) to learn more. For text-only use cases, `gemini-embedding-001` remains available. Building Retrieval Augmented Generation (RAG) systems is a common use case for AI products. Embeddings play a key role in significantly enhancing model outputs with improved factual accuracy, coherence, and contextual richness. If you prefer to use a managed RAG solution, we built the [File Search](/docs/file-search) tool which makes doing RAG easier to manage and more cost effective. ## Generating embeddings {% id="generate-embeddings" %} Use the `embedContent` method to generate text embeddings: {% tabs %} {% tab label="Python" %} ```python from google import genai client = genai.Client() result = client.models.embed_content( model="gemini-embedding-2", contents="What is the meaning of life?" ) print(result.embeddings) ``` {% /tab %} {% tab label="JavaScript" %} ```js import { GoogleGenAI } from "@google/genai"; async function main() { const ai = new GoogleGenAI({}); const response = await ai.models.embedContent({ model: 'gemini-embedding-2', contents: 'What is the meaning of life?', }); console.log(response.embeddings); } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.types.EmbedContentResponse; Client client = new Client(); EmbedContentResponse response = client.models.embedContent("gemini-embedding-2", "What is the meaning of life?", null); System.out.println(response.embeddings().orElse(null)); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "encoding/json" "fmt" "log" "google.golang.org/genai" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } contents := []*genai.Content{ genai.NewContentFromText("What is the meaning of life?", genai.RoleUser), } result, err := client.Models.EmbedContent(ctx, "gemini-embedding-2", contents, nil, ) if err != nil { log.Fatal(err) } embeddings, err := json.MarshalIndent(result.Embeddings, "", " ") if err != nil { log.Fatal(err) } fmt.Println(string(embeddings)) } ``` {% /tab %} {% tab label="REST" %} ```shell curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-embedding-2:embedContent" \ -H "Content-Type: application/json" \ -H "x-goog-api-key: ${GEMINI_API_KEY}" \ -d '{ "model": "models/gemini-embedding-2", "content": { "parts": [{ "text": "What is the meaning of life?" }] } }' ``` {% /tab %} {% /tabs %} {% callout type="note" %} While `gemini-embedding-001` lets you generate individual embeddings for a list of strings, Gemini Embedding 2 produces a single aggregated embedding for multiple inputs. You can find more information in [Embedding aggregation](/docs/embeddings#embedding-aggregation), or you can use the [Batch API](/docs/batch-api#batch-embedding) if you want to generate multiple embeddings at once. {% /callout %} ## Specify task type to improve performance {% id="task-types" %} You can use embeddings for a wide range of tasks from classification to document search. Specifying the right task type helps optimize the embeddings for the intended relationships, maximizing accuracy and efficiency. ### Task types with Embeddings 2 {% id="task-types-embeddings-2" %} For text-only tasks with `gemini-embedding-2`, we strongly recommend you add the task instruction in your prompt. This can be done by formatting the query and the document with the correct task prefix. When generating a [single embedding based on multimodal input](/docs/embeddings#embedding-aggregation), we generally don't recommend prefixing the text portion of the input with a task instruction. In some cases it improves performance, but in others it reduces performance. The following tables show examples of how to format queries and documents for symmetric and asymmetric use cases using the `gemini-embedding-2` model. **Retrieval use cases (Asymmetric format)** In asymmetric use cases, add the task prefix to the query and apply the document structure for the content you want to embed and retrieve. {% table %} * Use case * Query structure * Document structure --- * Search query * `task: search result | query: {content}` * `title: {title} | text: {content}` If there is no title, use `title: none`. --- * Question answering * `task: question answering | query: {content}` * `title: {title} | text: {content}` --- * Fact checking * `task: fact checking | query: {content}` * `title: {title} | text: {content}` --- * Code retrieval * `task: code retrieval | query: {content}` * `title: {title} | text: {content}` {% /table %} **Example usage** {% tabs %} {% tab label="Python" %} ```python def prepare_query(query): return f"task: search result | query: {query}" def prepare_document(content, title=None): if title is None: title = "none" return f"title: {title} | text: {content}" ``` {% /tab %} {% tab label="Java" %} ```java // Generate embedding for a task's query. Use your correct task here: String query = "What is the capital of France?"; String formattedQuery = "task: search result | query: " + query; // Generate embedding for document of an asymmetric retrieval task: String title = "France"; String content = "Paris is the capital and most populous city of France."; String formattedDocument = "title: " + (title != null ? title : "none") + " | text: " + content; ``` {% /tab %} {% /tabs %} **Single-input use cases (Symmetric format)** In symmetric use cases, for the same task, use the same formatting for the query and the document. {% table %} * Use case * Input structure --- * Classification * `task: classification | query: {content}` --- * Clustering * `task: clustering | query: {content}` --- * Semantic similarity * `task: sentence similarity | query: {content}` Do not use this for search or retrieval. It is intended for semantic textual similarity. {% /table %} **Example usage** {% tabs %} {% tab label="Python" %} ```python def prepare_query_and_document(content): return f'task: classification | query: {content}' ``` {% /tab %} {% tab label="Java" %} ```java // Generate embedding for query & document of your task. String content = "This movie was fantastic!"; String formattedContent = "task: classification | query: " + content; ``` {% /tab %} {% /tabs %} It is important that the task is used consistently. E.g., if documents are embedded with `f'task: classification | query: {content}'`, the query should also be embedded following this task format. ### Task types with Embeddings 1 {% id="task-types-embeddings-1" %} For `gemini-embedding-001`, you can specify the `task_type` in the `embedContent` method. For a complete list of supported task types, see the [Supported task types](/docs/embeddings#supported-task-types) table. {% callout type="note" %} You cannot use the `task_type` field for the `gemini-embedding-2` model. Instead, include the task as an instruction in your prompt, as detailed in the [above section](/docs/embeddings#task-types-embeddings-2). {% /callout %} The following example shows how you can use `SEMANTIC_SIMILARITY` to check how similar in meaning strings of texts are. {% tabs %} {% tab label="Python" %} ```python from google import genai from google.genai import types import pandas as pd from sklearn.metrics.pairwise import cosine_similarity client = genai.Client() texts = [ "What is the meaning of life?", "What is the purpose of existence?", "How do I bake a cake?", ] result = client.models.embed_content( model="gemini-embedding-001", contents=texts, config=types.EmbedContentConfig(task_type="SEMANTIC_SIMILARITY") ) df = pd.DataFrame( cosine_similarity([e.values for e in result.embeddings]), index=texts, columns=texts, ) print(df) ``` {% /tab %} {% tab label="JavaScript" %} ```js import { GoogleGenAI } from "@google/genai"; // npm i compute-cosine-similarity import * as cosineSimilarity from "compute-cosine-similarity"; async function main() { const ai = new GoogleGenAI({}); const texts = [ "What is the meaning of life?", "What is the purpose of existence?", "How do I bake a cake?", ]; const response = await ai.models.embedContent({ model: 'gemini-embedding-001', contents: texts, config: { taskType: 'SEMANTIC_SIMILARITY' }, }); const embeddings = response.embeddings?.map(e => e.values || []) || []; for (let i = 0; i < texts.length; i++) { for (let j = i + 1; j < texts.length; j++) { const text1 = texts[i]; const text2 = texts[j]; const similarity = cosineSimilarity(embeddings[i], embeddings[j]); console.log(`Similarity between '${text1}' and '${text2}': ${similarity.toFixed(4)}`); } } } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import java.util.Arrays; import com.google.genai.Client; import com.google.genai.types.ContentEmbedding; import com.google.genai.types.EmbedContentConfig; import com.google.genai.types.EmbedContentResponse; import java.util.List; Client client = new Client(); List texts = Arrays.asList( "What is the meaning of life?", "What is the purpose of existence?", "How do I bake a cake?"); EmbedContentConfig config = EmbedContentConfig.builder().taskType("SEMANTIC_SIMILARITY").build(); EmbedContentResponse response = client.models.embedContent("gemini-embedding-001", texts, config); List embeddings = response.embeddings().get(); for (int i = 0; i < texts.size(); i++) { for (int j = i + 1; j < texts.size(); j++) { List v1 = embeddings.get(i).values().get(); List v2 = embeddings.get(j).values().get(); double dotProduct = 0.0; double normA = 0.0; double normB = 0.0; for (int k = 0; k < v1.size(); k++) { dotProduct += v1.get(k) * v2.get(k); normA += v1.get(k) * v1.get(k); normB += v2.get(k) * v2.get(k); } double similarity = dotProduct / (Math.sqrt(normA) * Math.sqrt(normB)); System.out.printf( "Similarity between '%s' and '%s': %.4f%n", texts.get(i), texts.get(j), similarity); } } ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "math" "google.golang.org/genai" ) // cosineSimilarity calculates the similarity between two vectors. func cosineSimilarity(a, b []float32) (float64, error) { if len(a) != len(b) { return 0, fmt.Errorf("vectors must have the same length") } var dotProduct, aMagnitude, bMagnitude float64 for i := 0; i < len(a); i++ { dotProduct += float64(a[i] * b[i]) aMagnitude += float64(a[i] * a[i]) bMagnitude += float64(b[i] * b[i]) } if aMagnitude == 0 || bMagnitude == 0 { return 0, nil } return dotProduct / (math.Sqrt(aMagnitude) * math.Sqrt(bMagnitude)), nil } func main() { ctx := context.Background() client, _ := genai.NewClient(ctx, nil) defer client.Close() texts := []string{ "What is the meaning of life?", "What is the purpose of existence?", "How do I bake a cake?", } var contents []*genai.Content for _, text := range texts { contents = append(contents, genai.NewContentFromText(text, genai.RoleUser)) } result, _ := client.Models.EmbedContent(ctx, "gemini-embedding-001", contents, &genai.EmbedContentRequest{TaskType: genai.TaskTypeSemanticSimilarity}, ) embeddings := result.Embeddings for i := 0; i < len(texts); i++ { for j := i + 1; j < len(texts); j++ { similarity, _ := cosineSimilarity(embeddings[i].Values, embeddings[j].Values) fmt.Printf("Similarity between '%s' and '%s': %.4f\n", texts[i], texts[j], similarity) } } } ``` {% /tab %} {% tab label="REST" %} ```shell curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-embedding-001:embedContent" \ -H "Content-Type: application/json" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -d '{ "taskType": "SEMANTIC_SIMILARITY", "content": { "parts": [ { "text": "What is the meaning of life?" }, { "text": "How much wood would a woodchuck chuck?" }, { "text": "How does the brain work?" } ] } }' ``` {% /tab %} {% /tabs %} The code snippets will show how similar the different chunks of text are to one another when run. {% callout type="note" %} Cosine similarity is a good distance metric because it focuses on direction rather than magnitude, which more accurately reflects conceptual closeness. Values range from -1 (opposite) to 1 (greatest similarity). {% /callout %} #### Supported task types {% id="supported-task-types" %} Supported task types for `gemini-embedding-001`: {% table %} * **SEMANTIC_SIMILARITY** * Embeddings optimized to assess text similarity. * Recommendation systems, duplicate detection --- * **CLASSIFICATION** * Embeddings optimized to classify texts according to preset labels. * Sentiment analysis, spam detection --- * **CLUSTERING** * Embeddings optimized to cluster texts based on their similarities. * Document organization, market research, anomaly detection --- * **RETRIEVAL_DOCUMENT** * Embeddings optimized for document search. * Indexing articles, books, or web pages for search. --- * **RETRIEVAL_QUERY** * Embeddings optimized for general search queries. Use `RETRIEVAL_QUERY` for queries; `RETRIEVAL_DOCUMENT` for documents to be retrieved. * Custom search --- * **CODE_RETRIEVAL_QUERY** * Embeddings optimized for retrieval of code blocks based on natural language queries. Use `CODE_RETRIEVAL_QUERY` for queries; `RETRIEVAL_DOCUMENT` for code blocks to be retrieved. * Code suggestions and search --- * **QUESTION_ANSWERING** * Embeddings for questions in a question-answering system, optimized for finding documents that answer the question. Use `QUESTION_ANSWERING` for questions; `RETRIEVAL_DOCUMENT` for documents to be retrieved. * Chatbox --- * **FACT_VERIFICATION** * Embeddings for statements that need to be verified, optimized for retrieving documents that contain evidence supporting or refuting the statement. Use `FACT_VERIFICATION` for the target text; `RETRIEVAL_DOCUMENT` for documents to be retrieved. * Automated fact-checking systems {% /table %} ## Controlling embedding size {% id="control-embedding-size" %} Both `gemini-embedding-001` and `gemini-embedding-2` are trained using the Matryoshka Representation Learning (MRL) technique which teaches a model to learn high-dimensional embeddings that have initial segments (or prefixes) which are also useful, simpler versions of the same data. Use the `output_dimensionality` parameter to control the size of the output embedding vector. Selecting a smaller output dimensionality can save storage space and increase computational efficiency for downstream applications, while sacrificing little in terms of quality. By default, both models output a 3072-dimensional embedding, but you can truncate it to a smaller size without losing quality to save storage space. We recommend using 768, 1536, or 3072 output dimensions. {% tabs %} {% tab label="Python" %} ```python from google import genai from google.genai import types client = genai.Client() result = client.models.embed_content( model="gemini-embedding-2", contents="What is the meaning of life?", config=types.EmbedContentConfig(output_dimensionality=768) ) [embedding_obj] = result.embeddings embedding_length = len(embedding_obj.values) print(f"Length of embedding: {embedding_length}") ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; async function main() { const ai = new GoogleGenAI({}); const response = await ai.models.embedContent({ model: 'gemini-embedding-2', contents: 'What is the meaning of life?', config: { outputDimensionality: 768 }, }); const embeddingLength = response.embeddings?.[0]?.values?.length || 0; console.log(`Length of embedding: ${embeddingLength}`); } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.types.ContentEmbedding; import com.google.genai.types.EmbedContentConfig; import com.google.genai.types.EmbedContentResponse; Client client = new Client(); EmbedContentConfig config = EmbedContentConfig.builder().outputDimensionality(768).build(); EmbedContentResponse response = client.models.embedContent("gemini-embedding-2", "What is the meaning of life?", config); ContentEmbedding embeddingObj = response.embeddings().get().get(0); int embeddingLength = embeddingObj.values().get().size(); System.out.println("Length of embedding: " + embeddingLength); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" ) func main() { ctx := context.Background() // The client uses Application Default Credentials. // Authenticate with 'gcloud auth application-default login'. client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } defer client.Close() contents := []*genai.Content{ genai.NewContentFromText("What is the meaning of life?", genai.RoleUser), } result, err := client.Models.EmbedContent(ctx, "gemini-embedding-2", contents, &genai.EmbedContentRequest{OutputDimensionality: 768}, ) if err != nil { log.Fatal(err) } embedding := result.Embeddings[0] embeddingLength := len(embedding.Values) fmt.Printf("Length of embedding: %d\n", embeddingLength) } ``` {% /tab %} {% tab label="REST" %} ```shell curl -X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-embedding-2:embedContent" \ -H 'Content-Type: application/json' \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -d '{ "content": {"parts":[{ "text": "What is the meaning of life?"}]}, "output_dimensionality": 768 }' ``` {% /tab %} {% /tabs %} Example output from the code snippet: ```none Length of embedding: 768 ``` ## Ensuring quality for smaller dimensions {% id="quality-for-smaller-dimensions" %} {% callout type="note" %} `gemini-embedding-2` introduces automatic renormalization for non-default dimensions. {% /callout %} While the default 3072-dimension embeddings are always normalized, Gemini Embedding 2 also auto-normalizes truncated dimensions (e.g., 768, 1536). This ensures semantic similarity is calculated via vector direction rather than magnitude, providing more accurate results out of the box. **Older Models**: If you are using `gemini-embedding-001`, you must manually normalize non-3072 dimensions as follows: {% tabs %} {% tab label="Python" %} ```python import numpy as np from numpy.linalg import norm embedding_values_np = np.array(embedding_obj.values) normed_embedding = embedding_values_np / np.linalg.norm(embedding_values_np) print(f"Normed embedding length: {len(normed_embedding)}") print(f"Norm of normed embedding: {np.linalg.norm(normed_embedding):.6f}") # Should be very close to 1 ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.types.ContentEmbedding; import com.google.genai.types.EmbedContentConfig; import com.google.genai.types.EmbedContentResponse; import java.util.ArrayList; import java.util.List; Client client = new Client(); EmbedContentConfig config = EmbedContentConfig.builder().outputDimensionality(768).build(); EmbedContentResponse response = client.models.embedContent("gemini-embedding-2", "What is the meaning of life?", config); ContentEmbedding embeddingObj = response.embeddings().get().get(0); List values = embeddingObj.values().get(); double norm = 0.0; for (float v : values) { norm += v * v; } norm = Math.sqrt(norm); List normedEmbedding = new ArrayList<>(); double newNorm = 0.0; for (float v : values) { double normedVal = v / norm; normedEmbedding.add(normedVal); newNorm += normedVal * normedVal; } newNorm = Math.sqrt(newNorm); System.out.println("Normed embedding length: " + normedEmbedding.size()); System.out.printf("Norm of normed embedding: %.6f%n", newNorm); // Should be very close to 1 ``` {% /tab %} {% /tabs %} Example output from this code snippet: ```none Normed embedding length: 768 Norm of normed embedding: 1.000000 ``` The following table shows the MTEB scores, a commonly used benchmark for embeddings, for different dimensions. Notably, the result shows that performance is not strictly tied to the size of the embedding dimension, with lower dimensions achieving scores comparable to their higher dimension counterparts. {% table %} * 2048 * 68.16 --- * 1536 * 68.17 --- * 768 * 67.99 --- * 512 * 67.55 --- * 256 * 66.19 --- * 128 * 63.31 {% /table %} ## Multimodal embeddings {% id="multimodal" %} The `gemini-embedding-2` model supports multimodal input, allowing you to embed images, video, audio, and documents content alongside text. All modalities are mapped into the same embedding space, enabling cross-modal search and comparison. ### Supported modalities and limits {% id="supported-modalities" %} The overall maximum input tokens limit is 8192 tokens. {% table %} * **Text** * Supports up to 8,192 tokens. --- * **Image** * Maximum of 6 images per request. Supported formats: PNG, JPEG. --- * **Audio** * Maximum duration of 180 seconds. Supported formats: MP3, WAV. --- * **Video** * Maximum duration of 120 seconds. Supported formats: MP4, MOV. Supported codecs: H264, H265, AV1, VP9. The system processes a maximum of 32 frames per video: short videos (≤32s) are sampled at 1 fps, while longer videos are uniformly sampled to 32 frames. Audio tracks are not processed in video files. --- * **Documents (PDF)** * Maximum of 1 file per request, up to 6 pages. {% /table %} ### Embedding images {% id="embed-images" %} The following example shows how to embed an image using `gemini-embedding-2`. Images can be provided as inline data or as uploaded files through the [Files API](/docs/files). {% tabs %} {% tab label="Python" %} ```python from google import genai from google.genai import types with open('example.png', 'rb') as f: image_bytes = f.read() client = genai.Client() result = client.models.embed_content( model='gemini-embedding-2', contents=[ types.Part.from_bytes( data=image_bytes, mime_type='image/png', ), ] ) print(result.embeddings) ``` {% /tab %} {% tab label="JavaScript" %} ```js import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const imgBase64 = fs.readFileSync("example.png", { encoding: "base64" }); const response = await ai.models.embedContent({ model: 'gemini-embedding-2', contents: [{ inlineData: { mimeType: 'image/png', data: imgBase64, }, }], }); console.log(response.embeddings); } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.types.Content; import com.google.genai.types.EmbedContentResponse; import com.google.genai.types.Part; import java.nio.file.Files; import java.nio.file.Paths; Client client = new Client(); byte[] imageBytes = Files.readAllBytes(Paths.get("example.png")); Content content = Content.fromParts(Part.fromBytes(imageBytes, "image/png")); EmbedContentResponse response = client.models.embedContent("gemini-embedding-2", content, null); System.out.println(response.embeddings().orElse(null)); ``` {% /tab %} {% tab label="REST" %} ```sh IMG_PATH="/path/to/your/image.png" IMG_BASE64=$(base64 -w0 "${IMG_PATH}") curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-embedding-2:embedContent" \ -H "Content-Type: application/json" \ -H "x-goog-api-key: ${GEMINI_API_KEY}" \ -d '{ "content": { "parts": [{ "inline_data": { "mime_type": "image/png", "data": "'"${IMG_BASE64}"'" } }] } }' ``` {% /tab %} {% /tabs %} ### Embedding aggregation {% id="embedding-aggregation" %} When working with multimodal content, how you structure your input affects the embedding output: * **Multiple parts (aggregated):** Adding multiple inputs directly to the `contents` parameter produces one aggregated embedding for all inputs. * **Multiple `Content` objects (separate):** Wrapping each input in a `Content` object and passing them in the `contents` parameter returns separate embeddings for each entry. * **Post-level representation:** For complex objects like social media posts with multiple media items, we recommend aggregating separate embeddings (for example, by averaging) to create a coherent post-level representation. The following example shows how to create one aggregated embedding for text and image input. Simply add multiple inputs to the `contents` parameter: {% tabs %} {% tab label="Python" %} ```python from google import genai from google.genai import types client = genai.Client() with open('dog.png', 'rb') as f: image_bytes = f.read() result = client.models.embed_content( model='gemini-embedding-2', contents=[ "An image of a dog", types.Part.from_bytes( data=image_bytes, mime_type='image/png', ), ] ) for embedding in result.embeddings: print(embedding.values) ``` {% /tab %} {% tab label="JavaScript" %} ```js import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const imgBase64 = fs.readFileSync("dog.png", { encoding: "base64" }); const response = await ai.models.embedContent({ model: 'gemini-embedding-2', contents: [ 'An image of a dog', { inlineData: { mimeType: 'image/png', data: imgBase64, }, }, ], }); // This produces one embedding for (const embedding of response.embeddings || []) { console.log(embedding.values); } } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.types.Content; import com.google.genai.types.ContentEmbedding; import com.google.genai.types.EmbedContentResponse; import com.google.genai.types.Part; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Collections; Client client = new Client(); byte[] imageBytes = Files.readAllBytes(Paths.get("dog.png")); Content content = Content.fromParts( Part.fromText("An image of a dog"), Part.fromBytes(imageBytes, "image/png")); EmbedContentResponse response = client.models.embedContent("gemini-embedding-2", content, null); // This produces one embedding for (ContentEmbedding embedding : response.embeddings().orElse(Collections.emptyList())) { System.out.println(embedding.values().orElse(Collections.emptyList())); } ``` {% /tab %} {% tab label="REST" %} ```sh IMG_PATH="/path/to/your/dog.png" IMG_BASE64=$(base64 -w0 "${IMG_PATH}") curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-embedding-2:embedContent" \ -H "Content-Type: application/json" \ -H "x-goog-api-key: ${GEMINI_API_KEY}" \ -d '{ "content": { "parts": [ {"text": "An image of a dog"}, { "inline_data": { "mime_type": "image/png", "data": "'"${IMG_BASE64}"'" } } ] } }' ``` {% /tab %} {% /tabs %} {% callout type="note" %} The text portion of the multimodal input shouldn't include task type information. {% /callout %} On the other hand, if you use `Content` objects inside the `contents` parameter, it returns separate embeddings. This example creates multiple embeddings in one embedding call: {% tabs %} {% tab label="Python" %} ```python from google import genai from google.genai import types client = genai.Client() with open('dog.png', 'rb') as f: image_bytes = f.read() result = client.models.embed_content( model="gemini-embedding-2", contents=[ types.Content(parts=[types.Part.from_text(text="task: classification | query: An image of a dog")]), types.Content( parts=[ types.Part.from_bytes( data=image_bytes, mime_type="image/png", ), ] ), ], ) for embedding in result.embeddings: print(embedding.values) ``` {% /tab %} {% tab label="JavaScript" %} ```js import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const imgBase64 = fs.readFileSync("dog.png", { encoding: "base64" }); const response = await ai.models.embedContent({ model: 'gemini-embedding-2', contents: [ { parts: [{ text: 'task: classification | query: An image of a dog' }] }, { parts: [{ inlineData: { mimeType: 'image/png', data: imgBase64, }, }], }, ], }); // This produces two embeddings for (const embedding of response.embeddings || []) { console.log(embedding.values); } } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import java.util.Arrays; import com.google.genai.Client; import com.google.genai.types.Content; import com.google.genai.types.ContentEmbedding; import com.google.genai.types.EmbedContentResponse; import com.google.genai.types.Part; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Collections; import java.util.List; Client client = new Client(); byte[] imageBytes = Files.readAllBytes(Paths.get("dog.png")); List contents = Arrays.asList( Content.fromParts(Part.fromText("task: classification | query: An image of a dog")), Content.fromParts(Part.fromBytes(imageBytes, "image/png"))); // Embed each Content object separately to produce separate embeddings for (Content content : contents) { EmbedContentResponse response = client.models.embedContent("gemini-embedding-2", content, null); for (ContentEmbedding embedding : response.embeddings().orElse(Collections.emptyList())) { System.out.println(embedding.values().orElse(Collections.emptyList())); } } ``` {% /tab %} {% tab label="REST" %} ```sh IMG_PATH="/path/to/your/dog.png" IMG_BASE64=$(base64 -w0 "${IMG_PATH}") curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-embedding-2:batchEmbedContents" \ -H "Content-Type: application/json" \ -H "x-goog-api-key: ${GEMINI_API_KEY}" \ -d '{ "requests": [ { "model": "models/gemini-embedding-2", "content": {"parts": [{"text": "task: classification | query: An image of a dog"}]} }, { "model": "models/gemini-embedding-2", "content": {"parts": [{"inline_data": {"mime_type": "image/png", "data": "'"${IMG_BASE64}"'"}}]} } ] }' ``` {% /tab %} {% /tabs %} ### Embedding audio {% id="embed-audio" %} The following example shows how to embed an audio file using `gemini-embedding-2`. Audio files can be provided as inline data or as uploaded files through the [Files API](/docs/files). {% tabs %} {% tab label="Python" %} ```python from google import genai from google.genai import types with open('example.mp3', 'rb') as f: audio_bytes = f.read() client = genai.Client() result = client.models.embed_content( model='gemini-embedding-2', contents=[ types.Part.from_bytes( data=audio_bytes, mime_type='audio/mpeg', ), ] ) print(result.embeddings) ``` {% /tab %} {% tab label="JavaScript" %} ```js import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const audioBase64 = fs.readFileSync("example.mp3", { encoding: "base64" }); const response = await ai.models.embedContent({ model: 'gemini-embedding-2', contents: [{ inlineData: { mimeType: 'audio/mpeg', data: audioBase64, }, }], }); console.log(response.embeddings); } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.types.Content; import com.google.genai.types.EmbedContentResponse; import com.google.genai.types.Part; import java.nio.file.Files; import java.nio.file.Paths; Client client = new Client(); byte[] audioBytes = Files.readAllBytes(Paths.get("example.mp3")); Content content = Content.fromParts(Part.fromBytes(audioBytes, "audio/mpeg")); EmbedContentResponse response = client.models.embedContent("gemini-embedding-2", content, null); System.out.println(response.embeddings().orElse(null)); ``` {% /tab %} {% tab label="REST" %} ```sh AUDIO_PATH="/path/to/your/example.mp3" AUDIO_BASE64=$(base64 -w0 "${AUDIO_PATH}") curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-embedding-2:embedContent" \ -H "Content-Type: application/json" \ -H "x-goog-api-key: ${GEMINI_API_KEY}" \ -d '{ "content": { "parts": [{ "inline_data": { "mime_type": "audio/mpeg", "data": "'"${AUDIO_BASE64}"'" } }] } }' ``` {% /tab %} {% /tabs %} ### Embedding video {% id="embed-video" %} The following example shows how to embed a video using `gemini-embedding-2`. Videos can be provided as inline data or as uploaded files through the [Files API](/docs/files). {% tabs %} {% tab label="Python" %} ```python from google import genai from google.genai import types client = genai.Client() with open('example.mp4', 'rb') as f: video_bytes = f.read() result = client.models.embed_content( model='gemini-embedding-2', contents=[ types.Part.from_bytes( data=video_bytes, mime_type='video/mp4', ), ] ) print(result.embeddings[0].values) ``` {% /tab %} {% tab label="JavaScript" %} ```js import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const videoBase64 = fs.readFileSync("example.mp4", { encoding: "base64" }); const response = await ai.models.embedContent({ model: 'gemini-embedding-2', contents: [{ inlineData: { mimeType: 'video/mp4', data: videoBase64, }, }], }); console.log(response.embeddings); } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.types.Content; import com.google.genai.types.EmbedContentResponse; import com.google.genai.types.Part; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Collections; Client client = new Client(); byte[] videoBytes = Files.readAllBytes(Paths.get("example.mp4")); Content content = Content.fromParts(Part.fromBytes(videoBytes, "video/mp4")); EmbedContentResponse response = client.models.embedContent("gemini-embedding-2", content, null); System.out.println( response.embeddings().get().get(0).values().orElse(Collections.emptyList())); ``` {% /tab %} {% tab label="REST" %} ```sh VIDEO_PATH="/path/to/your/video.mp4" VIDEO_BASE64=$(base64 -w0 "${VIDEO_PATH}") curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-embedding-2:embedContent" \ -H "Content-Type: application/json" \ -H "x-goog-api-key: ${GEMINI_API_KEY}" \ -d '{ "content": { "parts": [{ "inline_data": { "mime_type": "video/mp4", "data": "'"${VIDEO_BASE64}"'" } }] } }' ``` {% /tab %} {% /tabs %} If you need to embed videos >120 seconds, you can chunk the video into overlapping segments and embed those chunks individually. ### Embedding documents {% id="embed-documents" %} Documents in PDF format can be embedded directly. The model processes the visual and text content of each page. PDFs can be provided as inline data or as uploaded files through the [Files API](/docs/files). #### How the model processes PDFs {% id="pdf-processing" %} When you embed a PDF, the model processes the document using both visual and text features: * **Visual representation:** The model renders each page as an image, which consumes **258 tokens** per page. * **Text extraction:** The model extracts text from the document. For **native PDFs** (which contain digital text), the model extracts the text directly. For **scanned PDFs** (which contain images of text), the model automatically runs optical character recognition (OCR) to extract the text. To calculate the total token count for a PDF, add the visual tokens (258 per page) to the text tokens. Your inputs must fit within the model's **8,192 token limit** (shared across all modalities). The system silently truncates inputs that exceed this limit. {% callout type="note" %} The Gemini Developer API always enables OCR for PDFs and does not support disabling it (the `document_ocr` parameter is only available in Vertex AI). {% /callout %} #### PDF limits {% id="pdf-limits" %} * **Files per request:** You can submit a maximum of 1 PDF file. * **Page limit:** You can submit a maximum of 6 pages per file. For the best quality, we strongly recommend using 1 page per PDF. The following example shows how to embed a PDF using `gemini-embedding-2`: {% tabs %} {% tab label="Python" %} ```python from google import genai from google.genai import types with open('example.pdf', 'rb') as f: pdf_bytes = f.read() client = genai.Client() result = client.models.embed_content( model='gemini-embedding-2', contents=[ types.Part.from_bytes( data=pdf_bytes, mime_type='application/pdf', ), ] ) print(result.embeddings) ``` {% /tab %} {% tab label="JavaScript" %} ```js import { GoogleGenAI } from "@google/genai"; import * as fs from "node:fs"; async function main() { const ai = new GoogleGenAI({}); const pdfBase64 = fs.readFileSync("example.pdf", { encoding: "base64" }); const response = await ai.models.embedContent({ model: 'gemini-embedding-2', contents: [{ inlineData: { mimeType: 'application/pdf', data: pdfBase64, }, }], }); console.log(response.embeddings); } await main(); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.types.Content; import com.google.genai.types.EmbedContentResponse; import com.google.genai.types.Part; import java.nio.file.Files; import java.nio.file.Paths; Client client = new Client(); byte[] pdfBytes = Files.readAllBytes(Paths.get("example.pdf")); Content content = Content.fromParts(Part.fromBytes(pdfBytes, "application/pdf")); EmbedContentResponse response = client.models.embedContent("gemini-embedding-2", content, null); System.out.println(response.embeddings().orElse(null)); ``` {% /tab %} {% tab label="REST" %} ```sh PDF_PATH="/path/to/your/example.pdf" PDF_BASE64=$(base64 -w0 "${PDF_PATH}") curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-embedding-2:embedContent" \ -H "Content-Type: application/json" \ -H "x-goog-api-key: ${GEMINI_API_KEY}" \ -d '{ "content": { "parts": [{ "inline_data": { "mime_type": "application/pdf", "data": "'"${PDF_BASE64}"'" } }] } }' ``` {% /tab %} {% /tabs %} ## Use cases {% id="common-use-cases" %} Text embeddings are crucial for a variety of common AI use cases, such as: * **Retrieval-Augmented Generation (RAG):** Embeddings enhance the quality of generated text by retrieving and incorporating relevant information into the context of a model. * **Information retrieval:** Search for the most semantically similar text or documents given a piece of input text. {% button href="https://github.com/google-gemini/cookbook/blob/main/examples/Talk_to_documents_with_embeddings.ipynb" variant="primary" icon="task" %}Document search tutorial{% /button %} * **Search reranking**: Prioritize the most relevant items by semantically scoring initial results against the query. {% button href="https://github.com/google-gemini/cookbook/blob/main/examples/Search_reranking_using_embeddings.ipynb" variant="primary" icon="task" %}Search reranking tutorial{% /button %} * **Anomaly detection:** Comparing groups of embeddings can help identify hidden trends or outliers. {% button href="https://github.com/google-gemini/cookbook/blob/main/examples/Anomaly_detection_with_embeddings.ipynb" variant="primary" icon="bubble_chart" %}Anomaly detection tutorial{% /button %} * **Classification:** Automatically categorize text based on its content, such as sentiment analysis or spam detection {% button href="https://github.com/google-gemini/cookbook/blob/main/examples/Classify_text_with_embeddings.ipynb" variant="primary" icon="token" %}Classification tutorial{% /button %} * **Clustering:** Effectively grasp complex relationships by creating clusters and visualizations of your embeddings. {% button href="https://github.com/google-gemini/cookbook/blob/main/examples/clustering_with_embeddings.ipynb" variant="primary" icon="bubble_chart" %}Clustering visualization tutorial{% /button %} ## Storing embeddings {% id="store-embeddings" %} As you take embeddings to production, it is common to use **vector databases** to efficiently store, index, and retrieve high-dimensional embeddings. Google Cloud offers managed data services that can be used for this purpose including [Gemini Enterprise Agent Platform Vector Search 2.0](https://docs.cloud.google.com/gemini-enterprise-agent-platform/build/vector-search-2/overview), [BigQuery](https://cloud.google.com/bigquery/docs/introduction), [AlloyDB](https://cloud.google.com/alloydb/docs/overview), and [Cloud SQL](https://cloud.google.com/sql/docs/postgres/introduction). The following tutorials show how to use other third party vector databases with Gemini Embedding. * {% button href="https://docs.trychroma.com/integrations/embedding-models/google-gemini" variant="primary" icon="bolt" %}ChromaDB tutorials{% /button %} * {% button href="https://qdrant.tech/documentation/embeddings/gemini/" variant="primary" icon="bolt" %}QDrant tutorials{% /button %} * {% button href="https://docs.weaviate.io/weaviate/model-providers/google" variant="primary" icon="bolt" %}Weaviate tutorials{% /button %} * {% button href="https://github.com/google-gemini/cookbook/blob/main/examples/langchain/Gemini_LangChain_QA_Pinecone_WebLoad.ipynb" variant="primary" icon="bolt" %}Pinecone tutorials{% /button %} ## Model versions {% id="model-versions" %} {% partial file="googledevai/en/gemini-api/docs/models/_includes/_gemini-embedding.md" /%} For deprecated Embeddings models, visit the [Deprecations](/docs/deprecations) page ## Migration from gemini-embedding-001 {% id="migration" %} The embedding spaces between `gemini-embedding-001` and `gemini-embedding-2` are **incompatible**. This means you cannot directly compare embeddings generated by one model with embeddings generated by the other. If you are upgrading to `gemini-embedding-2`, you must re-embed all of your existing data. Beyond incompatibility, there are several other notable differences between the two models: * **Task type specification:** With `gemini-embedding-001`, you specify the task type using the `task_type` parameter (e.g., `SEMANTIC_SIMILARITY`, `RETRIEVAL_DOCUMENT`). With `gemini-embedding-2`, the `task_type` parameter is not supported. Instead, you should include task instructions directly in the prompt for text-only tasks. See [Task types with Embeddings 2](/docs/embeddings#task-types-embeddings-2) for details on how to format prompts for different use cases. * **Embedding aggregation:** `gemini-embedding-001` generates individual embeddings for each string in a list of inputs. In contrast, `gemini-embedding-2` produces a single, aggregated embedding when multiple inputs (like text and images) are provided directly in one request. To generate separate embeddings for individual inputs, wrap each input in a `Content` object, or use the [Batch API](/docs/batch-api#batch-embedding). See [Embedding aggregation](/docs/embeddings#embedding-aggregation) for more information. * **Normalization:** If you use `output_dimensionality` to request embeddings with fewer than 3072 dimensions, `gemini-embedding-2` automatically normalizes these truncated embeddings. With `gemini-embedding-001`, you need to perform manual normalization for dimensions other than 3072. See [Ensuring quality for smaller dimensions](/docs/embeddings#quality-for-smaller-dimensions) for details. ## Batch embeddings {% id="batch-embedding" %} If latency is not a concern, try using the Gemini Embeddings models with [Batch API](/docs/batch-api#batch-embedding). This allows for much higher throughput at 50% of the default Embedding price. Find examples on how to get started in the [Batch API cookbook](https://github.com/google-gemini/cookbook/blob/main/quickstarts/Batch_mode.ipynb). ## Responsible use notice {% id="responsible-use-notice" %} Unlike generative AI models that create new content, the Gemini Embedding model is only intended to transform the format of your input data into a numerical representation. While Google is responsible for providing an embedding model that transforms the format of your input data to the numerical-format requested, users retain full responsibility for the data they input and the resulting embeddings. By using the Gemini Embedding model you confirm that you have the necessary rights to any content that you upload. Do not generate content that infringes on others' intellectual property or privacy rights. Your use of this service is subject to our [Prohibited Use Policy](https://policies.google.com/terms/generative-ai/use-policy) and [Google's Terms of Service](/docs/terms). ## Start building with embeddings {% id="start-building" %} Check out the [embeddings quickstart notebook](https://github.com/google-gemini/cookbook/blob/main/quickstarts/Embeddings.ipynb) to explore the model capabilities and learn how to customize and visualize your embeddings. # Gemini Robotics ER Source: https://aistudio.google.com/docs/robotics-overview Description: Overview of Gemini Robotics ER models and capabilities for building robotics applications. {% callout type="note" %} The Gemini Robotics ER model is in preview. {% /callout %} Gemini Robotics ER (embodied reasoning) models are vision-language models (VLMs) that let robots perceive and interact with the physical world. They interpret visual data, perform spatial and temporal reasoning, plan multi-step tasks, and orchestrate robots and tools. ## Models {% id="models" %} The Gemini Robotics ER 2 model is the latest model in Gemini Robotics. It is our updated reasoning model that enables robots to understand their environments precisely. It specializes in embodied reasoning capabilities, such as agentic orchestration of robots (e.g. using VLAs), robot video understanding including progress understanding and success detection, instrument reading, pointing, and spatial reasoning. The Gemini Robotics ER 2 model introduces two model endpoints: * **`gemini-robotics-er-2-preview`**: The standard ER 2 model. Builds on Gemini 3.5 Flash with improved spatial reasoning, video moment finding, video progress classification, multi-robot orchestration, and multi-step tool use. * **`gemini-robotics-er-2-streaming-preview`**: Optimized for real-time streaming using the [Live API](/docs/live-api/get-started-sdk). Use this model for low-latency robot agents that process continuous audio and video input. Gemini Robotics ER 1.6 was [deprecated on August 31, 2026](/docs/deprecations#robotics-models). If you are still using Gemini Robotics ER 1.6, upgrade to Gemini Robotics ER 2 by replacing `model="gemini-robotics-er-1.6-preview"` with `model="gemini-robotics-er-2-preview"` or `model="gemini-robotics-er-2-streaming-preview"` in your API calls. {% button href="https://aistudio.google.com/prompts/new_chat?model=gemini-robotics-er-2-preview" variant="ais" %}Try Gemini Robotics ER 2 in Google AI Studio{% /button %} ## Robotics capabilities {% id="capabilities" %} Gemini Robotics ER supports a range of embodied reasoning capabilities. Select a capability to learn more: {% table %} * Capability * Description * Guide --- * Spatial reasoning * Point to objects, track them in video, detect with bounding boxes, plan trajectories. * [Spatial reasoning](/docs/robotics-spatial) --- * Agentic vision * Use code execution to enhance other capabilities by leveraging image manipulation tools. * [Agentic vision](/docs/robotics-agentic) --- * Task orchestration * Combine spatial reasoning with custom robot APIs to complete long-horizon tasks. * [Task orchestration](/docs/robotics-orchestration) --- * Streaming (Gemini Robotics ER 2 Streaming endpoint only) * Bidirectional streaming for real-time robot agents with low-latency function calling. * [Streaming for robotics](/docs/robotics-streaming) --- * Video progress (Gemini Robotics ER 2 only) * Moment finding and progress classification from continuous video feeds. * [Video understanding](/docs/robotics-video-progress) {% /table %} ## Before you begin {% id="before-you-begin" %} The Gemini Robotics ER models are available through the **Gemini Developer API**. To get started, create a [Gemini API key](/docs/api-key) from [Google AI Studio](https://aistudio.google.com/apikey) or the [Google Cloud console](/docs/api-key#cloud-console), and [set up your environment](/docs/api-key#setup-environment). For details on key types, security, and how to configure your key in Python, JavaScript, and other languages, see [Using Gemini API keys](/docs/api-key). {% callout type="note" %} Cloud Storage URIs (`gs://`) are not directly accessible through the Gemini Developer API. Load your images locally or use the [Files API](/docs/files). {% /callout %} ## Getting started {% id="getting-started" %} The following example finds objects in an image and returns their normalized 2D coordinates and labels. You can pass this output directly to a robotics API or a VLA model to generate robot actions. {% tabs %} {% tab label="Python" filename="robotics_overview.py" %} ```python from google import genai PROMPT = """ Point to no more than 10 items in the image. The label returned should be an identifying name for the object detected. The answer should follow the json format: [{"point": , "label": }, ...]. The points are in [y, x] format normalized to 0-1000. """ client = genai.Client() uploaded_file = client.files.upload(file="my-image.png") image_response = client.interactions.create( model="gemini-robotics-er-2-preview", input=[ { "type": "image", "uri": uploaded_file.uri, "mime_type": uploaded_file.mime_type }, {"type": "text", "text": PROMPT} ], generation_config={"thinking_level": "high"}, ) print(image_response.output_text) ``` {% /tab %} {% tab label="JavaScript" %} ```javascript import { GoogleGenAI } from "@google/genai"; const PROMPT = ` Point to no more than 10 items in the image. The label returned should be an identifying name for the object detected. The answer should follow the json format: [{"point": , "label": }, ...]. The points are in [y, x] format normalized to 0-1000. `; const client = new GoogleGenAI(); const uploadedFile = await client.files.upload({ file: "my-image.png" }); const imageResponse = await client.interactions.create({ model: "gemini-robotics-er-2-preview", input: [ { type: "image", uri: uploadedFile.uri, mime_type: uploadedFile.mimeType, }, { type: "text", text: PROMPT }, ], generation_config: { thinking_level: "high" }, }); console.log(imageResponse.output_text); ``` {% /tab %} {% tab label="Java" %} ```java import com.google.genai.Client; import com.google.genai.gaos.models.interactions.Content; import com.google.genai.gaos.models.interactions.CreateModelInteraction; import com.google.genai.gaos.models.interactions.GenerationConfig; import com.google.genai.gaos.models.interactions.ImageContent; import com.google.genai.gaos.models.interactions.ImageContentMimeType; import com.google.genai.gaos.models.interactions.Interaction; import com.google.genai.gaos.models.interactions.InteractionsInput; import com.google.genai.gaos.models.interactions.Model; import com.google.genai.gaos.models.interactions.TextContent; import com.google.genai.gaos.models.interactions.ThinkingLevel; import com.google.genai.gaos.models.operations.CreateInteractionRequestBody; import com.google.genai.types.File; import com.google.genai.types.UploadFileConfig; import java.util.List; Client client = new Client(); String prompt = "Point to no more than 10 items in the image. The label returned " + "should be an identifying name for the object detected. " + "The answer should follow the json format: [{\"point\": , " + "\"label\": }, ...]. The points are in [y, x] format " + "normalized to 0-1000."; File uploadedFile = client.files.upload( new java.io.File("my-image.png"), UploadFileConfig.builder().mimeType("image/png").build()); Content imageContent = ImageContent.builder() .uri(uploadedFile.uri().orElse("")) .mimeType(ImageContentMimeType.of(uploadedFile.mimeType().orElse("image/png"))) .build(); Content textContent = TextContent.builder().text(prompt).build(); CreateModelInteraction params = CreateModelInteraction.builder() .model(Model.of("gemini-robotics-er-2-preview")) .input(InteractionsInput.ofContent(List.of(imageContent, textContent))) .generationConfig( GenerationConfig.builder().thinkingLevel(ThinkingLevel.HIGH).build()) .build(); Interaction imageResponse = client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get(); System.out.println(imageResponse.outputText().orElse("")); ``` {% /tab %} {% tab label="Go" %} ```go package main import ( "context" "fmt" "log" "google.golang.org/genai" "google.golang.org/genai/interactions/models/interactions" "google.golang.org/genai/interactions/models/operations" ) func main() { ctx := context.Background() client, err := genai.NewClient(ctx, nil) if err != nil { log.Fatal(err) } prompt := `Point to no more than 10 items in the image. The label returned should be an identifying name for the object detected. The answer should follow the json format: [{"point": , "label": }, ...]. The points are in [y, x] format normalized to 0-1000.` uploadedFile, err := client.Files.UploadFromPath(ctx, "my-image.png", &genai.UploadFileConfig{ MIMEType: "image/png", }) if err != nil { log.Fatal(err) } res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{ Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{ Model: interactions.Model("gemini-robotics-er-2-preview"), Input: interactions.NewInteractionsInput([]interactions.Content{ interactions.NewContent(interactions.ImageContent{ URI: genai.Ptr(uploadedFile.URI), MimeType: genai.Ptr(interactions.ImageMimeTypeImagePng), }), interactions.NewContent(interactions.TextContent{ Text: prompt, }), }), GenerationConfig: &interactions.GenerationConfig{ ThinkingLevel: interactions.ThinkingLevelHigh.ToPointer(), }, }), }) if err != nil { log.Fatal(err) } if res.Interaction.OutputText != nil { fmt.Println(*res.Interaction.OutputText) } } ``` {% /tab %} {% tab label="REST" filename="robotics_overview.sh" %} ```bash # First, ensure you have the image file locally. # Encode the image to base64 IMAGE_BASE64=$(base64 -w 0 my-image.png) curl -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gemini-robotics-er-2-preview", "input": { "parts": [ { "inlineData": { "mimeType": "image/png", "data": "'"${IMAGE_BASE64}"'" } }, { "text": "Point to no more than 10 items in the image. The label returned should be an identifying name for the object detected. The answer should follow the json format: [{\"point\": [y, x], \"label\": }, ...]. The points are in [y, x] format normalized to 0-1000." } ] }, "generation_config": { "thinking_config": { "thinking_level": "high" } } }' ``` {% /tab %} {% /tabs %} The output will be a JSON array containing objects, each with a `point` (normalized `[y, x]` coordinates) and a `label` identifying the object. {% tabs %} {% tab label="JSON" filename="output.json" %} ```json [ {"point": [376, 508], "label": "small banana"}, {"point": [287, 609], "label": "larger banana"}, {"point": [223, 303], "label": "pink starfruit"}, {"point": [435, 172], "label": "paper bag"}, {"point": [270, 786], "label": "green plastic bowl"}, {"point": [488, 775], "label": "metal measuring cup"}, {"point": [673, 580], "label": "dark blue bowl"}, {"point": [471, 353], "label": "light blue bowl"}, {"point": [492, 497], "label": "bread"}, {"point": [525, 429], "label": "lime"} ] ``` {% /tab %} {% /tabs %} The following image is an example of how these points can be displayed: ![An example that displays the points of objects in an image](/googledevai/static/gemini-api/docs/images/robotics/point-to-object.png) ## How it works {% id="how-it-works" %} Gemini Robotics ER takes image, video, or audio input with natural language prompts. It identifies objects, reasons about scene context and spatial relationships, and returns structured output like coordinates or bounding boxes. Gemini Robotics ER is also agentic: it breaks complex tasks into sub-tasks and executes them by calling your robot functions or running generated code. For example, "put the apple in the bowl" becomes a sequence of locate, grasp, and place steps. See [Function calling](/docs/function-calling?example=meeting#how-it-works) for details on how Gemini executes tool calls. ## Safety {% id="safety" %} While Gemini Robotics ER was built with safety in mind, it is your responsibility to maintain a safe environment around the robot. Generative AI models can make mistakes, and physical robots can cause damage. To learn more, visit the [Gemini Robotics safety page](https://deepmind.google/models/gemini-robotics/safety). ## Best practices {% id="best-practices" %} 1. Use plain, natural language. Describe what you want the robot to do as you would to a person. If a term isn't working, try a common synonym. 2. Optimize visual input. Crop or zoom into small or unclear objects before sending the image. Lighting and low color contrast can affect detection. 3. Break complex tasks into steps. Send each step as a separate prompt to keep the model focused and improve accuracy. 4. Query multiple times and average results for high-precision tasks. This consensus approach reduces variance on spatial outputs. ## Limitations {% id="limitations" %} Consider the following limitations when developing with Gemini Robotics ER: * **API key restrictions:** The Gemini API does not accept requests from unrestricted API keys and returns a `403 Forbidden` error. Secure your API key by adding restrictions in [AI Studio](https://aistudio.google.com/api-keys). See [Secure unrestricted API keys](/docs/api-key#secure-unrestricted-keys) for details. * **Latency vs performance:** Complex queries, high-resolution inputs or high thinking levels can lead to increased processing times. For thinking level use medium for a good balance between latency and performance. * **Hallucinations:** Like all large language models, Gemini Robotics ER models can occasionally "hallucinate" or provide incorrect information, especially for ambiguous prompts or out-of-distribution inputs. * **Dependence on prompt quality:** Output quality depends on the clarity of the input prompt. Use specific, well-structured prompts. * **Computational cost:** Running the model, especially with video inputs or high `thinking_budget`, consumes computational resources and incurs costs. See the [Thinking](/docs/thinking) page for more details. * **Input types:** See the following topics for details on limitations for each mode. * [Image inputs](/docs/image-understanding#technical-details-image) * [Video inputs](/docs/video-understanding#supported-formats) * [Audio inputs](/docs/audio#supported-formats) ## Privacy Notice {% id="privacy-notice" %} You acknowledge that the models referenced in this document (the "Robotics Models") leverage video and audio data in order to operate and move your hardware in accordance with your instructions. You therefore may operate the Robotics Models such that data from identifiable persons, such as voice, imagery, and likeness data ("Personal Data"), will be collected by the Robotics Models. If you elect to operate the Robotics Models in a manner that collects Personal Data, you agree that you will not permit any identifiable persons to interact with, or be present in the area surrounding, the Robotics Models, unless and until such identifiable persons have been sufficiently notified of and consented to the fact that their Personal Data may be provided to and used by Google as outlined in the Gemini API Additional Terms of Service found at [https://ai.google.dev/gemini-api/terms](https://ai.google.dev/gemini-api/terms) (the "Terms"), including in accordance with the section entitled "How Google Uses Your Data". You will ensure that such notice permits the collection and use of Personal Data as outlined in the Terms, and you will use commercially reasonable efforts to minimize the collection and distribution of Personal Data by using techniques such as face blurring and operating the Robotics Models in areas not containing identifiable persons to the extent practicable. ## Pricing {% id="pricing" %} For detailed information on pricing and available regions, refer to the [pricing](/docs/pricing) page. ## Model endpoints {% id="model-versions" %} {% partial file="googledevai/en/gemini-api/docs/models/_includes/_robotics-er.md" /%} ## What's next {% id="whats-next" %} * [Spatial reasoning](/docs/robotics-spatial) — pointing, tracking, bounding boxes, trajectories. * [Agentic capabilities](/docs/robotics-agentic) — code execution, instrument reading, image annotation. * [Task orchestration](/docs/robotics-orchestration) — long-horizon tasks with custom robot APIs. * [Robotics with streaming](/docs/robotics-streaming) — real-time bidirectional streaming (Gemini Robotics ER 2 only). * [Video understanding](/docs/robotics-video-progress) — moment finding and progress classification (Gemini Robotics ER 2 only). * [Gemini Robotics safety](https://deepmind.google/models/gemini-robotics/safety) — safety research behind the model family. # Spatial reasoning Source: https://aistudio.google.com/docs/robotics-spatial Description: Use Gemini Robotics ER for spatial reasoning tasks including object detection, tracking, and trajectory planning. Gemini Robotics ER models can point to objects, track them in video, detect them with bounding boxes, and generate movement trajectories. For full runnable code, see the [Robotics cookbook](https://github.com/google-gemini/robotics-samples/blob/main/Getting%20Started/gemini_robotics_er.ipynb). ## Point to objects {% id="pointing-to-objects" %} The following example finds specific objects in an image and returns their normalized `[y, x]` coordinates: {% tabs %} {% tab label="Python" filename="robotics_spatial.py" %} ```python from google import genai PROMPT = """ Point to no more than 10 items in the image. The label returned should be an identifying name for the object detected. The answer should follow the json format: [{"point": , "label": }, ...]. The points are in [y, x] format normalized to 0-1000. """ client = genai.Client() uploaded_file = client.files.upload(file="my-image.png") image_response = client.interactions.create( model="gemini-robotics-er-2-preview", input=[ { "type": "image", "uri": uploaded_file.uri, "mime_type": uploaded_file.mime_type }, {"type": "text", "text": PROMPT} ], generation_config={"thinking_level": "high"}, ) print(image_response.output_text) ``` {% /tab %} {% tab label="REST" filename="robotics_spatial.sh" %} ```bash # First, ensure you have the image file locally. # Encode the image to base64 IMAGE_BASE64=$(base64 -w 0 my-image.png) curl -X POST \ "https://generativelanguage.googleapis.com/v1beta/interactions" \ -H "x-goog-api-key: $GEMINI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gemini-robotics-er-2-preview", "input": { "parts": [ { "inlineData": { "mimeType": "image/png", "data": "'"${IMAGE_BASE64}"'" } }, { "text": "Point to no more than 10 items in the image. The label returned should be an identifying name for the object detected. The answer should follow the json format: [{\"point\": [y, x], \"label\": }, ...]. The points are in [y, x] format normalized to 0-1000." } ] }, "generation_config": { "thinking_config": { "thinking_level": "high" } } }' ``` {% /tab %} {% /tabs %} The output will be a JSON array containing objects, each with a `point` (normalized `[y, x]` coordinates) and a `label` identifying the object. {% tabs %} {% tab label="JSON" filename="output.json" %} ```json [ {"point": [376, 508], "label": "small banana"}, {"point": [287, 609], "label": "larger banana"}, {"point": [223, 303], "label": "pink starfruit"}, {"point": [435, 172], "label": "paper bag"}, {"point": [270, 786], "label": "green plastic bowl"}, {"point": [488, 775], "label": "metal measuring cup"}, {"point": [673, 580], "label": "dark blue bowl"}, {"point": [471, 353], "label": "light blue bowl"}, {"point": [492, 497], "label": "bread"}, {"point": [525, 429], "label": "lime"} ] ``` {% /tab %} {% /tabs %} The following image is an example of how these points can be displayed: ![An example that displays the points of objects in an image](/googledevai/static/gemini-api/docs/images/robotics/point-to-object.png) ## Tracking objects in a video {% id="object-tracking-video" %} Gemini Robotics ER 2 can also analyze video frames to track objects over time. See [Video inputs](/docs/video-understanding#supported-formats) for a list of supported video formats. {% tabs %} {% tab label="Python" filename="robotics_tracking.py" %} ```python from google import genai client = genai.Client() uploaded_file = client.files.upload(file="my-video.mp4") prompt = """ Point to the red ball in every frame where it appears. The answer should follow the json format: [{"point": [y, x], "label":