GEMINI LABJP
NANOLITE — Nano Banana 2 Lite is here: Google's fastest and most cost-efficient Gemini Image model, made for running lightweight image generation cheaplyOMNIFLASH — Gemini Omni Flash is in public preview, a natively multimodal model that lets enterprises and developers build custom, dynamic video workflowsAGENTS — Managed Agents expand with background: true for async server-side runs and polling, remote MCP server integration, and refreshing credentials across interactionsMEMORY — The Memory Bank IngestEvents API is generally available, decoupling event ingestion from memory generation so you can stream content continuouslyTHROUGHPUT — Provisioned Throughput now lets you submit up to seven pending orders for the same model and regionDEPRECATE — Image generation models shut down on August 17, and the Grok 4.1 family on the Gemini Enterprise Agent Platform on August 20NANOLITE — Nano Banana 2 Lite is here: Google's fastest and most cost-efficient Gemini Image model, made for running lightweight image generation cheaplyOMNIFLASH — Gemini Omni Flash is in public preview, a natively multimodal model that lets enterprises and developers build custom, dynamic video workflowsAGENTS — Managed Agents expand with background: true for async server-side runs and polling, remote MCP server integration, and refreshing credentials across interactionsMEMORY — The Memory Bank IngestEvents API is generally available, decoupling event ingestion from memory generation so you can stream content continuouslyTHROUGHPUT — Provisioned Throughput now lets you submit up to seven pending orders for the same model and regionDEPRECATE — Image generation models shut down on August 17, and the Grok 4.1 family on the Gemini Enterprise Agent Platform on August 20
Articles/API / SDK
API / SDK/2026-06-20Advanced

Gemini API Grounding × Structured Output Guide — Turn Web Search Results into Typed JSON Data

Combine Gemini API Grounding with Google Search and Structured Output to extract real-time web information as type-safe JSON data. Practical implementation patterns included.

Gemini API192Grounding4Structured Output9Google Search2JSONreal-time dataagents9

Premium Article

You want the Gemini API to fetch external information and return it as structured data. Until recently, you couldn't do both at the same time. Enabling Grounding with Google Search blocked Structured Output, and vice versa. The Gemini 3 API update finally removed this restriction.

Getting web search results back as JSON that matches your type definitions — this combination means you can now handle tasks like "fetch current exchange rates and return them as a JSON array" or "search competitor product prices and format them for a comparison table" in a single API call.

The Problem This Combination Solves

The old approach required a two-stage pipeline.

First API call: use Grounding to fetch web information, receive a text response. Second API call: feed that text into Structured Output to get JSON. Double the cost, double the latency, and a real risk of information loss when re-feeding the text response.

The unified API lets you specify Google Search in tools while defining a JSON schema via response_mime_type. The model executes the search, interprets the results, and converts everything into your specified type — all in one step.

from google import genai
from google.genai import types
import json
 
client = genai.Client()
 
# Combined Grounding + Structured Output request
response = client.models.generate_content(
    model="gemini-2.5-pro",
    contents="Look up the current Gemini API pricing as of April 2026, organized by model",
    config=types.GenerateContentConfig(
        tools=[types.Tool(google_search=types.GoogleSearch())],
        response_mime_type="application/json",
        response_schema={
            "type": "object",
            "properties": {
                "pricing_data": {
                    "type": "array",
                    "items": {
                        "type": "object",
                        "properties": {
                            "model_name": {"type": "string"},
                            "input_price_per_million": {"type": "string"},
                            "output_price_per_million": {"type": "string"},
                            "context_window": {"type": "string"},
                        },
                        "required": [
                            "model_name",
                            "input_price_per_million",
                            "output_price_per_million"
                        ]
                    }
                },
                "last_updated": {"type": "string"},
                "source_urls": {
                    "type": "array",
                    "items": {"type": "string"}
                }
            },
            "required": ["pricing_data", "last_updated"]
        }
    )
)
 
# Type-safe JSON returned directly
data = json.loads(response.text)
for model in data["pricing_data"]:
    print(f"{model['model_name']}: input {model['input_price_per_million']}/1M tokens")
 
# Verify sources via grounding metadata
if response.candidates[0].grounding_metadata:
    for chunk in response.candidates[0].grounding_metadata.grounding_chunks:
        print(f"  Source: {chunk.web.title}{chunk.web.uri}")

What you get back is structured JSON derived from live Google Search results. No fields outside your schema, no missing required fields.

Understanding the Response Structure

The combined response includes your Structured Output JSON plus grounding_metadata. This metadata contains the search queries used, source URLs, and citation information.

candidate = response.candidates[0]
 
# 1. Structured JSON text
structured_data = json.loads(candidate.content.parts[0].text)
 
# 2. Grounding metadata
metadata = candidate.grounding_metadata
 
# Queries the model used for searching
print("Search queries:", metadata.web_search_queries)
# → ['Gemini API pricing 2026', 'Gemini 2.5 Pro API cost per token']
 
# Source web pages
for chunk in metadata.grounding_chunks:
    print(f"Source: {chunk.web.title}")
    print(f"  URL: {chunk.web.uri}")
 
# Citation supports (which parts of the response are backed by which sources)
for support in metadata.grounding_supports:
    print(f"Text: {support.segment.text}")
    print(f"  Source indices: {support.grounding_chunk_indices}")
    print(f"  Confidence: {support.confidence_scores}")

One thing to watch out for: when combined with Structured Output, the text response is in JSON format, so grounding_supports segment.text may point to JSON fragments rather than readable sentences. For source verification, the grounding_chunks URL list is more reliable.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
Combine Grounding and Structured Output in a single call to extract web search results as type-safe JSON
A working verification gate that quarantines records by checking grounding_metadata provenance, with threshold design
End-to-end production know-how: schema design, cost structure, and the gotchas that bite real extraction pipelines
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Gemini Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

API / SDK2026-07-04
When Two Managed Agents Fight Over the Same Repo: External Leases and Fencing for Isolated Sandboxes
Every Managed Agents run gets its own isolated sandbox, so a local lock cannot stop two runs from touching the same repo or record. Here is how I serialize them safely with an external lease and a fencing token.
API / SDK2026-06-27
Your Gemini Structured Output Keys Keep Reordering — Pin Them With propertyOrdering
You constrained the shape with responseSchema, yet the JSON key order shifts between calls and your snapshot tests go red for no reason. Here is why field order is not guaranteed by default, how propertyOrdering fixes it, how Pydantic sets it for you, and how to align few-shot examples — all with working code.
API / SDK2026-06-19
Generate Japanese and English in One Structured Call to Stop Term Drift
Generating Japanese and English versions separately makes terminology drift article by article. Pair both languages in one Gemini 3.5 Flash structured-output call, pin a glossary, and detect drift mechanically — with measured results.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →