Get structured JSON from Claude without tool use. Use system prompts + temperature=0 to extract entities, classify text, and parse structured data.
Two patterns for getting structured JSON from Claude: prompt-based (simple) and tool-based (schema-validated).
import anthropic
import json
client = anthropic.Anthropic()
def extract_json(text: str, schema_desc: str) -> dict:
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
temperature=0,
system=f"""Extract structured data from text and return ONLY valid JSON.
Schema: {schema_desc}
Rules:
- Return only the JSON object, no markdown, no explanation
- Use null for missing fields
- Follow the exact field names in the schema""",
messages=[{"role": "user", "content": text}]
)
return json.loads(response.content[0].text)
# Example: extract contact info
result = extract_json(
"Call Sarah Johnson at sarah.j@company.com or +1-555-0123 for the Q3 budget review.",
'{"name": string, "email": string, "phone": string, "topic": string}'
)
print(result)
# {"name": "Sarah Johnson", "email": "sarah.j@company.com", "phone": "+1-555-0123", "topic": "Q3 budget review"}
def extract_with_tool(text: str) -> dict:
tool = {
"name": "extract_contact",
"description": "Extract contact information from text.",
"input_schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"email": {"type": "string", "format": "email"},
"phone": {"type": ["string", "null"]},
"topic": {"type": "string"}
},
"required": ["name", "email", "topic"]
}
}
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=512,
tools=[tool],
tool_choice={"type": "tool", "name": "extract_contact"},
messages=[{"role": "user", "content": text}]
)
for block in response.content:
if block.type == "tool_use":
return block.input
return {}
result = extract_with_tool("Please contact John Smith (jsmith@corp.io) re: contract renewal.")
print(result)
def classify(text: str, categories: list[str]) -> dict:
response = client.messages.create(
model="claude-haiku-4-5-20251001", # fast and cheap for classification
max_tokens=64,
temperature=0,
system=f'Classify the text. Return JSON: {{"category": one of {categories}, "confidence": 0.0-1.0, "reason": "brief"}}. Only JSON, no explanation.',
messages=[{"role": "user", "content": text}]
)
return json.loads(response.content[0].text)
result = classify("My bill was charged twice!", ["billing", "technical", "shipping", "general"])
print(result)
# {"category": "billing", "confidence": 0.98, "reason": "Duplicate charge complaint"}
See the full tool use guide for complex multi-step agent loops. Haiku 4.5 is cheapest for high-volume classification — see Haiku pricing.