Google's official model page marks Structured outputs as Supported for the stable gemini-3.8-flash; the structured output documentation gives the exact model configuration as response_format: type="text", mime_type="application/json", with the JSON Schema placed in schema. This constrains JSON syntax and shape, but the application must still validate field semantics and handle cases where the schema is too large, too deeply nested, or unsupported.
Suitable tasks: Information extraction, fixed-enum classification, structured summarization, preparing typed inputs for downstream APIs, and tasks that require streaming JSON fragments.
Unsuitable tasks: Treating valid JSON as proof of factual correctness or authorization for a safety-sensitive action; fields generated by the model remain untrusted input and cannot bypass business validation, permissions, or human confirmation.
Applicable model version: The stable gemini-3.8-flash; the API model ID corresponds exactly to the model string in the official code.
Applicable client, agent, or API: The Google Gemini API's Interactions API. The Google GenAI SDK supports defining schemas with Pydantic (Python) and Zod (JavaScript); other SDKs, agent frameworks, or third-party platforms must verify the field mapping themselves.
Output notes: The model page lists the output modality as Text; structured JSON is returned through the text response and should not be misunderstood as a standalone JSON output modality.
The core schema, model ID, and request fields from Google's structured output example are retained below; Recipe.model_json_schema() generates the JSON Schema through Pydantic, while model_validate_json parses and validates the returned value on the application side.
from google import genai
from pydantic import BaseModel, Field
from typing import List, Optional
class Ingredient(BaseModel):
name: str = Field(description="Name of the ingredient.")
quantity: str = Field(description="Quantity of the ingredient, including units.")
class Recipe(BaseModel):
recipe_name: str = Field(description="The name of the recipe.")
prep_time_minutes: Optional[int] = Field(
description="Optional time in minutes to prepare the recipe."
)
ingredients: List[Ingredient]
instructions: List[str]
client = genai.Client()
prompt = """
Please extract the recipe from the following text.
The user wants to make delicious chocolate chip cookies.
They need 2 and 1/4 cups of all-purpose flour, 1 teaspoon of baking soda,
1 teaspoon of salt, 1 cup of unsalted butter (softened), 3/4 cup of granulated sugar,
3/4 cup of packed brown sugar, 1 teaspoon of vanilla extract, and 2 large eggs.
For the best part, they'll need 2 cups of semisweet chocolate chips.
First, preheat the oven to 375°F (190°C). Then, in a small bowl, whisk together the flour,
baking soda, and salt. In a large bowl, cream together the butter, granulated sugar, and brown sugar
until light and fluffy. Beat in the vanilla and eggs, one at a time. Gradually beat in the dry
ingredients until just combined. Finally, stir in the chocolate chips. Drop by rounded tablespoons
onto ungreased baking sheets and bake for 9 to 11 minutes.
"""
interaction = client.interactions.create(
model="gemini-3.8-flash",
input=prompt,
response_format={
"type": "text",
"mime_type": "application/json",
"schema": Recipe.model_json_schema()
},
)
recipe = Recipe.model_validate_json(interaction.output_text)
print(recipe)When not using Pydantic, pass the schema directly while keeping the official request fields unchanged:
response_format = {
"type": "text",
"mime_type": "application/json",
"schema": {
"type": "object",
"properties": {
"label": {
"type": "string",
"enum": ["positive", "neutral", "negative"],
"description": "The classification label."
},
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "A confidence score between 0 and 1."
}
},
"required": ["label", "confidence"],
"additionalProperties": False
}
}
interaction = client.interactions.create(
model="gemini-3.8-flash",
input="Classify the sentiment of: The new UI is incredibly intuitive.",
response_format=response_format,
)The official example creates a stream with stream=True; the text block in each step.delta is a valid, concatenable JSON fragment. Do not treat the first fragment received as a complete object; concatenate the fragments after the stream ends and perform final schema validation.
from pydantic import BaseModel
from typing import Literal
class Feedback(BaseModel):
sentiment: Literal["positive", "neutral", "negative"]
summary: str
stream = client.interactions.create(
model="gemini-3.8-flash",
input="The new UI is incredibly intuitive. Add a very long summary to test streaming!",
response_format={
"type": "text",
"mime_type": "application/json",
"schema": Feedback.model_json_schema()
},
stream=True
)
for event in stream:
if event.event_type == "step.delta":
if event.delta.type == "text" and getattr(event.delta, "text", None):
print(event.delta.text, end="", flush=True)Google's documentation explicitly states that this is a subset of JSON Schema. The following are currently available:
| Category | Supported items |
|---|---|
| Basic types | string, number, integer, boolean, object, array, null |
| Descriptive properties | title, description |
| Objects | properties, required, additionalProperties |
| Strings | enum, format (such as date-time, date, time) |
| Numbers | enum, minimum, maximum |
| Arrays | items, prefixItems, minItems, maxItems |
When null values are allowed, include null in the type array, for example {"type": ["string", "null"]}. The description in a schema guides the model; it is not application-layer data validation or an authorization rule.
Structured outputs: Formats the final answer; suitable for tasks that require a fixed structure in the final result.
Function calling: Proposes functions and arguments to execute during a conversation; the application is responsible for validating, executing, and returning the result.
Structured output + built-in tools: Google's documentation marks this combination as Preview, and the example uses a Gemini 3 series model; do not rewrite the documentation's gemini-3.1-pro-preview example as a tool guarantee specific to 3.8. The Gemini 3.8 Flash model page lists Structured outputs, Function calling, and search capabilities separately, but whether they can be used in the target account, SDK version, and specific tool combination still requires real-world testing.
Fix model="gemini-3.8-flash" and first use a small object schema to verify the SDK, account, and Interactions API field mapping.
Check whether the response can be parsed as JSON, then use Pydantic, Zod, or an equivalent validator to verify types, enums, numeric ranges, required fields, and business rules.
Gradually increase nesting depth and array constraints; record schema rejections, parse failures, missing fields, and semantic errors, rather than attributing complex-schema problems to the prompt.
For streaming requests, consume only the text incrementally, then concatenate and validate the complete JSON after the stream ends; when it fails, retain a diagnosable error state and do not pass a partial object downstream.
If tools are enabled at the same time, validate structured output independently first, then validate tool calls; apply allowlists, permission, idempotency, and human-confirmation checks to tool parameters.
| Official page | Verifiable content | How this article uses it |
|---|---|---|
| Gemini 3.8 Flash model page | Model ID is gemini-3.8-flash; stable version; Structured outputs Supported; input token limit 1,048,576 and output token limit 65,536 | Proves the exact model and capability status; does not treat token limits as recommended per-request values |
| Structured output documentation | The Python example uses client.interactions.create, response_format, mime_type="application/json", and schema; Pydantic/Zod are supported; output can be streamed | Forms the executable configuration and streaming-processing constraints |
| JSON Schema support section in the structured output documentation | Only a subset of JSON Schema is supported, with a warning that schemas that are too large or too deeply nested may be rejected | Forms the schema-design and error-handling boundaries |
Structured outputs mainly ensure that output conforms to the syntax and declared shape; Google explicitly requires applications to validate values and implement error handling for results that conform to the schema but are semantically wrong.
“Supported” does not mean that all regions, account tiers, SDK versions, agent frameworks, or third-party routes are synchronized; conduct a real smoke test before production launch.
JSON Schema implements only the subset listed officially; do not assume that unlisted keywords are valid. Large or deeply nested schemas may be rejected.
A schema's description provides model guidance and cannot take responsibility for permissions, privacy, SQL injection protection, or business authorization.
Streaming chunks can be concatenated into final JSON, but intermediate fragments may not be complete objects; parsing and business validation must be completed after the stream ends.
Structured output and function calling solve different problems. Any write, payment, email, deletion, or device-control action must be protected by application-side permissions, auditing, and human confirmation.
Token limits, capability switches, pricing, and lifecycle on the model page may change; this article records only the official page state collected on 2026-09-08.
Google's core configuration requirement is to use the text type, set mime_type to application/json, and then provide a JSON Schema in the schema field. In engineering terms, treat it as a “validatable output contract,” not a guarantee of factual correctness or execution authority.
Gemini 3.8 Flash