Repository Public
1You can configure Gemini models to generate responses that adhere to a provided JSON2Schema. This ensures predictable, type-safe results and simplifies extracting3structured 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 SDKs12make it easy to define 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 response = client.models.generate_content(56 model="gemini-3.8-flash",57 contents=prompt,58 config={59 "response_format": {"text": {"mime_type": "application/json", "schema": Recipe.model_json_schema()}},60 },61 )6263 recipe = Recipe.model_validate_json(response.text)64 print(recipe)6566### JavaScript6768 import { GoogleGenAI } from "@google/genai";69 import { z } from "zod";70 import { zodToJsonSchema } from "zod-to-json-schema";7172 const ingredientSchema = z.object({73 name: z.string().describe("Name of the ingredient."),74 quantity: z.string().describe("Quantity of the ingredient, including units."),75 });7677 const recipeSchema = z.object({78 recipe_name: z.string().describe("The name of the recipe."),79 prep_time_minutes: z.number().optional().describe("Optional time in minutes to prepare the recipe."),80 ingredients: z.array(ingredientSchema),81 instructions: z.array(z.string()),82 });8384 const ai = new GoogleGenAI({});8586 const prompt = `87 Please extract the recipe from the following text.88 The user wants to make delicious chocolate chip cookies.89 They need 2 and 1/4 cups of all-purpose flour, 1 teaspoon of baking soda,90 1 teaspoon of salt, 1 cup of unsalted butter (softened), 3/4 cup of granulated sugar,91 3/4 cup of packed brown sugar, 1 teaspoon of vanilla extract, and 2 large eggs.92 For the best part, they'll need 2 cups of semisweet chocolate chips.93 First, preheat the oven to 375°F (190°C). Then, in a small bowl, whisk together the flour,94 baking soda, and salt. In a large bowl, cream together the butter, granulated sugar, and brown sugar95 until light and fluffy. Beat in the vanilla and eggs, one at a time. Gradually beat in the dry96 ingredients until just combined. Finally, stir in the chocolate chips. Drop by rounded tablespoons97 onto ungreased baking sheets and bake for 9 to 11 minutes.98 `;99100 const response = await ai.models.generateContent({101 model: "gemini-3.8-flash",102 contents: prompt,103 config: {104 responseFormat: { text: { mimeType: "application/json", schema: zodToJsonSchema(recipeSchema) } },105 },106 });107108 const recipe = recipeSchema.parse(JSON.parse(response.text));109 console.log(recipe);110111### Go112113 package main114115 import (116 "context"117 "fmt"118 "log"119120 "google.golang.org/genai"121 )122123 func main() {124 ctx := context.Background()125 client, err := genai.NewClient(ctx, nil)126 if err != nil {127 log.Fatal(err)128 }129130 prompt := `131 Please extract the recipe from the following text.132 The user wants to make delicious chocolate chip cookies.133 They need 2 and 1/4 cups of all-purpose flour, 1 teaspoon of baking soda,134 1 teaspoon of salt, 1 cup of unsalted butter (softened), 3/4 cup of granulated sugar,135 3/4 cup of packed brown sugar, 1 teaspoon of vanilla extract, and 2 large eggs.136 For the best part, they'll need 2 cups of semisweet chocolate chips.137 First, preheat the oven to 375°F (190°C). Then, in a small bowl, whisk together the flour,138 baking soda, and salt. In a large bowl, cream together the butter, granulated sugar, and brown sugar139 until light and fluffy. Beat in the vanilla and eggs, one at a time. Gradually beat in the dry140 ingredients until just combined. Finally, stir in the chocolate chips. Drop by rounded tablespoons141 onto ungreased baking sheets and bake for 9 to 11 minutes.142 `143 config := &genai.GenerateContentConfig{144 ResponseMIMEType: "application/json",145 ResponseJsonSchema: map[string]any{146 "type": "object",147 "properties": map[string]any{148 "recipe_name": map[string]any{149 "type": "string",150 "description": "The name of the recipe.",151 },152 "prep_time_minutes": map[string]any{153 "type": "integer",154 "description": "Optional time in minutes to prepare the recipe.",155 },156 "ingredients": map[string]any{157 "type": "array",158 "items": map[string]any{159 "type": "object",160 "properties": map[string]any{161 "name": map[string]any{162 "type": "string",163 "description": "Name of the ingredient.",164 },165 "quantity": map[string]any{166 "type": "string",167 "description": "Quantity of the ingredient, including units.",168 },169 },170 "required": []string{"name", "quantity"},171 },172 },173 "instructions": map[string]any{174 "type": "array",175 "items": map[string]any{"type": "string"},176 },177 },178 "required": []string{"recipe_name", "ingredients", "instructions"},179 },180 }181182 result, err := client.Models.GenerateContent(183 ctx,184 "gemini-3.8-flash",185 genai.Text(prompt),186 config,187 )188 if err != nil {189 log.Fatal(err)190 }191 fmt.Println(result.Text())192 }193194### REST195196 curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash:generateContent" \197 -H "x-goog-api-key: $GEMINI_API_KEY" \198 -H 'Content-Type: application/json' \199 -X POST \200 -d '{201 "contents": [{202 "parts":[203 { "text": "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." }204 ]205 }],206 "generationConfig": {207 "responseFormat": {208 "text": {209 "mimeType": "application/json",210 "schema": {211 "type": "object",212 "properties": {213 "recipe_name": {214 "type": "string",215 "description": "The name of the recipe."216 },217 "prep_time_minutes": {218 "type": "integer",219 "description": "Optional time in minutes to prepare the recipe."220 },221 "ingredients": {222 "type": "array",223 "items": {224 "type": "object",225 "properties": {226 "name": { "type": "string", "description": "Name of the ingredient."},227 "quantity": { "type": "string", "description": "Quantity of the ingredient, including units."}228 }229 }230 },231 "required": ["name", "quantity"]232 }233 },234 "instructions": {235 "type": "array",236 "items": { "type": "string" }237 }238 },239 "required": ["recipe_name", "ingredients", "instructions"]240 }241 }242 }'243244**Example Response:**245246 {247 "recipe_name": "Delicious Chocolate Chip Cookies",248 "ingredients": [249 {250 "name": "all-purpose flour",251 "quantity": "2 and 1/4 cups"252 },253 {254 "name": "baking soda",255 "quantity": "1 teaspoon"256 },257 {258 "name": "salt",259 "quantity": "1 teaspoon"260 },261 {262 "name": "unsalted butter (softened)",263 "quantity": "1 cup"264 },265 {266 "name": "granulated sugar",267 "quantity": "3/4 cup"268 },269 {270 "name": "packed brown sugar",271 "quantity": "3/4 cup"272 },273 {274 "name": "vanilla extract",275 "quantity": "1 teaspoon"276 },277 {278 "name": "large eggs",279 "quantity": "2"280 },281 {282 "name": "semisweet chocolate chips",283 "quantity": "2 cups"284 }285 ],286 "instructions": [287 "Preheat the oven to 375°F (190°C).",288 "In a small bowl, whisk together the flour, baking soda, and salt.",289 "In a large bowl, cream together the butter, granulated sugar, and brown sugar until light and fluffy.",290 "Beat in the vanilla and eggs, one at a time.",291 "Gradually beat in the dry ingredients until just combined.",292 "Stir in the chocolate chips.",293 "Drop by rounded tablespoons onto ungreased baking sheets and bake for 9 to 11 minutes."294 ]295 }296297### Content Moderation298299This example showcases `anyOf` for conditional schemas and `enum` for300classification, allowing the output structure to vary based on the content.301302### Python303304 from google import genai305 from pydantic import BaseModel, Field306 from typing import Union, Literal307308 class SpamDetails(BaseModel):309 reason: str = Field(description="The reason why the content is considered spam.")310 spam_type: Literal["phishing", "scam", "unsolicited promotion", "other"] = Field(description="The type of spam.")311312 class NotSpamDetails(BaseModel):313 summary: str = Field(description="A brief summary of the content.")314 is_safe: bool = Field(description="Whether the content is safe for all audiences.")315316 class ModerationResult(BaseModel):317 decision: Union[SpamDetails, NotSpamDetails]318319 client = genai.Client()320321 prompt = """322 Please moderate the following content and provide a decision.323 Content: 'Congratulations! You''ve won a free cruise to the Bahamas. Click here to claim your prize: www.definitely-not-a-scam.com'324 """325326 response = client.models.generate_content(327 model="gemini-3.8-flash",328 contents=prompt,329 config={330 "response_format": {"text": {"mime_type": "application/json", "schema": ModerationResult.model_json_schema()}},331 },332 )333334 result = ModerationResult.model_validate_json(response.text)335 print(result)336337### JavaScript338339 import { GoogleGenAI } from "@google/genai";340 import { z } from "zod";341 import { zodToJsonSchema } from "zod-to-json-schema";342343 const spamDetailsSchema = z.object({344 reason: z.string().describe("The reason why the content is considered spam."),345 spam_type: z.enum(["phishing", "scam", "unsolicited promotion", "other"]).describe("The type of spam."),346 });347348 const notSpamDetailsSchema = z.object({349 summary: z.string().describe("A brief summary of the content."),350 is_safe: z.boolean().describe("Whether the content is safe for all audiences."),351 });352353 const moderationResultSchema = z.object({354 decision: z.union([spamDetailsSchema, notSpamDetailsSchema]),355 });356357 const ai = new GoogleGenAI({});358359 const prompt = `360 Please moderate the following content and provide a decision.361 Content: 'Congratulations! You''ve won a free cruise to the Bahamas. Click here to claim your prize: www.definitely-not-a-scam.com'362 `;363364 const response = await ai.models.generateContent({365 model: "gemini-3.8-flash",366 contents: prompt,367 config: {368 responseFormat: { text: { mimeType: "application/json", schema: zodToJsonSchema(moderationResultSchema) } },369 },370 });371372 const result = moderationResultSchema.parse(JSON.parse(response.text));373 console.log(result);374375### Go376377 package main378379 import (380 "context"381 "fmt"382 "log"383384 "google.golang.org/genai"385 )386387 func main() {388 ctx := context.Background()389 client, err := genai.NewClient(ctx, nil)390 if err != nil {391 log.Fatal(err)392 }393394 prompt := `395 Please moderate the following content and provide a decision.396 Content: 'Congratulations! You''ve won a free cruise to the Bahamas. Click here to claim your prize: www.definitely-not-a-scam.com'397 `398 config := &genai.GenerateContentConfig{399 ResponseMIMEType: "application/json",400 ResponseJsonSchema: map[string]any{401 "type": "object",402 "properties": map[string]any{403 "decision": map[string]any{404 "anyOf": []map[string]any{405 {406 "type": "object",407 "title": "SpamDetails",408 "description": "Details for content classified as spam.",409 "properties": map[string]any{410 "reason": map[string]any{411 "type": "string",412 "description": "The reason why the content is considered spam.",413 },414 "spam_type": map[string]any{415 "type": "string",416 "enum": []string{"phishing", "scam", "unsolicited promotion", "other"},417 "description": "The type of spam.",418 },419 },420 "required": []string{"reason", "spam_type"},421 },422 {423 "type": "object",424 "title": "NotSpamDetails",425 "description": "Details for content classified as not spam.",426 "properties": map[string]any{427 "summary": map[string]any{428 "type": "string",429 "description": "A brief summary of the content.",430 },431 "is_safe": map[string]any{432 "type": "boolean",433 "description": "Whether the content is safe for all audiences.",434 },435 },436 "required": []string{"summary", "is_safe"},437 },438 },439 },440 },441 "required": []string{"decision"},442 },443 }444445 result, err := client.Models.GenerateContent(446 ctx,447 "gemini-3.8-flash",448 genai.Text(prompt),449 config,450 )451 if err != nil {452 log.Fatal(err)453 }454 fmt.Println(result.Text())455 }456457### REST458459 curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash:generateContent" \460 -H "x-goog-api-key: $GEMINI_API_KEY" \461 -H 'Content-Type: application/json' \462 -X POST \463 -d '{464 "contents": [{465 "parts":[466 { "text": "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''" }467 ]468 }],469 "generationConfig": {470 "responseFormat": {471 "text": {472 "mimeType": "application/json",473 "schema": {474 "type": "object",475 "properties": {476 "decision": {477 "anyOf": [478 {479 "type": "object",480 "title": "SpamDetails",481 "description": "Details for content classified as spam.",482 "properties": {483 "reason": { "type": "string", "description": "The reason why the content is considered spam." },484 "spam_type": { "type": "string", "enum": ["phishing", "scam", "unsolicited promotion", "other"], "description": "The type of spam." }485 }486 }487 },488 "required": ["reason", "spam_type"]489 },490 {491 "type": "object",492 "title": "NotSpamDetails",493 "description": "Details for content classified as not spam.",494 "properties": {495 "summary": { "type": "string", "description": "A brief summary of the content." },496 "is_safe": { "type": "boolean", "description": "Whether the content is safe for all audiences." }497 },498 "required": ["summary", "is_safe"]499 }500 ]501 }502 },503 "required": ["decision"]504 }505 }506 }'507 ```508509 **Example Response:**510511 ```json512 {513 "decision": {514 "reason": "The content is an unsolicited prize notification attempting to trick the user into clicking a suspicious link.",515 "spam_type": "scam"516 }517 }518519### Recursive Structures520521This example illustrates how to define a recursive schema such as an organization522chart.523524### Python525526 from google import genai527 from pydantic import BaseModel, Field528 from typing import List529530 class Employee(BaseModel):531 """Represents an employee in an organization."""532 name: str533 employee_id: int534 reports: List["Employee"] = Field(535 default_factory=list,536 description="A list of employees reporting to this employee."537 )538539 client = genai.Client()540541 prompt = """542 Generate an organization chart for a small team.543 The manager is Alice, who manages Bob and Charlie. Bob manages David.544 """545546 response = client.models.generate_content(547 model="gemini-3.8-flash",548 contents=prompt,549 config={550 "response_format": {"text": {"mime_type": "application/json", "schema": Employee.model_json_schema()}},551 },552 )553554 employee = Employee.model_validate_json(response.text)555 print(employee)556557### JavaScript558559 import { GoogleGenAI } from "@google/genai";560 import { z } from "zod";561 import { zodToJsonSchema } from "zod-to-json-schema";562563 const employeeSchema = z.object({564 name: z.string(),565 employee_id: z.number().int(),566 reports: z.lazy(() => z.array(employeeSchema)).describe("A list of employees reporting to this employee."),567 });568569 const ai = new GoogleGenAI({});570571 const prompt = `572 Generate an organization chart for a small team.573 The manager is Alice, who manages Bob and Charlie. Bob manages David.574 `;575576 const response = await ai.models.generateContent({577 model: "gemini-3.8-flash",578 contents: prompt,579 config: {580 responseFormat: { text: { mimeType: "application/json", schema: zodToJsonSchema(employeeSchema) } },581 },582 });583584 const employee = employeeSchema.parse(JSON.parse(response.text));585 console.log(employee);586587### Go588589 package main590591 import (592 "context"593 "fmt"594 "log"595596 "google.golang.org/genai"597 )598599 func main() {600 ctx := context.Background()601 client, err := genai.NewClient(ctx, nil)602 if err != nil {603 log.Fatal(err)604 }605606 prompt := `607 Generate an organization chart for a small team.608 The manager is Alice, who manages Bob and Charlie. Bob manages David.609 `610 config := &genai.GenerateContentConfig{611 ResponseMIMEType: "application/json",612 ResponseJsonSchema: map[string]any{613 "type": "object",614 "properties": map[string]any{615 "name": map[string]any{"type": "string"},616 "employee_id": map[string]any{"type": "integer"},617 "reports": map[string]any{618 "type": "array",619 "description": "A list of employees reporting to this employee.",620 "items": map[string]any{621 "$ref": "#",622 },623 },624 },625 "required": []string{"name", "employee_id", "reports"},626 },627 }628629 result, err := client.Models.GenerateContent(630 ctx,631 "gemini-3.8-flash",632 genai.Text(prompt),633 config,634 )635 if err != nil {636 log.Fatal(err)637 }638 fmt.Println(result.Text())639 }640641### REST642643 curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash:generateContent" \644 -H "x-goog-api-key: $GEMINI_API_KEY" \645 -H 'Content-Type: application/json' \646 -X POST \647 -d '{648 "contents": [{649 "parts":[650 { "text": "Generate an organization chart for a small team.\nThe manager is Alice, who manages Bob and Charlie. Bob manages David." }651 ]652 }],653 "generationConfig": {654 "responseFormat": {655 "text": {656 "mimeType": "application/json",657 "schema": {658 "type": "object",659 "properties": {660 "name": { "type": "string" },661 "employee_id": { "type": "integer" },662 "reports": {663 "type": "array",664 "description": "A list of employees reporting to this employee.",665 "items": {666 "$ref": "#"667 }668 }669 }670 }671 },672 "required": ["name", "employee_id", "reports"]673 }674 }675 }'676677**Example Response:**678679 {680 "name": "Alice",681 "employee_id": 101,682 "reports": [683 {684 "name": "Bob",685 "employee_id": 102,686 "reports": [687 {688 "name": "David",689 "employee_id": 104,690 "reports": []691 }692 ]693 },694 {695 "name": "Charlie",696 "employee_id": 103,697 "reports": []698 }699 ]700 }701702## Streaming703704You can stream structured outputs, which allows you to start processing the705response as it's being generated, without having to wait for the entire output706to be complete. This can improve the perceived performance of your application.707708The streamed chunks will be valid partial JSON strings, which can be709concatenated to form the final, complete JSON object.710711### Python712713 from google import genai714 from pydantic import BaseModel, Field715 from typing import Literal716717 class Feedback(BaseModel):718 sentiment: Literal["positive", "neutral", "negative"]719 summary: str720721 client = genai.Client()722 prompt = "The new UI is incredibly intuitive and visually appealing. Great job. Add a very long summary to test streaming!"723724 response_stream = client.models.generate_content_stream(725 model="gemini-3.8-flash",726 contents=prompt,727 config={728 "response_format": {"text": {"mime_type": "application/json", "schema": Feedback.model_json_schema()}},729 },730 )731732 for chunk in response_stream:733 print(chunk.candidates[0].content.parts[0].text)734735### JavaScript736737 import { GoogleGenAI } from "@google/genai";738 import { z } from "zod";739 import { zodToJsonSchema } from "zod-to-json-schema";740741 const ai = new GoogleGenAI({});742 const prompt = "The new UI is incredibly intuitive and visually appealing. Great job! Add a very long summary to test streaming!";743744 const feedbackSchema = z.object({745 sentiment: z.enum(["positive", "neutral", "negative"]),746 summary: z.string(),747 });748749 const stream = await ai.models.generateContentStream({750 model: "gemini-3.8-flash",751 contents: prompt,752 config: {753 responseFormat: { text: { mimeType: "application/json", schema: zodToJsonSchema(feedbackSchema) } },754 },755 });756757 for await (const chunk of stream) {758 console.log(chunk.candidates[0].content.parts[0].text)759 }760761## Structured outputs with tools762763> [!WARNING]764> **Preview:** This feature is available only to Gemini 3 series models, `gemini-3.1-pro-preview` and `gemini-3.8-flash`.765766Gemini 3 lets you combine Structured Outputs with built-in tools, including767[Grounding with Google Search](https://ai.google.dev/gemini-api/docs/google-search),768[URL Context](https://ai.google.dev/gemini-api/docs/url-context),769[Code Execution](https://ai.google.dev/gemini-api/docs/code-execution),770[File Search](https://ai.google.dev/gemini-api/docs/file-search#structured-output), and771[Function Calling](https://ai.google.dev/gemini-api/docs/function-calling).772773### Python774775 from google import genai776 from pydantic import BaseModel, Field777 from typing import List778779 class MatchResult(BaseModel):780 winner: str = Field(description="The name of the winner.")781 final_match_score: str = Field(description="The final match score.")782 scorers: List[str] = Field(description="The name of the scorer.")783784 client = genai.Client()785786 response = client.models.generate_content(787 model="gemini-3.1-pro-preview",788 contents="Search for all details for the latest Euro.",789 config={790 "tools": [791 {"google_search": {}},792 {"url_context": {}}793 ],794 "response_format": {"text": {"mime_type": "application/json", "schema": MatchResult.model_json_schema()}},795 }, 796 )797798 result = MatchResult.model_validate_json(response.text)799 print(result)800801### JavaScript802803 import { GoogleGenAI } from "@google/genai";804 import { z } from "zod";805 import { zodToJsonSchema } from "zod-to-json-schema";806807 const ai = new GoogleGenAI({});808809 const matchSchema = z.object({810 winner: z.string().describe("The name of the winner."),811 final_match_score: z.string().describe("The final score."),812 scorers: z.array(z.string()).describe("The name of the scorer.")813 });814815 async function run() {816 const response = await ai.models.generateContent({817 model: "gemini-3.1-pro-preview",818 contents: "Search for all details for the latest Euro.",819 config: {820 tools: [821 { googleSearch: {} },822 { urlContext: {} }823 ],824 responseFormat: { text: { mimeType: "application/json", schema: zodToJsonSchema(matchSchema) } },825 },826 });827828 const match = matchSchema.parse(JSON.parse(response.text));829 console.log(match);830 }831832 run();833834### REST835836 curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.1-pro-preview:generateContent" \837 -H "x-goog-api-key: $GEMINI_API_KEY" \838 -H 'Content-Type: application/json' \839 -X POST \840 -d '{841 "contents": [{842 "parts": [{"text": "Search for all details for the latest Euro."}]843 }],844 "tools": [845 {"googleSearch": {}},846 {"urlContext": {}}847 ],848 "generationConfig": {849 "responseFormat": {850 "text": {851 "mimeType": "application/json",852 "schema": {853 "type": "object",854 "properties": {855 "winner": {"type": "string", "description": "The name of the winner."},856 "final_match_score": {"type": "string", "description": "The final score."},857 "scorers": {858 "type": "array",859 "items": {"type": "string"},860 "description": "The name of the scorer."861 }862 }863 }864 },865 "required": ["winner", "final_match_score", "scorers"]866 }867 }868 }'869870## JSON schema support871872To generate a JSON object, set the `response_format` in the generation configuration. The schema must be a valid [JSON Schema](https://json-schema.org/) that describes the desired output format.873874The model will then generate a response that is a syntactically valid JSON string matching the provided schema. When using structured outputs, the model will produce outputs in the same order as the keys in the schema.875876Gemini's structured output mode supports a subset of the [JSON Schema](https://json-schema.org) specification.877878The following values of `type` are supported:879880- **`string`**: For text.881- **`number`**: For floating-point numbers.882- **`integer`**: For whole numbers.883- **`boolean`**: For true/false values.884- **`object`**: For structured data with key-value pairs.885- **`array`**: For lists of items.886- **`null`** : To allow a property to be null, include `"null"` in the type array (e.g., `{"type": ["string", "null"]}`).887888These descriptive properties help guide the model:889890- **`title`**: A short description of a property.891- **`description`**: A longer and more detailed description of a property.892893### Type-specific properties894895**For `object` values:**896897- **`properties`**: An object where each key is a property name and each value is a schema for that property.898- **`required`**: An array of strings, listing which properties are mandatory.899- **`additionalProperties`** : Controls whether properties not listed in `properties` are allowed. Can be a boolean or a schema.900901**For `string` values:**902903- **`enum`**: Lists a specific set of possible strings for classification tasks.904- **`format`** : Specifies a syntax for the string, such as `date-time`, `date`, `time`.905906**For `number` and `integer` values:**907908- **`enum`**: Lists a specific set of possible numeric values.909- **`minimum`**: The minimum inclusive value.910- **`maximum`**: The maximum inclusive value.911912**For `array` values:**913914- **`items`**: Defines the schema for all items in the array.915- **`prefixItems`**: Defines a list of schemas for the first N items, allowing for tuple-like structures.916- **`minItems`**: The minimum number of items in the array.917- **`maxItems`**: The maximum number of items in the array.918919## Model support920921The following models support structured output:922923| Model | Structured Outputs |924|---|---|925| Gemini 3.1 Flash-Lite | ✔️ |926| Gemini 3.1 Pro Preview | ✔️ |927| Gemini 3.5 Flash | ✔️ |928| Gemini 3.1 Flash-Lite Preview | ✔️ |929| Gemini 2.5 Pro | ✔️ |930| Gemini 2.5 Flash | ✔️ |931| Gemini 2.5 Flash-Lite | ✔️ |932| Gemini 2.0 Flash | ✔️\* |933| Gemini 2.0 Flash-Lite | ✔️\* |934935*\* Note that Gemini 2.0 requires an explicit `propertyOrdering` list within the JSON input to define the preferred structure. You can find an example in this [cookbook](https://github.com/google-gemini/cookbook/blob/main/examples/Pdf_structured_outputs_on_invoices_and_forms.ipynb).*936937## Structured outputs vs. function calling938939Both structured outputs and function calling use JSON schemas, but they serve different purposes:940941| Feature | Primary Use Case |942|---|---|943| **Structured Outputs** | **Formatting the final response to the user.** Use this when you want the model's *answer* to be in a specific format (e.g., extracting data from a document to save to a database). |944| **Function Calling** | **Taking action during the conversation.** Use this when the model needs to *ask you* to perform a task (e.g., "get current weather") before it can provide a final answer. |945946## Best practices947948- **Clear descriptions:** Use the `description` field in your schema to provide clear instructions to the model about what each property represents. This is crucial for guiding the model's output.949- **Strong typing:** Use specific types (`integer`, `string`, `enum`) whenever possible. If a parameter has a limited set of valid values, use an `enum`.950- **Prompt engineering:** Clearly state in your prompt what you want the model to do. For example, "Extract the following information from the text..." or "Classify this feedback according to the provided schema...".951- **Validation:** While structured output guarantees syntactically correct JSON, it does not guarantee the values are semantically correct. Always validate the final output in your application code before using it.952- **Error handling:** Implement robust error handling in your application to gracefully manage cases where the model's output, while schema-compliant, may not meet your business logic requirements.953954## Limitations955956- **Schema subset:** Not all features of the JSON Schema specification are supported. The model ignores unsupported properties.957- **Schema complexity:** The API may reject very large or deeply nested schemas. If you encounter errors, try simplifying your schema by shortening property names, reducing nesting, or limiting the number of constraints.