> ## Documentation Index
> Fetch the complete documentation index at: https://docs.portkey.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Structured Outputs

> Direct models to return data that conforms to a specific JSON schema.

Structured Outputs ensure that models follow your supplied [JSON schema](https://json-schema.org/overview/what-is-jsonschema). The Prisma AIRS AI Gateway supports this for Anthropic models using a unified `response_format` interface.

Define object schemas using [Pydantic](https://docs.pydantic.dev/latest/) (Python) or [Zod](https://zod.dev/) (JavaScript) to extract structured information from unstructured text.

### 1. Using Pydantic or Zod (Recommended)

This approach provides type hinting and automatic validation.

```sh cURL theme={"system"}
curl https://aigw.portkey.ai/v1/chat/completions \
  -H "Authorization: Bearer $PORTKEY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "@anthropic-provider/claude-3-5-sonnet-20241022",
    "messages": [
      {"role": "system", "content": "You are a helpful math tutor. Guide the user through the solution step by step."},
      {"role": "user", "content": "how can I solve 8x + 7 = -23"}
    ],
    "response_format": {
      "type": "json_schema",
      "json_schema": {
        "name": "math_reasoning",
        "schema": {
          "type": "object",
          "properties": {
            "steps": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "explanation": {"type": "string"},
                  "output": {"type": "string"}
                },
                "required": ["explanation", "output"],
                "additionalProperties": false
              }
            },
            "final_answer": {"type": "string"}
          },
          "required": ["steps", "final_answer"],
          "additionalProperties": false
        }
      }
    }
  }'
```

```python Anthropic Python SDK theme={"system"}
import json, re
from anthropic import Anthropic
from pydantic import BaseModel

class Step(BaseModel):
    explanation: str
    output: str

class MathReasoning(BaseModel):
    steps: list[Step]
    final_answer: str

def parse(client, model, messages, response_model):
    schema = response_model.model_json_schema()

    msg = client.messages.create(
        model=model,
        max_tokens=1024,
        system=f"Return ONLY JSON matching this schema:\n{json.dumps(schema)}",
        messages=messages
    )
    text = msg.content[0].text
    json_text = re.search(r"\{.*\}", text, re.S).group(0)

    return response_model.model_validate(json.loads(json_text))

client = Anthropic(
    auth_token="PORTKEY_API_KEY",
    base_url="https://aigw.portkey.ai"
)

completion = parse(
    client,
    "@anthropic-testing/claude-sonnet-4-6",
    [{"role": "user", "content": "how can I solve 8x + 7 = -23"}],
    MathReasoning
)
print(completion)
```

```javascript Anthropic JS SDK theme={"system"}
import Anthropic from "@anthropic-ai/sdk";
import { z } from "zod";

const Step = z.object({
    explanation: z.string(),
    output: z.string(),
});

const MathReasoning = z.object({
    steps: z.array(Step),
    final_answer: z.string(),
});

const client = new Anthropic({
    authToken: "PORTKEY_API_KEY",
    baseURL: "https://aigw.portkey.ai",
});

async function main() {
    const completion = await client.messages.create({
        model: "@anthropic-testing/claude-sonnet-4-6",
        max_tokens: 1024,
        system: "Return ONLY valid JSON matching the schema: {steps:[{explanation:string,output:string}], final_answer:string}",
        messages: [
            { role: "user", content: "how can I solve 8x + 7 = -23" }
        ],
    });

    const text = completion.content[0].text;

    const jsonText = text.match(/\{[\s\S]*\}/)[0];

    const result = MathReasoning.parse(JSON.parse(jsonText));

    console.log(result);
}

main().catch(console.error);
```

### 2. Using Raw JSON Schema

For cross-language compatibility or dynamic schemas, pass a standard JSON schema directly.

```sh cURL theme={"system"}
curl https://aigw.portkey.ai/v1/chat/completions \
  -H "Authorization: Bearer $PORTKEY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "@anthropic-provider/claude-3-5-sonnet-20241022",
    "messages": [
      { "role": "system", "content": "Extract event information." },
      { "role": "user", "content": "Alice and Bob are going to a science fair on Friday." }
    ],
    "response_format": {
      "type": "json_schema",
      "json_schema": {
        "name": "event_extraction",
        "schema": {
          "type": "object",
          "properties": {
            "location": { "type": "string" },
            "date": { "type": "string" },
            "participants": { "type": "array", "items": { "type": "string" } }
          },
          "required": ["location", "date", "participants"],
          "additionalProperties": false
        },
        "strict": true
      }
    }
  }'
```

```python Anthropic Python SDK theme={"system"}
from anthropic import Anthropic
import json

client = Anthropic(
    auth_token="PORTKEY_API_KEY",
    base_url="https://aigw.portkey.ai" )

schema = {
    "type": "object",
    "properties": {
        "location": {"type": "string"},
        "date": {"type": "string"},
        "participants": {
            "type": "array",
            "items": {"type": "string"}
        }
    },
    "required": ["location", "date", "participants"],
    "additionalProperties": False
}

prompt = f"""
Extract the event information from the sentence.

Return ONLY valid JSON matching this schema:
{json.dumps(schema, indent=2)}

Sentence:
Alice and Bob are going to a science fair on Friday.
"""

response = client.messages.create(
    model="@anthropic-testing/claude-sonnet-4-6",
    max_tokens=200,
    system="You are an information extraction system. Only return valid JSON.",
    messages=[
        {
            "role": "user",
            "content": prompt
        }
    ]
)

print(response.content[0].text)
```

```javascript Anthropic JS SDK theme={"system"}
import Anthropic from '@anthropic-ai/sdk';

const client = new Anthropic({
    authToken: "PORTKEY_API_KEY",
    baseURL: "https://aigw.portkey.ai",

});

async function main() {
    const message = await client.messages.create({
        model: "@anthropic-testing/claude-sonnet-4-6",
        max_tokens: 1024,
        messages: [{ role: "user", content: "Alice and Bob are going to a science fair on Friday." }],
        response_format: {
            type: "json_schema",
            json_schema: {
                name: "event_extraction",
                schema: {
                    type: "object",
                    properties: {
                        location: { type: "string" },
                        date: { type: "string" },
                        participants: { type: "array", items: { type: "string" } }
                    },
                    required: ["location", "date", "participants"],
                    additionalProperties: false
                },
                strict: true
            }
        }
    });

    console.log(message.content);
}

main().catch(console.error);
```

For more, refer to Anthropic's [detailed documentation on Structured Outputs here](https://docs.anthropic.com/en/docs/build-with-claude/structured-outputs).


## Related topics

- [Structured Outputs](https://docs.portkey.ai/docs/aigw/integrations/llms/openai/structured-outputs.md)
- [Anthropic](https://docs.portkey.ai/docs/aigw/integrations/llms/anthropic.md)
- [Open Responses](https://docs.portkey.ai/docs/aigw/product/ai-gateway/responses-api.md)
- [Messages](https://docs.portkey.ai/docs/aigw/product/ai-gateway/messages-api.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.