Gemini 4 Carbon is Google's frontier model that excels at deep work in complex, real-world tasks across domains including coding, finance, legal, cybersecurity, and science. It's part of the Gemini 4 family.
This document covers the key capabilities of 4 Carbon, the API conventions it enforces, how to migrate to it, and a quickstart. For an overview of the Gemini 4 family, see Get started with Gemini 4.
Key capabilities in Gemini 4 Carbon
Gemini 4 Carbon includes the following capabilities:
- Unified input and output token limit: 4 Carbon 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: 4 Carbon
extends generation beyond a single foreground segment (65,536 tokens when
streaming, or 32,768 tokens when 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: 4 Carbon supports
LOW,MEDIUM(default ongemini-4-carbon), andHIGH(default ongemini-4-carbon-cyber-permissive). - 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,
4 Carbon 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. - Agentic video understanding: Agentic video understanding is generally available and off by default.
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-carbon in the
Agent Studio
UI, do the following:
- Open Agent Studio
in your Google Cloud project and select
gemini-4-carbonunder the Gemini group. - In Model settings, configure the following options:
- Thinking level: Choose
Low,Medium(default), orHigh. - 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-carbon 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-carbon",
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="MEDIUM", # Default: "MEDIUM" (Valid: "LOW", "MEDIUM", "HIGH")
),
),
)
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-carbon",
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-carbon",
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-carbon:generateContent" \
-d '{
"contents": [
{
"role": "user",
"parts": [
{
"text": "Provide an architectural review of this Go interface."
}
]
}
],
"generationConfig": {
"thinkingConfig": {
"thinkingLevel": "MEDIUM"
}
}
}'
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-carbon",
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
when streaming or 32,768 output tokens when 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-carbon",
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}")
# 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)
# Streaming yields events across all segments in order. Intermediate segments
# emit interaction.completed with status="requires_continuation".
stream = client.interactions.create(
model="gemini-4-carbon",
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}")
# Set automatic_continuation=False to return after a single segment.
single_segment = client.interactions.create(
model="gemini-4-carbon",
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-carbon",
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-carbon",
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 (leaving default automatic_continuation=True lets the SDK finish remaining segments).
if segment.status == "incomplete" and segment.continuation_token:
segment = client.interactions.create(
model="gemini-4-carbon",
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-carbon",
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-carbon",
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-carbon",
"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-carbon",
"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-carbon",
"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-carbon",
"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 at 32,768 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-carbon",
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 >= 32,768 tokens decoded).
# cancelled = client.interactions.cancel(id=interaction.id)
# if cancelled.continuation_token:
# resumed = client.interactions.create(
# model="gemini-4-carbon",
# 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-carbon",
"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-carbon",
"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 (32,768
# 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-carbon",
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-carbon",
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-carbon",
"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-carbon",
"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
for streaming requests or greater than 32,768 for non-streaming requests (up to
1,048,576). 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-carbon",
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-carbon",
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 > 32,768
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-carbon: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-carbon: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
4 Carbon enforces the conventions in the following sections for thinking levels, token limits, caching, generation parameters, and multi-turn tool execution.
Thinking levels
4 Carbon supports three thinking_level values
(thinking_budget and MINIMAL return an HTTP 400 validation error). Pass
uppercase values ("LOW", "MEDIUM", "HIGH") on GenerateContent and
lowercase values ("low", "medium", "high") on the
Interactions API. The following table lists each thinking level and its
recommended workloads:
| Thinking level | Recommended workloads |
|---|---|
HIGH (default on gemini-4-carbon-cyber-permissive) |
Multi-file software engineering, formal proofs, architecture design, and vulnerability discovery. |
MEDIUM (default on gemini-4-carbon) |
General coding, tool use, document Q&A, and video understanding. |
LOW |
Classification, summarization, and metadata extraction. |
Token limits, caching, and billing
4 Carbon applies the following token, caching, media, and billing rules:
- Unified input and output token limit and default output budgets:
Token budgets and foreground segment 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. - When
max_output_tokensis omitted onGenerateContentor the Interactions API, the default total output budget (thinking, function calls, and response) is 65,536 tokens. Because a single foreground segment generates up to 65,536 tokens when streaming or 32,768 tokens when non-streaming, the Google Gen AI SDK (v1beta1) automatically chains two 32,768-token segments on non-streaming calls when needed, whereas a single non-streaming REST request stops after one 32,768-token foreground segment. In Agent Studio, the output token limit defaults to1,048,576with automatic continuation.
- The overall token limit of the model is
- Long decodes: A single foreground segment generates up to 65,536 output
tokens when streaming or 32,768 output tokens when 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://) usinginlineDataorfileDataonGenerateContentanddocumentinputs (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
4 Carbon enforces the following rules for generation parameters, tool calls, 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: Tool declarations and execution turns follow these rules:
- Turn symmetry: Each
FunctionResponsemust match theid,name, and order of the precedingFunctionCall. - Sequential execution: Prefer sequential tool execution turns in multi-step tool loops.
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 generates up to 65,536 output tokens when streaming (stream=true) or
32,768 output tokens when non-streaming (stream=false) 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, streaming segments generate up to 65,536 output tokens and
non-streaming segments generate up to 32,768 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 default output budget (or a single
32,768-token non-streaming foreground segment over REST). 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- or 32,768-token request on thinking. |
| Chat, Q&A, summarization, classification, and extraction | No | These tasks finish well under 32,768 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-carbon
and gemini-4-carbon-cyber-permissive.
| 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 32,768 (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, callers in other languages over REST, 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, checkpoints every 5,000 tokens after 32,768) or 32,768 (stream=false) |
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, checkpoints every 5,000 tokens after 32,768) or 32,768 (stream=false) |
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 32,768 (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, checkpoints every 5,000 tokens after 32,768) or 32,768 (generateContent) |
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 other languages on the Interactions API, call the REST API directly withbackground=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 (so a non-streaming call stops at 32,768 tokens with
status="requires_continuation", and a second segment can generate the
remaining 32,768 tokens). Set generation_config.max_output_tokens up to
1,048,576 (minus input tokens) for longer decodes in both foreground and
background=true modes. The server returns the following status values:
requires_continuation: The per-segment output limit (32,768 non-streaming or 65,536 streaming) 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 after 32,768 output tokens) 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 (streaming) or 32,768 (non-streaming) 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 32,768 or 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 4 Carbon from 3.1 Pro
The following behavior is different from gemini-3.1-pro-preview:
- 4 Carbon 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. A single
foreground segment is capped at 65,536 tokens when streaming (or 32,768
tokens when non-streaming), and output 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). thinking_budgetreturns an HTTP400error instead of being mapped to a thinking level.MINIMALalso returns an error.- Explicit context caching isn't supported.
- 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.1 Pro.
client = genai.Client(
enterprise=True,
project="PROJECT_ID",
location="global", # Supports "global", "us", and "eu" ("global" and "us" for cyber)
)
response = client.models.generate_content(
- model="gemini-3.1-pro-preview",
+ model="gemini-4-carbon",
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 Carbon
+ thinking_level="MEDIUM", # Valid: "LOW", "MEDIUM" (default), "HIGH"
),
),
)
To migrate from gemini-3.1-pro-preview, do the following:
- Update the model ID to
gemini-4-carbon(orgemini-4-carbon-cyber-permissivefor cybersecurity workloads approved through the Fairwind Program). - 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). - Replace the reasoning budget parameter: Replace
thinking_budgetandMINIMALwiththinking_levelset toLOW,MEDIUM(default ongemini-4-carbon), orHIGH(default ongemini-4-carbon-cyber-permissive) (use lowercase"low","medium", or"high"on the Interactions API). - Remove explicit caching and front-load static prompt content (4,096 tokens or more) for automatic implicit caching.
- 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 4 Carbon integration:
Known issues
The following known issues apply to 4 Carbon 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 4 Carbon, see the following resources:
- Gemini 4 Carbon model page
- Get started with Gemini 4
- Introductory notebook
- Gemini 4 Carbon for cyber