Gemini 4 Hydrogen brings cutting-edge intelligence with speed and efficiency to everyday coding and agentic enterprise workflows.
This document covers the key capabilities of Hydrogen, the API conventions it enforces, how to migrate to it from Gemini 3.8 Flash and earlier Gemini 3 Flash models, and a quickstart. For an overview of the Gemini 4 family, see Get started with Gemini 4.
Key capabilities in Gemini 4 Hydrogen
Gemini 4 Hydrogen includes the following capabilities:
- Unified input and output token limit: Hydrogen has a unified 1,048,576-token limit that includes both input and output tokens (where output includes thinking, function calls, and the final response).
- Long decodes up to 1,048,576 tokens: Hydrogen
extends generation beyond a single 65,536-token foreground segment
(streaming or non-streaming) up to 1,048,576 tokens (minus your input
tokens) on both the
Interactions API and
GenerateContent(v1beta1). The Google Gen AI SDK handlescontinuation_tokenautomatically across segments, or you can run asynchronous server-managed background decodes (background=true) or managecontinuation_tokenin a custom continuation loop. - Thinking levels: Hydrogen supports
LOW,MEDIUM,HIGH(default), andXHIGH. - Implicit caching with durable caching: Implicit caching applies automatically to shared prompt prefixes of 4,096 tokens or more, with durable caching enabled by default. Explicit context caching isn't supported.
- Office and OpenDocument file inputs: In addition to PDF and plain text,
Hydrogen accepts Microsoft Office (
.docx,.dotx,.doc,.pptx,.ppt,.xlsx,.xls) and OpenDocument (.odt,.odp,.ods) files inline or from Cloud Storage on bothGenerateContentand the Interactions API, including inside multimodalFunctionResponseparts. - Agentic video understanding: Agentic video understanding is generally available and off by default.
- Short-term release lifecycle: Hydrogen is a short-term generally available (GA) release subject to a minimum 45-day retirement notice policy. For lifecycle details, see Model versions and lifecycle.
Quickstart
Before you begin, you must authenticate to Gemini Enterprise Agent Platform using Application Default Credentials (ADC) or an API key. See Get started with Agent Platform for more information.
In the following code blocks, replace PROJECT_ID with
your project ID.
Try it in Agent Studio
To test prompts and configure gemini-4-hydrogen in the
Agent Studio
UI, do the following:
- Open Agent Studio
in your Google Cloud project and select
gemini-4-hydrogenunder the Gemini group. - In Model settings, configure the following options:
- Thinking level: Choose
Low,Medium,High(default), orExtra high. - Region: Select
Global,us, oreu. - Output token limit: Set between
32,768and1,048,576(1,048,576default). Agent Studio handles continuation tokens automatically for responses over the single-request limit.
- Thinking level: Choose
Installation
Upgrade to the latest Google Gen AI SDK. Automatic continuation on the
Interactions API requires google-genai >= 2.34.0 for Python,
@google/genai >= 2.32.0 for JavaScript/TypeScript, >= 1.77.0 for Go, or
>= 1.80.0 for Java (on GenerateContent, automatic continuation requires
>= 2.30.1 for Python, >= 2.29.1 for JavaScript/TypeScript, >= 1.74.0 for
Go, >= 1.77.0 for Java, >= 1.26.0 for .NET, or >= 1.6.0 for Kotlin):
pip install --upgrade "google-genai>=2.34.0"
Basic request
Send a request to gemini-4-hydrogen using the
Google Gen AI SDK or REST:
Python (GenerateContent)
from google import genai
from google.genai import types
client = genai.Client(enterprise=True, project="PROJECT_ID", location="global")
response = client.models.generate_content(
model="gemini-4-hydrogen",
contents="Design a lock-free ring buffer in Rust for multi-producer, single-consumer telemetry ingestion.",
config=types.GenerateContentConfig(
thinking_config=types.ThinkingConfig(
thinking_level="HIGH", # Default: "HIGH" (Valid: "LOW", "MEDIUM", "HIGH", "XHIGH")
),
),
)
print(response.text)
Python (Interactions API)
from google import genai
client = genai.Client(enterprise=True, project="PROJECT_ID", location="global")
# Turn 1: Initial request (stored server-side by default)
turn1 = client.interactions.create(
model="gemini-4-hydrogen",
input="Design a lock-free ring buffer in Rust for multi-producer, single-consumer telemetry ingestion.",
store=True,
)
print(turn1.output_text)
# Turn 2: Continue the conversation using previous_interaction_id
turn2 = client.interactions.create(
model="gemini-4-hydrogen",
input="Add a bounded backpressure policy and unit tests for concurrent writers.",
previous_interaction_id=turn1.id,
)
print(turn2.output_text)
REST
curl -X POST \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" \
"https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/publishers/google/models/gemini-4-hydrogen:generateContent" \
-d '{
"contents": [
{
"role": "user",
"parts": [
{
"text": "Provide an architectural review of this Go interface."
}
]
}
],
"generationConfig": {
"thinkingConfig": {
"thinkingLevel": "HIGH"
}
}
}'
Structured output
To generate JSON output that conforms to a schema, configure
response_mime_type and response_schema:
from pydantic import BaseModel, Field
from google import genai
from google.genai import types
class ArchitectureReview(BaseModel):
component: str = Field(description="Service or module name")
bottlenecks: list[str] = Field(description="Throughput or latency bottlenecks")
recommended_changes: list[str] = Field(description="Concrete refactoring steps")
client = genai.Client(enterprise=True, project="PROJECT_ID", location="global")
response = client.models.generate_content(
model="gemini-4-hydrogen",
contents="Review a synchronous order-processing pipeline backed by a single primary database at 15,000 writes/sec.",
config=types.GenerateContentConfig(
response_mime_type="application/json",
response_schema=ArchitectureReview,
thinking_config=types.ThinkingConfig(thinking_level="HIGH"),
),
)
print(response.text)
Long decode examples
By default, a single foreground API segment generates up to 65,536 output tokens
(streaming or non-streaming), where output includes thinking, function calls,
and the final response. To generate completions up to
1,048,576 tokens (minus your input tokens), use long decodes on either the
Interactions API or
GenerateContent. For continuation options, status transitions, and validation
rules, see Long decodes.
Use long decodes with the Interactions API
In google-genai >= 2.34.0 (Python), @google/genai >= 2.32.0
(JavaScript/TypeScript), Go >= 1.77.0, and Java >= 1.80.0,
interactions.create() automatically follows continuation_token across
segments whenever a segment returns status="requires_continuation". You can
also opt out (automatic_continuation=False) to run a custom stored
(store=True) or stateless (store=False) loop:
Python (SDK automatic)
from google import genai
client = genai.Client(
enterprise=True,
project="PROJECT_ID",
location="global",
)
# Automatic continuation is enabled by default in google-genai >= 2.34.0.
# Unary calls merge all segments into one Interaction with summed usage.
interaction = client.interactions.create(
model="gemini-4-hydrogen",
input="Write a complete formal proof of the prime number theorem.",
generation_config={
"max_output_tokens": 256000,
"thinking_level": "high",
},
)
print(interaction.output_text)
print(f"Merged segment IDs: {interaction.continuation_ids}")
print(f"Initial input tokens: {interaction.usage.initial_input_tokens}")
# Streaming yields events across all segments in order. Intermediate segments
# emit interaction.completed with status="requires_continuation".
stream = client.interactions.create(
model="gemini-4-hydrogen",
input="Write a complete formal proof of the prime number theorem.",
stream=True,
generation_config={
"max_output_tokens": 256000,
"thinking_level": "high",
},
)
for event in stream:
if event.event_type == "step.delta" and getattr(event.delta, "text", None):
print(event.delta.text, end="", flush=True)
elif (
event.event_type == "interaction.completed"
and event.interaction.status != "requires_continuation"
):
print(f"\nFinal status: {event.interaction.status}")
# Optional: Delete each stored server segment (last segment first) before its 7-day TTL expires.
for segment_id in reversed(interaction.continuation_ids or [interaction.id]):
client.interactions.delete(id=segment_id)
# Set automatic_continuation=False to return after a single segment.
single_segment = client.interactions.create(
model="gemini-4-hydrogen",
input="Write a complete formal proof of the prime number theorem.",
generation_config={"max_output_tokens": 256000, "thinking_level": "high"},
automatic_continuation=False,
)
Python (Custom loop)
from google import genai
client = genai.Client(
enterprise=True,
project="PROJECT_ID",
location="global",
)
prompt = "Write a complete formal proof of the prime number theorem."
# Stored loop (store=True, default): chain previous_interaction_id + continuation_token
# without resending input.
segment = client.interactions.create(
model="gemini-4-hydrogen",
input=prompt,
store=True,
generation_config={"max_output_tokens": 131072, "thinking_level": "high"},
automatic_continuation=False,
)
full_text = segment.output_text or ""
while segment.status == "requires_continuation" and segment.continuation_token:
segment = client.interactions.create(
model="gemini-4-hydrogen",
previous_interaction_id=segment.id,
continuation_token=segment.continuation_token,
generation_config={"max_output_tokens": 131072, "thinking_level": "high"},
automatic_continuation=False,
)
full_text += segment.output_text or ""
# If status == "incomplete", max_output_tokens was exhausted; raise max_output_tokens to continue.
if segment.status == "incomplete" and segment.continuation_token:
segment = client.interactions.create(
model="gemini-4-hydrogen",
previous_interaction_id=segment.id,
continuation_token=segment.continuation_token,
generation_config={"max_output_tokens": 256000, "thinking_level": "high"},
)
full_text += segment.output_text or ""
# Stateless loop (store=False): resend original input + continuation_token
# with no previous_interaction_id.
stateless_seg = client.interactions.create(
model="gemini-4-hydrogen",
input=prompt,
store=False,
generation_config={"max_output_tokens": 131072, "thinking_level": "high"},
automatic_continuation=False,
)
stateless_text = stateless_seg.output_text or ""
while stateless_seg.status == "requires_continuation" and stateless_seg.continuation_token:
stateless_seg = client.interactions.create(
model="gemini-4-hydrogen",
input=prompt,
store=False,
continuation_token=stateless_seg.continuation_token,
generation_config={"max_output_tokens": 131072, "thinking_level": "high"},
automatic_continuation=False,
)
stateless_text += stateless_seg.output_text or ""
REST (Stored)
# Segment 1: Start a stored interaction (store=true by default)
curl -s -X POST \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" \
"https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/interactions" \
-d '{
"model": "gemini-4-hydrogen",
"store": true,
"input": "Write a complete formal proof of the prime number theorem.",
"generation_config": {
"max_output_tokens": 131072,
"thinking_level": "high"
}
}'
# Segment 2: When status is "requires_continuation", pass previous_interaction_id
# and continuation_token without resending input
curl -s -X POST \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" \
"https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/interactions" \
-d '{
"model": "gemini-4-hydrogen",
"store": true,
"previous_interaction_id": "SEGMENT_1_ID",
"continuation_token": "CONTINUATION_TOKEN",
"generation_config": {
"max_output_tokens": 131072,
"thinking_level": "high"
}
}'
REST (Stateless)
# Segment 1: Stateless interaction (store=false)
curl -s -X POST \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" \
"https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/interactions" \
-d '{
"model": "gemini-4-hydrogen",
"store": false,
"input": "Write a complete formal proof of the prime number theorem.",
"generation_config": {
"max_output_tokens": 131072,
"thinking_level": "high"
}
}'
# Segment 2: Resend the original input and continuation_token (no previous_interaction_id)
curl -s -X POST \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" \
"https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/interactions" \
-d '{
"model": "gemini-4-hydrogen",
"store": false,
"input": "Write a complete formal proof of the prime number theorem.",
"continuation_token": "CONTINUATION_TOKEN",
"generation_config": {
"max_output_tokens": 131072,
"thinking_level": "high"
}
}'
For asynchronous server-managed execution (background=True with store=True)
or recovery from streaming checkpoints (interaction.status_update events
emitted starting at 65,536 output tokens and every 5,000 tokens thereafter), use
the following patterns:
Python (Background)
import time
from google import genai
client = genai.Client(
enterprise=True,
project="PROJECT_ID",
location="global",
)
# Start a server-managed background long decode (requires store=True)
interaction = client.interactions.create(
model="gemini-4-hydrogen",
input="Write a complete formal proof of the prime number theorem.",
background=True,
store=True,
generation_config={"max_output_tokens": 256000, "thinking_level": "high"},
)
while interaction.status in ("queued", "in_progress"):
time.sleep(10)
interaction = client.interactions.get(id=interaction.id)
print(f"Status: {interaction.status}")
print(interaction.output_text)
# Optional: Cancel an in-progress background interaction and resume later
# from its persisted checkpoint continuation_token (if >= 65,536 tokens decoded).
# cancelled = client.interactions.cancel(id=interaction.id)
# if cancelled.continuation_token:
# resumed = client.interactions.create(
# model="gemini-4-hydrogen",
# previous_interaction_id=cancelled.id,
# continuation_token=cancelled.continuation_token,
# background=True,
# generation_config={"max_output_tokens": 256000, "thinking_level": "high"},
# )
REST (Background)
# Start a server-managed background long decode (requires store=true)
curl -s -X POST \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" \
"https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/interactions" \
-d '{
"model": "gemini-4-hydrogen",
"background": true,
"store": true,
"input": "Write a complete formal proof of the prime number theorem.",
"generation_config": {
"max_output_tokens": 256000,
"thinking_level": "high"
}
}'
# Poll the interaction until status reaches completed, incomplete, failed, or cancelled
curl -s -X GET \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
"https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/interactions/INTERACTION_ID"
# Optional: Cancel an in-progress background decode
curl -s -X POST \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
"https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/interactions/INTERACTION_ID/cancel"
# Optional: Resume a cancelled background decode from its checkpoint continuation_token
curl -s -X POST \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" \
"https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/interactions" \
-d '{
"model": "gemini-4-hydrogen",
"background": true,
"store": true,
"previous_interaction_id": "INTERACTION_ID",
"continuation_token": "CONTINUATION_TOKEN",
"generation_config": {
"max_output_tokens": 256000,
"thinking_level": "high"
}
}'
Python (Streaming checkpoints)
from google import genai
from google.genai import errors
client = genai.Client(
enterprise=True,
project="PROJECT_ID",
location="global",
)
# With default automatic_continuation=True, stream=True automatically
# reconnects from the latest interaction.status_update checkpoint (65,536
# output tokens, then every 5,000 tokens) if no output was yielded after the
# checkpoint. If a disconnect occurs after output was yielded since the last
# checkpoint, the SDK raises ContinuationInterruptedError so you can resume
# from err.continuation_token.
stream = client.interactions.create(
model="gemini-4-hydrogen",
input="Write a complete formal proof of the prime number theorem.",
stream=True,
store=True,
generation_config={"max_output_tokens": 256000, "thinking_level": "high"},
)
try:
for event in stream:
if event.event_type == "step.delta" and getattr(event.delta, "text", None):
print(event.delta.text, end="", flush=True)
except errors.ContinuationInterruptedError as err:
# Resuming from a mid-segment checkpoint regenerates any output yielded
# after that checkpoint.
if err.interaction_id and err.continuation_token:
resumed_stream = client.interactions.create(
model="gemini-4-hydrogen",
previous_interaction_id=err.interaction_id,
continuation_token=err.continuation_token,
stream=True,
store=True,
generation_config={"max_output_tokens": 256000, "thinking_level": "high"},
)
for event in resumed_stream:
if event.event_type == "step.delta" and getattr(event.delta, "text", None):
print(event.delta.text, end="", flush=True)
REST (Streaming checkpoints)
# Start a streaming interaction; save interaction.id from interaction.created
# and the latest continuation_token from interaction.status_update SSE events
curl -N -X POST \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" \
"https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/interactions" \
-d '{
"model": "gemini-4-hydrogen",
"stream": true,
"store": true,
"input": "Write a complete formal proof of the prime number theorem.",
"generation_config": {
"max_output_tokens": 256000,
"thinking_level": "high"
}
}'
# Resume a dropped stream from the last saved checkpoint continuation_token
# (for store=false, resend the original input instead of previous_interaction_id)
curl -N -X POST \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" \
"https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/interactions" \
-d '{
"model": "gemini-4-hydrogen",
"stream": true,
"store": true,
"previous_interaction_id": "SEGMENT_ID",
"continuation_token": "CHECKPOINT_CONTINUATION_TOKEN",
"generation_config": {
"max_output_tokens": 256000,
"thinking_level": "high"
}
}'
Use long decodes with GenerateContent
On GenerateContent (v1beta1), set max_output_tokens greater than 65,536
(up to 1,048,576) for streaming or non-streaming requests. The
Google Gen AI SDK automatically follows
continuation_token across segments when finish_reason is CONTINUATION
(set automatic_continuation=False in GenerateContentConfig to opt out), or
you can pass continuation_token in a custom loop:
Python (SDK - Recommended)
from google import genai
from google.genai import types
client = genai.Client(enterprise=True, project="PROJECT_ID", location="global")
# Automatic continuation is enabled by default in google-genai >= 2.30.1.
# Chunks across all continuation requests are yielded as a single stream.
for chunk in client.models.generate_content_stream(
model="gemini-4-hydrogen",
contents="Write a complete formal proof of the prime number theorem.",
config=types.GenerateContentConfig(
max_output_tokens=256000,
thinking_config=types.ThinkingConfig(thinking_level="HIGH"),
),
):
print(chunk.text, end="")
# Set automatic_continuation=False to disable automatic continuation.
for chunk in client.models.generate_content_stream(
model="gemini-4-hydrogen",
contents="Write a complete formal proof of the prime number theorem.",
config=types.GenerateContentConfig(
thinking_config=types.ThinkingConfig(thinking_level="HIGH"),
automatic_continuation=False,
),
):
print(chunk.text, end="")
REST (Custom continuation loop)
# Request 1: Initial request with maxOutputTokens > 65,536
curl -s -X POST \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" \
"https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/publishers/google/models/gemini-4-hydrogen:generateContent" \
-d '{
"contents": [{
"role": "user",
"parts": [{"text": "Write a complete formal proof of the prime number theorem."}]
}],
"generationConfig": {
"maxOutputTokens": 131072,
"thinkingConfig": {"thinkingLevel": "HIGH"}
}
}'
# Request 2: Resend the original request with top-level continuationToken
# from Request 1 (candidates[0].continuationToken)
curl -s -X POST \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" \
"https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/publishers/google/models/gemini-4-hydrogen:generateContent" \
-d '{
"contents": [{
"role": "user",
"parts": [{"text": "Write a complete formal proof of the prime number theorem."}]
}],
"continuationToken": "CONTINUATION_TOKEN",
"generationConfig": {
"maxOutputTokens": 131072,
"thinkingConfig": {"thinkingLevel": "HIGH"}
}
}'
Mandatory API rules and behavioral conventions
Hydrogen enforces the conventions in the following sections for thinking levels, token limits, caching, generation parameters, and multi-turn tool execution.
Thinking levels
Hydrogen supports four thinking_level values
(thinking_budget and MINIMAL return an HTTP 400 validation error). The
following table lists each thinking level and its recommended workloads:
| Thinking level | Recommended workloads |
|---|---|
XHIGH |
Deep reasoning, mathematical proofs, scientific analysis, and the most complex multi-file software engineering tasks. |
HIGH (default on gemini-4-hydrogen) |
Multi-step agentic tool loops, code generation, architectural refactoring, and complex multimodal analysis. |
MEDIUM |
General coding, tool use, document Q&A, and video understanding with balanced latency. |
LOW |
High-throughput classification, routing, summarization, and structured metadata extraction. |
Token limits, caching, and billing
Hydrogen applies the following token, caching, media, and billing rules:
- Unified input and output token limit and single-request output limits:
Token budgets and per-request limits work as follows:
- The overall token limit of the model is
1,048,576tokens and includes both input and output tokens (where output includes thinking, function calls, and the final response).max_output_tokenscontrols the output token cap for the generation (up to1,048,576minus your input tokens); settingmax_output_tokensgreater than1,048,576returns an HTTP400error. - To avoid unintended long completions, the default output budget and single-segment foreground limit (thinking, function calls, and model response) is 65,536 tokens for both streaming and non-streaming requests.
- Reasoning tokens generated at
HIGH(default) andXHIGHcount towardmax_output_tokensand accumulate in multi-turn context when you preserve thought signatures across turns. Setmax_output_tokenshigh enough for both thinking and final output, avoid overly low context-compaction thresholds in multi-turn coding harnesses, or setthinking_level="MEDIUM"on latency-sensitive tool turns.
- The overall token limit of the model is
- Long decodes: Single-segment foreground responses generate up to 65,536
output tokens (streaming or non-streaming). To extend single-turn output up
to 1,048,576 tokens (minus input tokens) on the
Interactions API or
GenerateContent(v1beta1), see Long decodes. - Context caching: Explicit context caching isn't supported. Implicit caching (with durable caching enabled by default) applies automatically to shared prompt prefixes of 4,096 tokens or more, so put static content at the start of your prompt.
- Office and OpenDocument inputs: Pass Word
(
application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.openxmlformats-officedocument.wordprocessingml.template,application/msword,application/vnd.oasis.opendocument.text), PowerPoint (application/vnd.openxmlformats-officedocument.presentationml.presentation,application/vnd.ms-powerpoint,application/vnd.oasis.opendocument.presentation), and Excel or OpenDocument spreadsheet (application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel,application/vnd.oasis.opendocument.spreadsheet) files inline or by Cloud Storage URI (gs://) usinginlineDataorfileDataonGenerateContent(including insideFunctionResponseparts) anddocumentinputs (including tool results) on the Interactions API. - Agentic video: Uploaded videos default to
media_processing="static". Setmedia_processing="agentic"to enable agentic video processing. - Token counting and billing: 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.
Parameters, function calling, and chat validation
Hydrogen enforces the following rules for generation parameters, tool calls, thought signatures, and chat history:
- Ignored sampling parameters (
temperature,top_k,top_p): The backend ignores custom values. Control reasoning depth withthinking_level, and output format withresponse_schema. - Unsupported parameters (
frequency_penalty,presence_penalty, andcandidate_countgreater than1): Passingfrequency_penalty,presence_penalty, orcandidate_countgreater than1(candidateCountis fixed at1) returns an HTTP400error. Remove these parameters from your requests. Function calling and thought signatures: Tool declarations, parallel tool calls, and multi-turn
thought_signaturereplay follow these rules:- Turn symmetry: Each
FunctionResponsemust match theid,name, and order of the precedingFunctionCall. - Multimodal
FunctionResponseparts: Include Office documents, spreadsheets, presentations, PDFs, images, audio, and video inside multimodalFunctionResponseparts (or tool results on the Interactions API) rather than appending them as separate user-turn parts. - Parallel function call
thought_signatureplacement: When the model emits multiple parallelfunctionCallparts in a singlemodelturn, only the firstfunctionCallpart contains thethought_signature. Omittingthought_signaturefrom the firstfunctionCallpart in the active user turn, duplicating it onto subsequent parallelfunctionCallparts, or interleavingfunctionCallandfunctionResponseturns returns an HTTP400error; keep all parallelfunctionCallparts in a singlemodelturn followed by all matchingfunctionResponseparts in a singleuserturn. For details, see Thought signatures. - Prompt-prefix binding (
prefix_mismatch_behavior): Inputthought_signatureparts are cryptographically bound to the conversation prefix (system_instruction,tools, and priorcontents). By default (prefix_mismatch_behavior="ERROR"), modifying earlier turns or system instructions on a same-model replay returns an HTTP400(INVALID_ARGUMENT) error (signatures generated by a different model, such asgemini-4-carbonorgemini-4-argon, are dropped automatically). If your agent harness compacts, prunes, or edits earlier conversation history, setprefix_mismatch_behavior="DROP"inThinkingConfig(orgeneration_config.prefix_mismatch_behavior="drop"on the Interactions API) so the server drops prefix-mismatchedthought_signaturevalues while retaining visible text,function_call, and media parts. - Cross-turn
thought_signaturepreservation: Pass back everythought_signatureinside its originalPartacross all previous turns in multi-turn chat history (bothfunctionCalland finaltextparts), not only within the active user turn. Although HTTP400signature validation applies only tofunctionCallsteps within the active user turn, strippingthought_signaturevalues from earlier turns or substituting bypass values such asskip_thought_signature_validatorremoves reasoning context, degrades output quality, and can causeMALFORMED_FUNCTION_CALLfinish reasons. Pre-tool formatting: Separate inline instructions with
\n\nand avoid unstructured text before tool calls. To log intermediate state before a tool call, use a dedicated function declaration:{ "name": "update", "description": "Update working notes before tool execution", "parameters": { "type": "OBJECT", "properties": { "previous_step": {"type": "STRING"}, "plan": {"type": "STRING"}, "next_step": {"type": "STRING"} }, "required": ["previous_step", "plan", "next_step"] } }
- Turn symmetry: Each
Chat sequence validation: Multi-turn chat payloads enforce the following constraints:
- History payloads can't end with a
modelrole turn. - Prefilled model turns aren't supported.
- History payloads can't end with a
Long decodes
Long decode splits a generation up to 1,048,576 tokens (minus your input tokens)
across multiple segments on either the
Interactions API or
GenerateContent (v1beta1). On the Interactions API, each foreground
segment (stream=true or stream=false) generates up to 65,536 output tokens
and returns status="requires_continuation" with an encrypted
continuation_token, or you can set background=true (store=true) so the
server runs the continuation loop asynchronously and stores the merged output in
one Interaction. On GenerateContent, each streaming or non-streaming segment
generates up to 65,536 output tokens before emitting
finish_reason=CONTINUATION with continuation_token, continuing until
finish_reason=STOP. In Agent Studio, setting the output token limit greater
than 65,536 up to 1,048,576 handles continuation tokens automatically. For
runnable code samples, see the
Long decode quickstart examples.
When to use long decode
Most requests finish within the 65,536-token per-segment output limit. Use long
decode only when one response needs more output than that. Long decode gives the
model more room to reason; it doesn't make answers longer (use thinking_level
to control reasoning depth).
| Workload | Use long decode? | Why |
|---|---|---|
| Hard math, science, research, and formal proofs | Yes | The model can spend more than 65,536 tokens to explore and check its reasoning. |
| The hardest coding and agentic tasks | Yes | Some tasks need more than 65,536 tokens of thinking and code in one response. Most coding and agentic tasks finish under 65,536 tokens. |
| Evaluation harnesses that stop at the output limit | Yes | Long decode prevents cut-off answers when the model spends an entire 65,536-token segment on thinking. |
| Chat, Q&A, summarization, classification, and extraction | No | These tasks finish well under 65,536 tokens. |
| Requests for a fixed length, such as "write a 700,000-word book" | No | The model doesn't follow length targets. |
| Agents that call tools in many short turns | No | Each turn is short. Large outputs on each turn fill the unified 1,048,576-token input and output limit quickly. |
| Prompts near the 1,048,576-token input limit | No | Output can use only 1,048,576 tokens minus your input. |
| Latency-sensitive requests | No | Long decode can run for several minutes. |
Choose a continuation option
Select a continuation pattern based on your API surface, storage posture, and
runtime environment. All options in the following table reach the same
1,048,576-token limit (minus input tokens) on gemini-4-hydrogen.
| Continuation option | API surface | Who starts each segment | Tokens per segment | Time limit per request | Server storage | Best for |
|---|---|---|---|---|---|---|
| Google Gen AI SDK automatic continuation (recommended) | Interactions API (v1beta1) |
Google Gen AI SDKs: Python (google-genai >= 2.34.0), JavaScript/TypeScript (@google/genai >= 2.32.0), Go (>= 1.77.0), and Java (>= 1.80.0) |
Up to 65,536 (stream=true or stream=false) |
20 minutes per segment | 7-day server storage by default (store=true), or none (store=false) |
Most stateful or stateless Interactions API applications |
Background server-managed loop (background=true) |
Interactions API (v1beta1) |
Agent Platform server loop; your code polls get |
Managed server-side up to max_output_tokens |
Asynchronous (no open client stream required) | 7-day server storage (store=true required) |
Asynchronous jobs, .NET/Kotlin callers, and single-record persistence |
Custom foreground stored loop (store=true) |
Interactions API (v1beta1) |
Your code (previous_interaction_id + continuation_token, no input) |
Up to 65,536 (stream=true or stream=false; checkpoints starting at 65,536 and every 5,000 tokens thereafter) |
20 minutes per segment | 7-day server storage (store=true) |
REST callers and custom checkpoint recovery |
Custom foreground stateless loop (store=false) |
Interactions API (v1beta1) |
Your code (original input + continuation_token, no previous_interaction_id) |
Up to 65,536 (stream=true or stream=false; checkpoints starting at 65,536 and every 5,000 tokens thereafter) |
20 minutes per segment | No server storage (Zero Data Retention workflows) | Custom REST harnesses requiring stateless execution |
| Google Gen AI SDK automatic continuation (recommended) | GenerateContent (v1beta1) |
Google Gen AI SDKs: Python (>= 2.30.1), JavaScript/TypeScript (>= 2.29.1), Go (>= 1.74.0), Java (>= 1.77.0), .NET (>= 1.26.0), and Kotlin (>= 1.6.0) |
Up to 65,536 (generate_content_stream or generate_content) |
20 minutes per segment | No server storage (Zero Data Retention workflows) | Existing GenerateContent applications |
| Custom continuation loop | GenerateContent (v1beta1) |
Your code (original contents + continuation_token) |
Up to 65,536 (streamGenerateContent or generateContent; checkpoints starting at 65,536 and every 5,000 tokens thereafter) |
20 minutes per segment | No server storage (Zero Data Retention workflows) | Direct REST GenerateContent callers and evaluation harnesses |
API version and SDK requirements
Long decodes require the following API version and minimum SDK versions:
v1beta1API requirement (known issue): Long decoding (continuation_token) on both the Interactions API andGenerateContent(generateContentandstreamGenerateContent) is supported only in thev1beta1API (notv1) on Agent Platform. The Google Gen AI SDK usesv1beta1by default unlessapi_version='v1'is specified inhttp_options(orapi_version="v1"oninteractions.create); for direct REST calls, use the/v1beta1/endpoint path.- SDK versions and OpenAI compatibility: For automatic
continuation on the Interactions API, upgrade to Python
google-genai >= 2.34.0, JavaScript/TypeScript@google/genai >= 2.32.0, Go>= 1.77.0, or Java>= 1.80.0(for .NET and Kotlin on the Interactions API, usebackground=trueor a custom continuation loop). For automatic continuation onGenerateContent, upgrade to Python>= 2.30.1, JavaScript/TypeScript>= 2.29.1, Go>= 1.74.0, Java>= 1.77.0, .NET>= 1.26.0, or Kotlin>= 1.6.0. Earlier SDK versions and the OpenAI compatibility layer can't retrieve long completions using continuation tokens.
Interactions API continuation rules
The following status transitions, chaining rules, and storage behaviors apply to long decodes on the Interactions API.
Status values and output token budget
When generation_config.max_output_tokens is omitted on an
Interactions API request, the total output budget defaults to 65,536
tokens (matching the 65,536-token single-segment foreground limit for both
streaming and non-streaming requests). Set
generation_config.max_output_tokens greater than 65,536 (up to 1,048,576
minus input tokens) for multi-segment long decodes in both foreground and
background=true modes. The server returns the following status values:
requires_continuation: The 65,536-token per-segment output limit was reached beforemax_output_tokens; pass the returnedcontinuation_tokenon the next request to continue decoding.incomplete: The totalmax_output_tokensbudget was exhausted; continuing withcontinuation_tokenwithout raisingmax_output_tokensreturns an HTTP400error (max_output_tokens has already been exhausted). Increasemax_output_tokenson the next request to resume decoding.completed: Generation finished naturally andcontinuation_tokenis cleared.
Chaining, mode switching, and segment storage
Continuation requests on the Interactions API enforce the following rules:
- Stored continuation (
store=true, default): Passprevious_interaction_idset to the segmentidthat issued thecontinuation_tokenalong withcontinuation_token, and omitinput(the stored segment already holds the turn input). Always pair eachcontinuation_tokenwith theprevious_interaction_idof the segment that issued it; passing acontinuation_tokenon an alreadycompletedinteraction returns an HTTP400error. - Stateless continuation (
store=false): Omitprevious_interaction_idand resend the originalinputalongsidecontinuation_tokenon every segment. - Switching
storemodes across segments: You can switch from stored (store=true) to stateless (store=false) mid-decode by omittingprevious_interaction_idand resending the originalinputwithcontinuation_token. Switching from stateless (store=false) to stored (store=true) isn't supported because no stored parent interaction exists forprevious_interaction_id. - Foreground and
background=truemode switching and branching: Stored continuations (store=true) can switch between foreground (background=false) and background (background=true) execution across segments, including resuming a cancelledbackground=trueinteraction from its checkpointcontinuation_token(persisted starting at 65,536 output tokens and every 5,000 tokens thereafter) in either background or foreground mode. Reusing the sameprevious_interaction_idandcontinuation_tokencreates independent branched continuations. - Turn-boundary enforcement: Starting a new user turn
(
previous_interaction_idwith newinputand nocontinuation_token) from a segment whose status isrequires_continuationorincompletereturns an HTTP400error. Finish continuing the decode tocompleted, or branch your next turn from the most recentcompletedinteraction. Once the final segment reachescompleted, passing that final segment'sidasprevious_interaction_idreconstructs the full conversation history across all prior segments. - Parameter consistency across segments: Changing
model,system_instruction, or function declarations (tools) on a continuation segment returns an HTTP400error. Keepthinking_leveland built-in tools unchanged across segments as well (see Known issues). - Single-segment
get,list, anddeletebehavior: In foreground mode (background=false), each segment is stored as a separateInteractionresource (interactions.get(id)returns only that segment,interactions.list()lists each segment separately, andinteractions.delete(id)deletes only that segment; when deleting a chain of segments, delete in reverse order from the last segment backward). In the Google Gen AI SDK withautomatic_continuation=True(stream=False),interactions.create()merges all segments on return and populatesinteraction.continuation_idswith the ordered segment IDs (ending withinteraction.id). If a later segment fails, exceeds a numeric per-calltimeout, or drops mid-stream after progress was made past a resumable checkpoint, the SDK raisesContinuationInterruptedErrorcarryingpartial_interaction,continuation_token,interaction_id, andcontinuation_idsso you can resume fromcontinuation_token.
GenerateContent custom loop rules
In a custom GenerateContent continuation loop, follow these rules:
- Set
max_output_tokensgreater than 65,536 (up to 1,048,576), and resend the originalcontents,system_instruction, andtoolson every continuation request along with the latestcontinuation_token(a top-level field onGenerateContentRequestin REST, or inGenerateContentConfigin the Google Gen AI SDK). - Don't append partial model output into
contentsor send a follow-up prompt asking the model to continue. - Continue looping as long as
finish_reasonisCONTINUATIONandcontinuation_tokenis present, even if a segment spent all 65,536 tokens on thinking (parts: [{"text": ""}]). Iffinish_reasonisMAX_TOKENSwhencontinuation_tokenis present, raisemax_output_tokensin the next request. - Combine accumulated parts into a single
modelturn for multi-turn history only afterSTOP.
Token counting, compaction, and implicit caching
Token accounting and caching across continuation segments work as follows:
- On the Interactions API, non-streaming
interactions.create()calls withautomatic_continuation=Trueand server-managedbackground=trueinteractions sum token counts across all segments inusage(total_input_tokens,total_cached_tokens,total_output_tokens,total_thought_tokens,total_tokens), preserving the first segment's prompt count inusage.initial_input_tokens. In custom foreground loops and streamedinteraction.completedevents, each segment'susagereports only that segment's delta, so sumusagefields across segments for total billed tokens. - On
GenerateContent, the Python Google Gen AI SDK (generate_contentandgenerate_content_stream) accumulates total billed tokens across segments in the finalusage_metadataand preservesinitial_prompt_token_count. In custom REST loops, sum the finalprompt_token_count,cached_content_token_count,candidates_token_count, andthoughts_token_countacross segments. - Because each foreground continuation segment re-prefills the conversation
and previously generated tokens as input,
usage.total_input_tokens(on the Interactions API) andprompt_token_count(onGenerateContent) increase across segments. Don't use cumulative input counts to trigger context compaction in agent harnesses; instead, checkusage.initial_input_tokens(orinitial_prompt_token_countonGenerateContent) and compact only after the turn finishes (status="completed"or nocontinuation_token). - Each continuation segment re-prefills the prompt plus previously decoded tokens and automatically qualifies for implicit context caching (4,096-token minimum, with durable caching enabled by default) when segments run back-to-back. Completed segments are billed at the end of each segment even if a later segment fails or is cancelled.
Migrate to Hydrogen from 3.8 Flash
The following behavior is different from gemini-3.8-flash and
earlier Gemini 3 Flash models:
- Hydrogen has a unified 1,048,576-token limit across
input and output (where output includes thinking, function calls, and the
final response), instead of separate input and output limits. Single-segment
foreground output is capped at 65,536 tokens (streaming or non-streaming),
and can be extended up to 1,048,576 tokens using long decodes
on the Interactions API or
GenerateContent(handled automatically in the Google Gen AI SDK, withbackground=trueon the Interactions API, or usingcontinuation_tokenin custom loops). - The default
thinking_levelisHIGH(changed fromMEDIUMongemini-3.8-flash), andXHIGHis supported for deep reasoning tasks (leave context-compaction headroom forHIGHandXHIGHreasoning traces in multi-turn coding harnesses, or setMEDIUMon latency-sensitive turns).thinking_budgetandthinking_level="MINIMAL"return an HTTP400error. - Explicit context caching (
cached_content) isn't supported. Implicit caching applies automatically at a 4,096-token minimum (reduced from 6,144 tokens ongemini-3.8-flash), with durable caching enabled by default. - Microsoft Office (
.docx,.dotx,.doc,.pptx,.ppt,.xlsx,.xls) and OpenDocument (.odt,.odp,.ods) files are supported inline or by Cloud Storage URI (gs://), including inside multimodalFunctionResponseparts. - Parallel function-calling turns enforce strict
thought_signatureplacement (only the firstfunctionCallpart in a parallel turn carriesthought_signature; omitting it in the active turn or duplicating it onto subsequent siblingfunctionCallparts returns an HTTP400error), and same-model prompt-prefix edits fail with HTTP400by default unlessprefix_mismatch_behavior="DROP"is set inThinkingConfig. Preservethought_signatureparts across all previous turns as well (bothfunctionCalland finaltextparts) to maintain reasoning quality and avoidMALFORMED_FUNCTION_CALLfinish reasons. - Every token the model processes is billed, including internal tool system instructions and function declarations when using grounding.
For a side-by-side comparison, see Migrate from Gemini 3 models.
client = genai.Client(
enterprise=True,
project="PROJECT_ID",
location="global", # Supports "global", "us", and "eu"
)
response = client.models.generate_content(
- model="gemini-3.8-flash",
+ model="gemini-4-hydrogen",
contents=prompt,
config=types.GenerateContentConfig(
- temperature=0.0,
- cached_content="projects/.../cachedContents/...", # Explicit caching unsupported
thinking_config=types.ThinkingConfig(
- thinking_budget=16384, # Returns HTTP 400 instead of mapping silently
- thinking_level="MINIMAL", # MINIMAL unsupported on Gemini 4 Hydrogen
+ thinking_level="HIGH", # Valid: "LOW", "MEDIUM", "HIGH" (default), "XHIGH"
+ # prefix_mismatch_behavior="DROP", # Optional: set if compacting or editing prior history
),
),
)
To migrate from gemini-3.8-flash or earlier
Gemini 3 Flash models, do the following:
- Update the model ID to
gemini-4-hydrogen. - Upgrade to the latest Google Gen AI SDK and account for the unified
input and output token limit: Upgrade to
google-genai >= 2.34.0(Python),@google/genai >= 2.32.0(JavaScript/TypeScript), Go>= 1.77.0, or Java>= 1.80.0for Interactions API automatic continuation (or>= 2.30.1Python />= 2.29.1JavaScript onGenerateContent). Input and output tokens (including thinking and function calls) share the unified 1,048,576-token limit. For outputs exceeding 65,536 tokens (up to 1,048,576 tokens) on the Interactions API orGenerateContent, setmax_output_tokensgreater than 65,536 so the Google Gen AI SDK continues automatically across segments (or usebackground=trueor a customcontinuation_tokenloop). - Update
thinking_levelconfiguration: Replacethinking_budgetandMINIMALwiththinking_levelset toLOW,MEDIUM,HIGH(default ongemini-4-hydrogen), orXHIGH(use lowercase"low","medium","high", or"xhigh"on the Interactions API). If your workload relied onMEDIUMas the default ongemini-3.8-flash, explicitly setthinking_level="MEDIUM"to keep equivalent reasoning latency. - Remove explicit caching and front-load static prompt content (4,096 tokens or more) for automatic implicit caching.
- Verify multi-turn and parallel
thought_signaturepreservation and prefix compaction: Preservethought_signatureacross all previous turns (bothfunctionCalland finaltextparts) rather than stripping signatures between turns, keepthought_signatureonly on the firstfunctionCallpart of a parallel tool-calling turn, and setprefix_mismatch_behavior="DROP"inThinkingConfigif your application modifies or compacts earlier turns in multi-turn chat history. - Remove parameters that have no effect or aren't supported: Remove
ignored and rejected generation fields as follows:
- Remove
temperature,top_p, andtop_k, which are ignored. - Remove
frequency_penalty,presence_penalty, and anycandidate_countvalue greater than1. - Remove any prefilled model turns from conversation histories.
- Remove
Summary checklist for developers
Use the following checklist to verify your Hydrogen integration:
Known issues
The following known issues apply to Hydrogen long decodes:
- Long decodes require
v1beta1: Long decoding (continuation_token) on both the Interactions API and theGenerateContentAPI (generateContentandstreamGenerateContent) is supported only in thev1beta1API (notv1) on Agent Platform. The Google Gen AI SDK usesv1beta1by default unlessapi_version='v1'is set inhttp_options(orapi_version="v1"oninteractions.create); for direct REST calls, use the/v1beta1/endpoint path. - Parameter changes across Interactions API continuation
segments: Changing
model,system_instruction, or function declarations across continuation segments returns an HTTP400error, whereas mid-decode changes togeneration_config.thinking_levelor built-in tools (google_search,code_execution,url_context) aren't rejected by server validation. Keepthinking_leveland built-in tools unchanged across all segments of a continuation loop.
Additional resources
For more information about Hydrogen, see the following resources: