AI & LLM APIs cookbook · Beginner
Extract structured data with a schema
Turn free-text emails or documents into validated objects your code can store.
Approach
Define the result as a Pydantic model and use client.messages.parse(..., output_format=Model), which returns a
validated instance in parsed_output. Keep business validation (allowed values, ranges) in the model, and
handle the cases where the input really doesn't contain the data.
Solution
from typing import Literal, Optional
import anthropic
from pydantic import BaseModel, Field
client = anthropic.Anthropic()
class Lead(BaseModel):
name: str
email: Optional[str] = None
company: Optional[str] = None
plan: Literal["starter", "team", "enterprise", "unknown"]
seats: Optional[int] = Field(default=None, ge=1, le=100_000)
wants_demo: bool
def extract_lead(email_text: str) -> Lead:
response = client.messages.parse(
model="claude-sonnet-5-5",
max_tokens=1024,
system="Extract the sales lead. Use null for anything the email does not state. Never guess emails.",
messages=[{"role": "user", "content": f"<email>\n{email_text}\n</email>"}],
output_format=Lead,
)
return response.parsed_output
lead = extract_lead("Hi, I'm Priya from Northwind. We'd like Enterprise for about 250 people. Can we see a demo?")
print(lead.model_dump())
Pitfalls
- Making every field required, which pushes the model to invent values; use optional fields and an
unknownchoice. - Trusting schema-valid output blindly: check business rules (for example, that the email domain matches the company) in code.
- Putting the raw document in the system prompt; keep untrusted text in the user turn, inside tags.
Variations
- Use
output_config={"format": {"type": "json_schema", "schema": {...}}}withmessages.createwhen you don't use Pydantic. - For many documents, send the requests through the Batch API at a lower price.
Further reading: Structured outputs
Reference: https://docs.anthropic.com/en/docs/build-with-claude/structured-outputs
More AI & LLM APIs recipes
- Answer with citations that point at the source text
- Build hybrid RAG search on PostgreSQL with pgvector
- Cache a long system prompt and documents
- Cache answers to frequent questions safely
- Classify thousands of items with the Batch API
- Compare two prompt versions with an unbiased model judge
- Expose an internal API as an MCP server
- Fit conversation history into a token budget