System-to-system integration — extraction pipelines, classifiers, routers, form fillers — needs output that parses on the first try, every time. There are three levels of rigor for getting JSON out of Claude on Microsoft Foundry: prompting, tool-based schemas, and the structured outputs feature. Which ones are available depends on a Foundry-specific detail: whether your deployment is "Hosted on Azure" or "Hosted on Anthropic infrastructure".
Option 1: Structured outputs — beta, Hosted on Anthropic only
Anthropic's structured outputs feature constrains generation so the response is guaranteed to match your JSON schema. On Foundry it is beta, and it is one of the features Anthropic explicitly lists as unavailable on "Hosted on Azure" deployments — a request using it against an Azure-hosted deployment returns 400 Bad Request by design. If your organization deployed Claude with Foundry's default settings, you have an Azure-hosted deployment and this option is off the table until you add a Hosted-on-Anthropic deployment. On newer models the feature is configured via output_config.format (the older top-level output_format parameter was migrated there).
Option 2: Tool use as a schema contract — GA everywhere on Foundry
The workhorse pattern, and the one that works on every Foundry deployment: core tool use is GA on both hosting versions. Define a single "tool" whose input schema is your desired output shape, and require Claude to call it. Claude fills in the tool's arguments as JSON conforming to the schema — you never execute anything; you just read the arguments.
from anthropic import AnthropicFoundry
client = AnthropicFoundry(api_key="...", resource="example-resource")
msg = client.messages.create(
model="claude-opus-4-8", max_tokens=1024,
tools=[{
"name": "record_ticket",
"description": "Record the classified support ticket.",
"input_schema": {"type": "object", "properties": {
"category": {"type": "string"},
"priority": {"type": "string"},
"summary": {"type": "string"}},
"required": ["category", "priority", "summary"]},
}],
tool_choice={"type": "tool", "name": "record_ticket"},
messages=[{"role": "user", "content": ticket_text}],
)
data = next(b for b in msg.content if b.type == "tool_use").input
Note that forcing a specific tool with tool_choice adds a modest system-prompt token overhead versus letting Claude choose, and tool schemas count as input tokens — keep them lean.
Option 3: Prompting — the baseline, never the whole answer
Plain prompting ("respond with only a JSON object matching this example, no prose") works surprisingly well with current models, especially when you show a compact example of the exact shape you want in the system prompt. But it is a request, not a contract. Two Foundry-relevant cautions:
- Assistant prefill is gone on current models. The classic trick of pre-seeding the assistant's reply with
{to force JSON returns a400error on Opus 4.7 and later, Sonnet 5, and Fable 5. Anthropic's migration guide points to structured outputs or system-prompt instructions instead. - Always parse defensively. Strip markdown code fences, validate against your schema in code, and route parse failures to a retry with the error message included. If code can check it, code should check it.
Choosing for your deployment
| Technique | Hosted on Azure | Hosted on Anthropic | Status |
|---|---|---|---|
Structured outputs (output_config.format) | No (400) | Yes | Beta |
| Forced tool use with JSON schema | Yes | Yes | GA |
| Prompting + code-side validation | Yes | Yes | Always works, weakest guarantee |
Whichever you pick, build the validation layer anyway. Schema enforcement guarantees shape, not correctness — a well-formed JSON object can still contain a wrong category or an invented order ID, so business-rule checks belong in your code.
Finally, make the output contract testable. Keep a small suite of representative inputs with expected JSON outputs and run it whenever anything changes — the prompt, the schema, or the model behind the deployment. Model upgrades matter more than they look here: moving to a new generation can change how conservatively fields are filled, and on Foundry an upgrade is a new deployment your staging environment can exercise before production traffic moves. A ten-case golden-file test catches most schema regressions for pennies.
Where to go next
The tool-use mechanics are covered in using Claude tool use on Foundry. For platform-neutral background, read structured outputs, and see Foundry beta caveats before adopting the beta path in production.