Repository Public
1You can configure Gemini models to generate responses that adhere to a provided2JSON Schema. This ensures predictable, type-safe results and simplifies3extracting structured data from unstructured text.45Using structured outputs is ideal for:67- **Data extraction:** Pull specific information like names and dates from text.8- **Structured classification:** Classify text into predefined categories.9- **Agentic workflows:** Generate structured inputs for tools or APIs.1011In addition to supporting JSON Schema in the REST API, the Google GenAI SDKs12allow defining schemas using13[Pydantic](https://docs.pydantic.dev/latest/) (Python) and14[Zod](https://zod.dev/) (JavaScript).1516## Structured output examples1718### Recipe Extractor1920This example demonstrates how to extract structured data from text using basic21JSON Schema types like `object`, `array`, `string`, and `integer`.2223### Python2425 from google import genai26 from pydantic import BaseModel, Field27 from typing import List, Optional2829 class Ingredient(BaseModel):30 name: str = Field(description="Name of the ingredient.")31 quantity: str = Field(description="Quantity of the ingredient, including units.")3233 class Recipe(BaseModel):34 recipe_name: str = Field(description="The name of the recipe.")35 prep_time_minutes: Optional[int] = Field(description="Optional time in minutes to prepare the recipe.")36 ingredients: List[Ingredient]37 instructions: List[str]3839 client = genai.Client()4041 prompt = """42 Please extract the recipe from the following text.43 The user wants to make delicious chocolate chip cookies.44 They need 2 and 1/4 cups of all-purpose flour, 1 teaspoon of baking soda,45 1 teaspoon of salt, 1 cup of unsalted butter (softened), 3/4 cup of granulated sugar,46 3/4 cup of packed brown sugar, 1 teaspoon of vanilla extract, and 2 large eggs.47 For the best part, they'll need 2 cups of semisweet chocolate chips.48 First, preheat the oven to 375°F (190°C). Then, in a small bowl, whisk together the flour,49 baking soda, and salt. In a large bowl, cream together the butter, granulated sugar, and brown sugar50 until light and fluffy. Beat in the vanilla and eggs, one at a time. Gradually beat in the dry51 ingredients until just combined. Finally, stir in the chocolate chips. Drop by rounded tablespoons52 onto ungreased baking sheets and bake for 9 to 11 minutes.53 """5455 interaction = client.interactions.create(56 model="gemini-3.8-flash",57 input=prompt,58 response_format={59 "type": "text",60 "mime_type": "application/json",61 "schema": Recipe.model_json_schema()62 },63 )6465 recipe = Recipe.model_validate_json(interaction.output_text)66 print(recipe)6768### JavaScript6970 // Note: Ensure zod is installed (npm install zod)71 import { GoogleGenAI } from "@google/genai";72 import * as z from "zod";7374 const recipeJsonSchema = {75 type: "object",76 properties: {77 recipe_name: {78 type: "string",79 description: "The name of the recipe."80 },81 prep_time_minutes: {82 type: "integer",83 description: "Optional time in minutes to prepare the recipe."84 },85 ingredients: {86 type: "array",87 items: {88 type: "object",89 properties: {90 name: { type: "string", description: "Name of the ingredient."},91 quantity: { type: "string", description: "Quantity of the ingredient, including units."}92 },93 required: ["name", "quantity"]94 }95 },96 instructions: {97 type: "array",98 items: { type: "string" }99 }100 },101 required: ["recipe_name", "ingredients", "instructions"]102 };103104 const recipeSchema = z.fromJSONSchema(recipeJsonSchema);105106 const client = new GoogleGenAI({});107108 const prompt = `109 Please extract the recipe from the following text.110 The user wants to make delicious chocolate chip cookies.111 They need 2 and 1/4 cups of all-purpose flour, 1 teaspoon of baking soda,112 1 teaspoon of salt, 1 cup of unsalted butter (softened), 3/4 cup of granulated sugar,113 3/4 cup of packed brown sugar, 1 teaspoon of vanilla extract, and 2 large eggs.114 For the best part, they'll need 2 cups of semisweet chocolate chips.115 First, preheat the oven to 375°F (190°C). Then, in a small bowl, whisk together the flour,116 baking soda, and salt. In a large bowl, cream together the butter, granulated sugar, and brown sugar117 until light and fluffy. Beat in the vanilla and eggs, one at a time. Gradually beat in the dry118 ingredients until just combined. Finally, stir in the chocolate chips. Drop by rounded tablespoons119 onto ungreased baking sheets and bake for 9 to 11 minutes.120 `;121122 const interaction = await client.interactions.create({123 model: "gemini-3.8-flash",124 input: prompt,125 response_format: {126 type: 'text',127 mime_type: 'application/json',128 schema: recipeJsonSchema129 },130 });131132 const recipe = recipeSchema.parse(JSON.parse(interaction.output_text));133 console.log(recipe);134135### Java136137 import com.google.genai.Client;138 import com.google.genai.gaos.models.interactions.CreateModelInteraction;139 import com.google.genai.gaos.models.interactions.CreateModelInteractionResponseFormat;140 import com.google.genai.gaos.models.interactions.Interaction;141 import com.google.genai.gaos.models.interactions.InteractionsInput;142 import com.google.genai.gaos.models.interactions.Model;143 import com.google.genai.gaos.models.interactions.ResponseFormat;144 import com.google.genai.gaos.models.interactions.TextResponseFormat;145 import com.google.genai.gaos.models.interactions.TextResponseFormatMimeType;146 import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;147 import java.util.Arrays;148 import java.util.HashMap;149 import java.util.Map;150151 Client client = new Client();152153 Map<String, Object> ingredientProps = new HashMap<>();154 Map<String, Object> nameProp = new HashMap<>();155 nameProp.put("type", "string");156 nameProp.put("description", "Name of the ingredient.");157 ingredientProps.put("name", nameProp);158159 Map<String, Object> quantityProp = new HashMap<>();160 quantityProp.put("type", "string");161 quantityProp.put("description", "Quantity of the ingredient, including units.");162 ingredientProps.put("quantity", quantityProp);163164 Map<String, Object> ingredientItemSchema = new HashMap<>();165 ingredientItemSchema.put("type", "object");166 ingredientItemSchema.put("properties", ingredientProps);167 ingredientItemSchema.put("required", Arrays.asList("name", "quantity"));168169 Map<String, Object> properties = new HashMap<>();170171 Map<String, Object> recipeNameProp = new HashMap<>();172 recipeNameProp.put("type", "string");173 recipeNameProp.put("description", "The name of the recipe.");174 properties.put("recipe_name", recipeNameProp);175176 Map<String, Object> prepTimeProp = new HashMap<>();177 prepTimeProp.put("type", "integer");178 prepTimeProp.put("description", "Optional time in minutes to prepare the recipe.");179 properties.put("prep_time_minutes", prepTimeProp);180181 Map<String, Object> ingredientsProp = new HashMap<>();182 ingredientsProp.put("type", "array");183 ingredientsProp.put("items", ingredientItemSchema);184 properties.put("ingredients", ingredientsProp);185186 Map<String, Object> instructionsProp = new HashMap<>();187 instructionsProp.put("type", "array");188 Map<String, Object> stringItem = new HashMap<>();189 stringItem.put("type", "string");190 instructionsProp.put("items", stringItem);191 properties.put("instructions", instructionsProp);192193 Map<String, Object> recipeJsonSchema = new HashMap<>();194 recipeJsonSchema.put("type", "object");195 recipeJsonSchema.put("properties", properties);196 recipeJsonSchema.put("required", Arrays.asList("recipe_name", "ingredients", "instructions"));197198 String prompt =199 "Please extract the recipe from the following text.\n"200 + "The user wants to make delicious chocolate chip cookies.\n"201 + "They need 2 and 1/4 cups of all-purpose flour, 1 teaspoon of baking soda,\n"202 + "1 teaspoon of salt, 1 cup of unsalted butter (softened), 3/4 cup of granulated sugar,\n"203 + "3/4 cup of packed brown sugar, 1 teaspoon of vanilla extract, and 2 large eggs.\n"204 + "For the best part, they'll need 2 cups of semisweet chocolate chips.\n"205 + "First, preheat the oven to 375°F (190°C). Then, in a small bowl, whisk together the flour,\n"206 + "baking soda, and salt. In a large bowl, cream together the butter, granulated sugar, and brown sugar\n"207 + "until light and fluffy. Beat in the vanilla and eggs, one at a time. Gradually beat in the dry\n"208 + "ingredients until just combined. Finally, stir in the chocolate chips. Drop by rounded tablespoons\n"209 + "onto ungreased baking sheets and bake for 9 to 11 minutes.";210211 CreateModelInteractionResponseFormat format =212 CreateModelInteractionResponseFormat.of(213 ResponseFormat.of(214 TextResponseFormat.builder()215 .mimeType(TextResponseFormatMimeType.APPLICATION_JSON)216 .schema(recipeJsonSchema)217 .build()));218219 CreateModelInteraction params =220 CreateModelInteraction.builder()221 .model(Model.of("gemini-3.8-flash"))222 .input(InteractionsInput.of(prompt))223 .responseFormat(format)224 .build();225226 Interaction interaction =227 client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();228229 System.out.println(interaction.outputText().orElse(""));230231### REST232233 curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \234 -H "x-goog-api-key: $GEMINI_API_KEY" \235 -H 'Content-Type: application/json' \236 -d '{237 "model": "gemini-3.8-flash",238 "input": "Please extract the recipe from the following text.\nThe user wants to make delicious chocolate chip cookies.\nThey need 2 and 1/4 cups of all-purpose flour, 1 teaspoon of baking soda,\n1 teaspoon of salt, 1 cup of unsalted butter (softened), 3/4 cup of granulated sugar,\n3/4 cup of packed brown sugar, 1 teaspoon of vanilla extract, and 2 large eggs.\nFor the best part, they will need 2 cups of semisweet chocolate chips.\nFirst, preheat the oven to 375°F (190°C). Then, in a small bowl, whisk together the flour,\nbaking soda, and salt. In a large bowl, cream together the butter, granulated sugar, and brown sugar\nuntil light and fluffy. Beat in the vanilla and eggs, one at a time. Gradually beat in the dry\ningredients until just combined. Finally, stir in the chocolate chips. Drop by rounded tablespoons\nonto ungreased baking sheets and bake for 9 to 11 minutes.",239 "response_format": {240 "type": "text",241 "mime_type": "application/json",242 "schema": {243 "type": "object",244 "properties": {245 "recipe_name": {246 "type": "string",247 "description": "The name of the recipe."248 },249 "prep_time_minutes": {250 "type": "integer",251 "description": "Optional time in minutes to prepare the recipe."252 },253 "ingredients": {254 "type": "array",255 "items": {256 "type": "object",257 "properties": {258 "name": { "type": "string", "description": "Name of the ingredient."},259 "quantity": { "type": "string", "description": "Quantity of the ingredient, including units."}260 },261 "required": ["name", "quantity"]262 }263 },264 "instructions": {265 "type": "array",266 "items": { "type": "string" }267 }268 },269 "required": ["recipe_name", "ingredients", "instructions"]270 }271 }272 }273 }'274275**Example Response:**276277 {278 "recipe_name": "Delicious Chocolate Chip Cookies",279 "ingredients": [280 { "name": "all-purpose flour", "quantity": "2 and 1/4 cups" },281 { "name": "baking soda", "quantity": "1 teaspoon" },282 { "name": "salt", "quantity": "1 teaspoon" },283 { "name": "unsalted butter (softened)", "quantity": "1 cup" },284 { "name": "granulated sugar", "quantity": "3/4 cup" },285 { "name": "packed brown sugar", "quantity": "3/4 cup" },286 { "name": "vanilla extract", "quantity": "1 teaspoon" },287 { "name": "large eggs", "quantity": "2" },288 { "name": "semisweet chocolate chips", "quantity": "2 cups" }289 ],290 "instructions": [291 "Preheat the oven to 375°F (190°C).",292 "In a small bowl, whisk together the flour, baking soda, and salt.",293 "In a large bowl, cream together the butter, granulated sugar, and brown sugar until light and fluffy.",294 "Beat in the vanilla and eggs, one at a time.",295 "Gradually beat in the dry ingredients until just combined.",296 "Stir in the chocolate chips.",297 "Drop by rounded tablespoons onto ungreased baking sheets and bake for 9 to 11 minutes."298 ]299 }300301### Content Moderation302303This example showcases `anyOf` for conditional schemas and `enum` for304classification, allowing the output structure to vary based on the content.305306### Python307308 from google import genai309 from pydantic import BaseModel, Field310 from typing import Union, Literal311312 class SpamDetails(BaseModel):313 reason: str = Field(description="The reason why the content is considered spam.")314 spam_type: Literal["phishing", "scam", "unsolicited promotion", "other"] = Field(description="The type of spam.")315316 class NotSpamDetails(BaseModel):317 summary: str = Field(description="A brief summary of the content.")318 is_safe: bool = Field(description="Whether the content is safe for all audiences.")319320 class ModerationResult(BaseModel):321 decision: Union[SpamDetails, NotSpamDetails]322323 client = genai.Client()324325 prompt = """326 Please moderate the following content and provide a decision.327 Content: 'Congratulations! You''ve won a free cruise to the Bahamas. Click here to claim your prize: www.definitely-not-a-scam.com'328 """329330 interaction = client.interactions.create(331 model="gemini-3.8-flash",332 input=prompt,333 response_format={334 "type": "text",335 "mime_type": "application/json",336 "schema": ModerationResult.model_json_schema()337 },338 )339340 result = ModerationResult.model_validate_json(interaction.output_text)341 print(result)342343### JavaScript344345 // Note: Ensure zod is installed (npm install zod)346 import { GoogleGenAI } from "@google/genai";347 import * as z from "zod";348349 const moderationResultJsonSchema = {350 type: "object",351 properties: {352 decision: {353 anyOf: [354 {355 type: "object",356 title: "SpamDetails",357 description: "Details for content classified as spam.",358 properties: {359 reason: { type: "string", description: "The reason why the content is considered spam." },360 spam_type: { type: "string", enum: ["phishing", "scam", "unsolicited promotion", "other"], description: "The type of spam." }361 },362 required: ["reason", "spam_type"]363 },364 {365 type: "object",366 title: "NotSpamDetails",367 description: "Details for content classified as not spam.",368 properties: {369 summary: { type: "string", description: "A brief summary of the content." },370 is_safe: { type: "boolean", description: "Whether the content is safe for all audiences." }371 },372 required: ["summary", "is_safe"]373 }374 ]375 }376 },377 required: ["decision"]378 };379380 const moderationResultSchema = z.fromJSONSchema(moderationResultJsonSchema);381382 const client = new GoogleGenAI({});383384 const prompt = `385 Please moderate the following content and provide a decision.386 Content: 'Congratulations! You''ve won a free cruise to the Bahamas. Click here to claim your prize: www.definitely-not-a-scam.com'387 `;388389 const interaction = await client.interactions.create({390 model: "gemini-3.8-flash",391 input: prompt,392 response_format: {393 type: 'text',394 mime_type: 'application/json',395 schema: moderationResultJsonSchema396 },397 });398399 const result = moderationResultSchema.parse(JSON.parse(interaction.output_text));400 console.log(result);401402### Java403404 import com.google.genai.Client;405 import com.google.genai.gaos.models.interactions.CreateModelInteraction;406 import com.google.genai.gaos.models.interactions.CreateModelInteractionResponseFormat;407 import com.google.genai.gaos.models.interactions.Interaction;408 import com.google.genai.gaos.models.interactions.InteractionsInput;409 import com.google.genai.gaos.models.interactions.Model;410 import com.google.genai.gaos.models.interactions.ResponseFormat;411 import com.google.genai.gaos.models.interactions.TextResponseFormat;412 import com.google.genai.gaos.models.interactions.TextResponseFormatMimeType;413 import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;414 import java.util.Arrays;415 import java.util.HashMap;416 import java.util.Map;417418 Client client = new Client();419420 Map<String, Object> spamProps = new HashMap<>();421 Map<String, Object> reasonProp = new HashMap<>();422 reasonProp.put("type", "string");423 reasonProp.put("description", "The reason why the content is considered spam.");424 spamProps.put("reason", reasonProp);425426 Map<String, Object> spamTypeProp = new HashMap<>();427 spamTypeProp.put("type", "string");428 spamTypeProp.put("enum", Arrays.asList("phishing", "scam", "unsolicited promotion", "other"));429 spamTypeProp.put("description", "The type of spam.");430 spamProps.put("spam_type", spamTypeProp);431432 Map<String, Object> spamDetailsSchema = new HashMap<>();433 spamDetailsSchema.put("type", "object");434 spamDetailsSchema.put("title", "SpamDetails");435 spamDetailsSchema.put("properties", spamProps);436 spamDetailsSchema.put("required", Arrays.asList("reason", "spam_type"));437438 Map<String, Object> notSpamProps = new HashMap<>();439 Map<String, Object> summaryProp = new HashMap<>();440 summaryProp.put("type", "string");441 summaryProp.put("description", "A brief summary of the content.");442 notSpamProps.put("summary", summaryProp);443444 Map<String, Object> isSafeProp = new HashMap<>();445 isSafeProp.put("type", "boolean");446 isSafeProp.put("description", "Whether the content is safe for all audiences.");447 notSpamProps.put("is_safe", isSafeProp);448449 Map<String, Object> notSpamDetailsSchema = new HashMap<>();450 notSpamDetailsSchema.put("type", "object");451 notSpamDetailsSchema.put("title", "NotSpamDetails");452 notSpamDetailsSchema.put("properties", notSpamProps);453 notSpamDetailsSchema.put("required", Arrays.asList("summary", "is_safe"));454455 Map<String, Object> decisionProp = new HashMap<>();456 decisionProp.put("anyOf", Arrays.asList(spamDetailsSchema, notSpamDetailsSchema));457458 Map<String, Object> properties = new HashMap<>();459 properties.put("decision", decisionProp);460461 Map<String, Object> moderationResultJsonSchema = new HashMap<>();462 moderationResultJsonSchema.put("type", "object");463 moderationResultJsonSchema.put("properties", properties);464 moderationResultJsonSchema.put("required", Arrays.asList("decision"));465466 String prompt =467 "Please moderate the following content and provide a decision.\n"468 + "Content: 'Congratulations! You''ve won a free cruise to the Bahamas. Click here to claim your prize: www.definitely-not-a-scam.com'";469470 CreateModelInteractionResponseFormat format =471 CreateModelInteractionResponseFormat.of(472 ResponseFormat.of(473 TextResponseFormat.builder()474 .mimeType(TextResponseFormatMimeType.APPLICATION_JSON)475 .schema(moderationResultJsonSchema)476 .build()));477478 CreateModelInteraction params =479 CreateModelInteraction.builder()480 .model(Model.of("gemini-3.8-flash"))481 .input(InteractionsInput.of(prompt))482 .responseFormat(format)483 .build();484485 Interaction interaction =486 client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();487488 System.out.println(interaction.outputText().orElse(""));489490### REST491492 curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \493 -H "x-goog-api-key: $GEMINI_API_KEY" \494 -H 'Content-Type: application/json' \495 -d '{496 "model": "gemini-3.8-flash",497 "input": "Please moderate the following content and provide a decision.\nContent: '\''Congratulations! You have won a free cruise to the Bahamas. Click here to claim your prize: www.definitely-not-a-scam.com'\''",498 "response_format": {499 "type": "text",500 "mime_type": "application/json",501 "schema": {502 "type": "object",503 "properties": {504 "decision": {505 "anyOf": [506 {507 "type": "object",508 "title": "SpamDetails",509 "description": "Details for content classified as spam.",510 "properties": {511 "reason": { "type": "string", "description": "The reason why the content is considered spam." },512 "spam_type": { "type": "string", "enum": ["phishing", "scam", "unsolicited promotion", "other"], "description": "The type of spam." }513 },514 "required": ["reason", "spam_type"]515 },516 {517 "type": "object",518 "title": "NotSpamDetails",519 "description": "Details for content classified as not spam.",520 "properties": {521 "summary": { "type": "string", "description": "A brief summary of the content." },522 "is_safe": { "type": "boolean", "description": "Whether the content is safe for all audiences." }523 },524 "required": ["summary", "is_safe"]525 }526 ]527 }528 },529 "required": ["decision"]530 }531 }532 }533 }'534535**Example Response:**536537 {538 "decision": {539 "reason": "The content is an unsolicited prize notification attempting to trick the user into clicking a suspicious link.",540 "spam_type": "scam"541 }542 }543544### Recursive Structures545546This example illustrates how to define a recursive schema such as an547organization chart.548549### Python550551 from google import genai552 from pydantic import BaseModel, Field553 from typing import List554555 class Employee(BaseModel):556 """Represents an employee in an organization."""557 name: str558 employee_id: int559 reports: List["Employee"] = Field(560 default_factory=list,561 description="A list of employees reporting to this employee."562 )563564 client = genai.Client()565566 prompt = """567 Generate an organization chart for a small team.568 The manager is Alice, who manages Bob and Charlie. Bob manages David.569 """570571 interaction = client.interactions.create(572 model="gemini-3.8-flash",573 input=prompt,574 response_format={575 "type": "text",576 "mime_type": "application/json",577 "schema": Employee.model_json_schema()578 },579 )580581 employee = Employee.model_validate_json(interaction.output_text)582 print(employee)583584### JavaScript585586 // Note: Ensure zod is installed (npm install zod)587 import { GoogleGenAI } from "@google/genai";588 import * as z from "zod";589590 const employeeJsonSchema = {591 type: "object",592 properties: {593 name: { type: "string" },594 employee_id: { type: "integer" },595 reports: {596 type: "array",597 description: "A list of employees reporting to this employee.",598 items: {599 "$ref": "#"600 }601 }602 },603 required: ["name", "employee_id", "reports"]604 };605606 const employeeSchema = z.fromJSONSchema(employeeJsonSchema);607608 const client = new GoogleGenAI({});609610 const prompt = `611 Generate an organization chart for a small team.612 The manager is Alice, who manages Bob and Charlie. Bob manages David.613 `;614615 const interaction = await client.interactions.create({616 model: "gemini-3.8-flash",617 input: prompt,618 response_format: {619 type: 'text',620 mime_type: 'application/json',621 schema: employeeJsonSchema622 },623 });624625 const employee = employeeSchema.parse(JSON.parse(interaction.output_text));626 console.log(employee);627628### Java629630 import com.google.genai.Client;631 import com.google.genai.gaos.models.interactions.CreateModelInteraction;632 import com.google.genai.gaos.models.interactions.CreateModelInteractionResponseFormat;633 import com.google.genai.gaos.models.interactions.Interaction;634 import com.google.genai.gaos.models.interactions.InteractionsInput;635 import com.google.genai.gaos.models.interactions.Model;636 import com.google.genai.gaos.models.interactions.ResponseFormat;637 import com.google.genai.gaos.models.interactions.TextResponseFormat;638 import com.google.genai.gaos.models.interactions.TextResponseFormatMimeType;639 import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;640 import java.util.Arrays;641 import java.util.Collections;642 import java.util.HashMap;643 import java.util.Map;644645 Client client = new Client();646647 Map<String, Object> properties = new HashMap<>();648649 Map<String, Object> nameProp = new HashMap<>();650 nameProp.put("type", "string");651 properties.put("name", nameProp);652653 Map<String, Object> idProp = new HashMap<>();654 idProp.put("type", "integer");655 properties.put("employee_id", idProp);656657 Map<String, Object> reportsProp = new HashMap<>();658 reportsProp.put("type", "array");659 reportsProp.put("description", "A list of employees reporting to this employee.");660 reportsProp.put("items", Collections.singletonMap("$ref", "#"));661 properties.put("reports", reportsProp);662663 Map<String, Object> employeeJsonSchema = new HashMap<>();664 employeeJsonSchema.put("type", "object");665 employeeJsonSchema.put("properties", properties);666 employeeJsonSchema.put("required", Arrays.asList("name", "employee_id", "reports"));667668 String prompt =669 "Generate an organization chart for a small team.\n"670 + "The manager is Alice, who manages Bob and Charlie. Bob manages David.";671672 CreateModelInteractionResponseFormat format =673 CreateModelInteractionResponseFormat.of(674 ResponseFormat.of(675 TextResponseFormat.builder()676 .mimeType(TextResponseFormatMimeType.APPLICATION_JSON)677 .schema(employeeJsonSchema)678 .build()));679680 CreateModelInteraction params =681 CreateModelInteraction.builder()682 .model(Model.of("gemini-3.8-flash"))683 .input(InteractionsInput.of(prompt))684 .responseFormat(format)685 .build();686687 Interaction interaction =688 client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();689690 System.out.println(interaction.outputText().orElse(""));691692### REST693694 curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \695 -H "x-goog-api-key: $GEMINI_API_KEY" \696 -H 'Content-Type: application/json' \697 -d '{698 "model": "gemini-3.8-flash",699 "input": "Generate an organization chart for a small team.\nThe manager is Alice, who manages Bob and Charlie. Bob manages David.",700 "response_format": {701 "type": "text",702 "mime_type": "application/json",703 "schema": {704 "type": "object",705 "properties": {706 "name": { "type": "string" },707 "employee_id": { "type": "integer" },708 "reports": {709 "type": "array",710 "description": "A list of employees reporting to this employee.",711 "items": {712 "$ref": "#"713 }714 }715 },716 "required": ["name", "employee_id", "reports"]717 }718 }719 }720 }'721722**Example Response:**723724 {725 "name": "Alice",726 "employee_id": 101,727 "reports": [728 {729 "name": "Bob",730 "employee_id": 102,731 "reports": [732 {733 "name": "David",734 "employee_id": 104,735 "reports": []736 }737 ]738 },739 {740 "name": "Charlie",741 "employee_id": 103,742 "reports": []743 }744 ]745 }746747## Streaming results748749You can stream structured outputs, allowing you to start processing the750response as it's being generated. The streamed chunks are valid partial JSON751strings that can be concatenated to form the final JSON object.752753### Python754755 from google import genai756 from pydantic import BaseModel757 from typing import Literal758759 class Feedback(BaseModel):760 sentiment: Literal["positive", "neutral", "negative"]761 summary: str762763 client = genai.Client()764 prompt = "The new UI is incredibly intuitive. Add a very long summary to test streaming!"765766 stream = client.interactions.create(767 model="gemini-3.8-flash",768 input=prompt,769 response_format={770 "type": "text",771 "mime_type": "application/json",772 "schema": Feedback.model_json_schema()773 },774 stream=True775 )776 for event in stream:777 if event.event_type == "step.delta":778 if event.delta.type == "text" and getattr(event.delta, "text", None):779 print(event.delta.text, end="", flush=True)780781### JavaScript782783 // Note: Ensure zod is installed (npm install zod)784 import { GoogleGenAI } from "@google/genai";785 import * as z from "zod";786787 const feedbackJsonSchema = {788 type: "object",789 properties: {790 sentiment: { type: "string", enum: ["positive", "neutral", "negative"] },791 summary: { type: "string" }792 },793 required: ["sentiment", "summary"]794 };795796 const feedbackSchema = z.fromJSONSchema(feedbackJsonSchema);797798 const client = new GoogleGenAI({});799800 const stream = await client.interactions.create({801 model: "gemini-3.8-flash",802 input: "The new UI is incredibly intuitive. Add a very long summary!",803 response_format: {804 type: 'text',805 mime_type: 'application/json',806 schema: feedbackJsonSchema807 },808 stream: true,809 });810811 for await (const event of stream) {812 if (event.event_type === "step.delta") {813 if (event.delta.type === "text") {814 process.stdout.write(event.delta.text);815 }816 }817 }818819### Java820821 import com.google.genai.Client;822 import com.google.genai.gaos.models.interactions.CreateModelInteraction;823 import com.google.genai.gaos.models.interactions.CreateModelInteractionResponseFormat;824 import com.google.genai.gaos.models.interactions.InteractionSSEEvent;825 import com.google.genai.gaos.models.interactions.InteractionSSEStreamEvent;826 import com.google.genai.gaos.models.interactions.InteractionsInput;827 import com.google.genai.gaos.models.interactions.Model;828 import com.google.genai.gaos.models.interactions.ResponseFormat;829 import com.google.genai.gaos.models.interactions.StepDelta;830 import com.google.genai.gaos.models.interactions.StepDeltaData;831 import com.google.genai.gaos.models.interactions.TextDelta;832 import com.google.genai.gaos.models.interactions.TextResponseFormat;833 import com.google.genai.gaos.models.interactions.TextResponseFormatMimeType;834 import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;835 import com.google.genai.gaos.models.operations.CreateInteractionResponse;836 import com.google.genai.gaos.utils.EventStream;837 import java.util.Arrays;838 import java.util.HashMap;839 import java.util.Map;840841 Client client = new Client();842843 Map<String, Object> properties = new HashMap<>();844845 Map<String, Object> sentimentProp = new HashMap<>();846 sentimentProp.put("type", "string");847 sentimentProp.put("enum", Arrays.asList("positive", "neutral", "negative"));848 properties.put("sentiment", sentimentProp);849850 Map<String, Object> summaryProp = new HashMap<>();851 summaryProp.put("type", "string");852 properties.put("summary", summaryProp);853854 Map<String, Object> feedbackJsonSchema = new HashMap<>();855 feedbackJsonSchema.put("type", "object");856 feedbackJsonSchema.put("properties", properties);857 feedbackJsonSchema.put("required", Arrays.asList("sentiment", "summary"));858859 String prompt = "The new UI is incredibly intuitive. Add a very long summary to test streaming!";860861 CreateModelInteractionResponseFormat format =862 CreateModelInteractionResponseFormat.of(863 ResponseFormat.of(864 TextResponseFormat.builder()865 .mimeType(TextResponseFormatMimeType.APPLICATION_JSON)866 .schema(feedbackJsonSchema)867 .build()));868869 CreateModelInteraction params =870 CreateModelInteraction.builder()871 .model(Model.of("gemini-3.8-flash"))872 .input(InteractionsInput.of(prompt))873 .responseFormat(format)874 .stream(true)875 .build();876877 CreateInteractionResponse response =878 client.interactions.create(CreateInteractionRequestBody.of(params));879880 try (EventStream<InteractionSSEStreamEvent> events = response.events()) {881 for (InteractionSSEStreamEvent streamEvent : events) {882 InteractionSSEEvent event = streamEvent.data().orElse(null);883 if (event instanceof StepDelta) {884 StepDeltaData data = ((StepDelta) event).delta().orElse(null);885 if (data instanceof TextDelta) {886 ((TextDelta) data).text().ifPresent(System.out::print);887 }888 }889 }890 }891892### REST893894 curl -N -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \895 -H "x-goog-api-key: $GEMINI_API_KEY" \896 -H 'Content-Type: application/json' \897 -d '{898 "model": "gemini-3.8-flash",899 "input": "The new UI is incredibly intuitive. Add a very long summary!",900 "response_format": {901 "type": "text",902 "mime_type": "application/json",903 "schema": {904 "type": "object",905 "properties": {906 "sentiment": { "type": "string", "enum": ["positive", "neutral", "negative"] },907 "summary": { "type": "string" }908 },909 "required": ["sentiment", "summary"]910 }911 },912 "stream": true913 }'914915## Structured outputs with tools916917> [!WARNING]918> **Preview:** This feature is available only to Gemini 3 series models.919920Gemini 3 lets you combine Structured Outputs with built-in tools, including921[Grounding with Google Search](https://ai.google.dev/gemini-api/docs/google-search),922[URL Context](https://ai.google.dev/gemini-api/docs/url-context),923[Code Execution](https://ai.google.dev/gemini-api/docs/code-execution),924[File Search](https://ai.google.dev/gemini-api/docs/file-search#structured-output), and925[Function Calling](https://ai.google.dev/gemini-api/docs/function-calling).926927### Python928929 from google import genai930 from pydantic import BaseModel, Field931 from typing import List932933 class MatchResult(BaseModel):934 winner: str = Field(description="The name of the winner.")935 final_match_score: str = Field(description="The final match score.")936 scorers: List[str] = Field(description="The name of the scorer.")937938 client = genai.Client()939940 interaction = client.interactions.create(941 model="gemini-3.1-pro-preview",942 input="Search for all details for the latest Euro.",943 tools=[{"type": "google_search"}, {"type": "url_context"}],944 response_format={945 "type": "text",946 "mime_type": "application/json",947 "schema": MatchResult.model_json_schema()948 },949 )950951 result = MatchResult.model_validate_json(interaction.output_text)952 print(result)953954### JavaScript955956 // Note: Ensure zod is installed (npm install zod)957 import { GoogleGenAI } from "@google/genai";958 import * as z from "zod";959960 const matchJsonSchema = {961 type: "object",962 properties: {963 winner: { type: "string" },964 final_match_score: { type: "string" },965 scorers: { type: "array", items: { type: "string" } }966 },967 required: ["winner", "final_match_score", "scorers"]968 };969970 const matchSchema = z.fromJSONSchema(matchJsonSchema);971972 const client = new GoogleGenAI({});973974 const interaction = await client.interactions.create({975 model: "gemini-3.1-pro-preview",976 input: "Search for all details for the latest Euro.",977 tools: [{type: "google_search"}, {type: "url_context"}],978 response_format: {979 type: 'text',980 mime_type: 'application/json',981 schema: matchJsonSchema982 },983 });984985 const match = matchSchema.parse(JSON.parse(interaction.output_text));986 console.log(match);987988### Java989990 import com.google.genai.Client;991 import com.google.genai.gaos.models.interactions.CreateModelInteraction;992 import com.google.genai.gaos.models.interactions.CreateModelInteractionResponseFormat;993 import com.google.genai.gaos.models.interactions.GoogleSearch;994 import com.google.genai.gaos.models.interactions.Interaction;995 import com.google.genai.gaos.models.interactions.InteractionsInput;996 import com.google.genai.gaos.models.interactions.Model;997 import com.google.genai.gaos.models.interactions.ResponseFormat;998 import com.google.genai.gaos.models.interactions.TextResponseFormat;999 import com.google.genai.gaos.models.interactions.TextResponseFormatMimeType;1000 import com.google.genai.gaos.models.interactions.URLContext;1001 import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;1002 import java.util.Arrays;1003 import java.util.Collections;1004 import java.util.HashMap;1005 import java.util.Map;10061007 Client client = new Client();10081009 Map<String, Object> properties = new HashMap<>();10101011 Map<String, Object> winnerProp = new HashMap<>();1012 winnerProp.put("type", "string");1013 winnerProp.put("description", "The name of the winner.");1014 properties.put("winner", winnerProp);10151016 Map<String, Object> scoreProp = new HashMap<>();1017 scoreProp.put("type", "string");1018 scoreProp.put("description", "The final match score.");1019 properties.put("final_match_score", scoreProp);10201021 Map<String, Object> scorersProp = new HashMap<>();1022 scorersProp.put("type", "array");1023 scorersProp.put("description", "The name of the scorer.");1024 scorersProp.put("items", Collections.singletonMap("type", "string"));1025 properties.put("scorers", scorersProp);10261027 Map<String, Object> matchJsonSchema = new HashMap<>();1028 matchJsonSchema.put("type", "object");1029 matchJsonSchema.put("properties", properties);1030 matchJsonSchema.put("required", Arrays.asList("winner", "final_match_score", "scorers"));10311032 CreateModelInteractionResponseFormat format =1033 CreateModelInteractionResponseFormat.of(1034 ResponseFormat.of(1035 TextResponseFormat.builder()1036 .mimeType(TextResponseFormatMimeType.APPLICATION_JSON)1037 .schema(matchJsonSchema)1038 .build()));10391040 CreateModelInteraction params =1041 CreateModelInteraction.builder()1042 .model(Model.of("gemini-3.1-pro-preview"))1043 .input(InteractionsInput.of("Search for all details for the latest Euro."))1044 .tools(Arrays.asList(GoogleSearch.builder().build(), URLContext.builder().build()))1045 .responseFormat(format)1046 .build();10471048 Interaction interaction =1049 client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();10501051 System.out.println(interaction.outputText().orElse(""));10521053### REST10541055 curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \1056 -H "x-goog-api-key: $GEMINI_API_KEY" \1057 -H 'Content-Type: application/json' \1058 -d '{1059 "model": "gemini-3.1-pro-preview",1060 "input": "Search for all details for the latest Euro.",1061 "tools": [{"type": "google_search"}, {"type": "url_context"}],1062 "response_format": {1063 "type": "text",1064 "mime_type": "application/json",1065 "schema": {1066 "type": "object",1067 "properties": {1068 "winner": {"type": "string"},1069 "final_match_score": {"type": "string"},1070 "scorers": {"type": "array", "items": {"type": "string"}}1071 },1072 "required": ["winner", "final_match_score", "scorers"]1073 }1074 }1075 }'10761077## JSON schema support10781079To generate a JSON object, configure `response_format` with an object (or an array containing an object) of type `text` and set its `mime_type` to `application/json`. The schema should be provided in the `schema` field.10801081Gemini's structured output mode supports a subset of the1082[JSON Schema](https://json-schema.org/) specification.10831084The following values of `type` are supported:10851086- **`string`**: For text.1087- **`number`**: For floating-point numbers.1088- **`integer`**: For whole numbers.1089- **`boolean`**: For true or false values.1090- **`object`**: For structured data with key-value pairs.1091- **`array`**: For lists of items.1092- **`null`** : To allow a property to be null, include `"null"` in the type array (e.g., `{"type": ["string", "null"]}`).10931094These descriptive properties help guide the model:10951096- **`title`**: A short description of a property.1097- **`description`**: A longer and more detailed description of a property.10981099### Type-specific properties11001101**For `object` values:**11021103- **`properties`**: An object where each key is a property name and each value is a schema for that property.1104- **`required`**: An array of strings, listing which properties are mandatory.1105- **`additionalProperties`** : Controls whether properties not listed in `properties` are allowed. Can be a boolean or a schema.11061107**For `string` values:**11081109- **`enum`**: Lists a specific set of possible strings for classification tasks.1110- **`format`** : Specifies a syntax for the string, such as `date-time`, `date`, `time`.11111112**For `number` and `integer` values:**11131114- **`enum`**: Lists a specific set of possible numeric values.1115- **`minimum`**: The minimum inclusive value.1116- **`maximum`**: The maximum inclusive value.11171118**For `array` values:**11191120- **`items`**: Defines the schema for all items in the array.1121- **`prefixItems`**: Defines a list of schemas for the first N items, allowing for tuple-like structures.1122- **`minItems`**: The minimum number of items in the array.1123- **`maxItems`**: The maximum number of items in the array.11241125## Structured outputs versus function calling11261127| Feature | Primary Use Case |1128|---|---|1129| **Structured Outputs** | **Formatting the final response.** Use when you want the model's *answer* in a specific format. |1130| **Function Calling** | **Taking action during conversation.** Use when the model needs to *ask you* to perform a task before providing a final answer. |11311132## Best practices11331134- **Clear descriptions:** Use the `description` field to guide the model.1135- **Strong typing:** Use specific types (`integer`, `string`, `enum`).1136- **Prompt engineering:** Clearly state what you want the model to do.1137- **Validation:** While output is syntactically correct JSON, always validate values in your application.1138- **Error handling:** Implement robust error handling for schema-compliant but semantically incorrect outputs.11391140## Limitations11411142- **Schema subset:** Not all JSON Schema features are supported.1143- **Schema complexity:** Very large or deeply nested schemas may be rejected.