Structured outputs and web search
On this page
Combine structured outputs and real-time search
Structured outputs aren’t just for static data. On Grok 4 and later models—meaning the entire current lineup—you can combine structured outputs with web search. The model searches the web for real-time information, then structures the results according to your schema.
Why this combination is powerful
Without this feature, getting structured data from the web requires three separate steps:
- Call a search API (Google, Bing, etc.)
- Parse the raw results
- Send the results to the LLM for structuring
With structured outputs + web search, everything happens in a single call. The model searches, synthesizes, and structures.
Prerequisites: Grok 4 minimum
This feature is available on Grok 4 and later models, which covers the entire current lineup (Grok 4.5, Grok 4.3, grok-4.20 variants). Older Grok 3 and Grok 3 Mini models did not support combining tools with structured outputs.
Example: Competitive intelligence
from pydantic import BaseModel
class Concurrent(BaseModel):
nom: str
site_web: str
produit_phare: str
avantage_principal: str
class VeilleConcurrentielle(BaseModel):
secteur: str
date_analyse: str
concurrents: list[Concurrent]
tendances: list[str]
opportunites: list[str]
response, parsed = client.chat.parse(
model="grok-4.20-0309-reasoning",
messages=[{
"role": "user",
"content": "Perform competitive intelligence on the French neobank market in 2026"
}],
response_format=VeilleConcurrentielle,
tools=[{"type": "web_search"}]
)
for c in parsed.concurrents:
print(f"{c.nom} — {c.avantage_principal}")
The model will:
- Search for current French neobanks on the web
- Collect relevant information
- Structure everything according to the
VeilleConcurrentielleschema
Example: News tracking
class Article(BaseModel):
titre: str
source: str
date: str
resume: str
impact: str
class RevuePresse(BaseModel):
sujet: str
articles: list[Article]
synthese: str
response, parsed = client.chat.parse(
model="grok-4.20-0309-reasoning",
messages=[{
"role": "user",
"content": "What is the latest news on AI regulation in Europe?"
}],
response_format=RevuePresse,
tools=[{"type": "web_search"}]
)
print(parsed.synthese)
for article in parsed.articles:
print(f"[{article.source}] {article.titre}")
Best practices
Be specific in the prompt
Web search works best with specific queries:
# Too vague
"What's new in tech?"
# Precise and actionable
"The 5 largest AI funding rounds in France in Q1 2026"
Adapt your schema to available data
Don’t request data the web cannot reliably provide:
# Hard to find precisely
class Entreprise(BaseModel):
chiffre_affaires_exact: float # rarely public
# Realistic
class Entreprise(BaseModel):
chiffre_affaires_estime: str # "around €50M"
source_estimation: str
Handle missing data
Make fields optional if they might not be found:
class InfoEntreprise(BaseModel):
nom: str
fondateur: str
annee_creation: int
valorisation: str | None # not always available
nombre_employes: str | None
Key takeaways
- The structured outputs + web search combination requires Grok 4 minimum—the entire current lineup is compatible
- Enable web search with
tools=[{"type": "web_search"}] - A single API call replaces a search → parsing → structuring chain
- Be specific in your prompts for better results
- Make fields optional if availability isn’t guaranteed