> ## 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 Claude models on AWS Bedrock 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.

<Note>
  This feature is supported on Claude 3 and later models hosted on AWS Bedrock.
</Note>

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

This approach provides type hinting and automatic validation.

<CodeGroup>
  ```sh cURL theme={"system"}
  curl -X POST https://aigw.portkey.ai/v1/chat/completions \
    -H "Authorization: Bearer PORTKEY_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "@bedrock/global.anthropic.claude-sonnet-4-6",
      "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,
      "@bedrock/global.anthropic.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";
  import { zodToJsonSchema } from "zod-to-json-schema";

  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: "@bedrock/global.anthropic.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);
  ```
</CodeGroup>

### 2. Using Raw JSON Schema

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

<CodeGroup>
  ```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": "@bedrock/global.anthropic.claude-sonnet-4-6",
      "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="@bedrock/global.anthropic.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({
      apiKey: "dummy",
      baseURL: "https://aigw.portkey.ai/v1",
      defaultHeaders: {
          "Authorization": "Bearer PORTKEY_API_KEY"
      }
  });

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

  async function main() {
      const message = await client.messages.create({
          model: "@bedrock/us.anthropic.claude-3-5-sonnet-20241022-v2:0",
          max_tokens: 1024,
          system: `You are an information extraction system. Return ONLY valid JSON matching this schema:\n${JSON.stringify(schema, null, 2)}`,
          messages: [{ role: "user", content: "Alice and Bob are going to a science fair on Friday." }],
      });

      const result = JSON.parse(message.content[0].text);
      console.log(result);
  }

  main();
  ```
</CodeGroup>

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](/docs/aigw/integrations/llms/openai/structured-outputs.md)
- [Anthropic](/docs/aigw/integrations/llms/anthropic.md)
- [Open Responses](/docs/aigw/product/ai-gateway/responses-api.md)
- [Messages](/docs/aigw/product/ai-gateway/messages-api.md)
