Structured Outputs

Get type-safe JSON responses that conform to a specific schema. Perfect for building reliable applications that need predictable output formats.

What are Structured Outputs?

Structured outputs ensure that AI responses conform to a specific JSON schema. Instead of hoping the AI returns valid JSON, you can guarantee it by providing a schema that the model must follow.

❌ Without Structured Outputs

"Please return JSON with name and age fields"

May return invalid JSON, missing fields, or wrong types

✅ With Structured Outputs

Provide JSON schema with required fields and types

Guaranteed valid JSON matching your exact schema

Basic Example

structured-output.ts
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'https://www.superagentstack.com/api/v1',
  apiKey: process.env.OPENROUTER_KEY,
  defaultHeaders: { 'superAgentKey': process.env.SUPER_AGENT_KEY },
});

const response = await client.chat.completions.create({
  model: 'openai/gpt-4o',
  messages: [{
    role: 'user',
    content: 'Extract the person\'s information: "Hi, I\'m John Doe, 25 years old from NYC"'
  }],
  response_format: {
    type: 'json_schema',
    json_schema: {
      name: 'person_info',
      strict: true,
      schema: {
        type: 'object',
        properties: {
          name: { type: 'string', description: 'Full name' },
          age: { type: 'number', description: 'Age in years' },
          location: { type: 'string', description: 'City or location' }
        },
        required: ['name', 'age', 'location'],
        additionalProperties: false
      }
    }
  }
});

// Parse the guaranteed valid JSON
const person = JSON.parse(response.choices[0].message.content!);
console.log(person);
// Output: { name: "John Doe", age: 25, location: "NYC" }

Response Format Types

TypeDescriptionUse Case
textDefault text responseGeneral conversations
json_objectValid JSON without schemaFlexible JSON responses
json_schemaJSON matching exact schemaType-safe structured data

Supported Schema Types

TypeDescriptionExample
stringText values"John Doe"
numberNumeric values25, 3.14
booleanTrue/false valuestrue, false
arrayLists of items["item1", "item2"]
objectNested objects{"key": "value"}
enumPredefined values"red", "green", "blue"

Complex Schema Example

complex-schema.ts
const response = await client.chat.completions.create({
  model: 'openai/gpt-4o',
  messages: [{ role: 'user', content: 'Analyze this product review...' }],
  response_format: {
    type: 'json_schema',
    json_schema: {
      name: 'review_analysis',
      strict: true,
      schema: {
        type: 'object',
        properties: {
          sentiment: {
            type: 'string',
            enum: ['positive', 'negative', 'neutral']
          },
          rating: {
            type: 'number',
            minimum: 1,
            maximum: 5
          },
          key_points: {
            type: 'array',
            items: { type: 'string' },
            maxItems: 5
          },
          categories: {
            type: 'object',
            properties: {
              quality: { type: 'number', minimum: 1, maximum: 5 },
              price: { type: 'number', minimum: 1, maximum: 5 },
              service: { type: 'number', minimum: 1, maximum: 5 }
            },
            required: ['quality', 'price', 'service']
          },
          would_recommend: { type: 'boolean' }
        },
        required: ['sentiment', 'rating', 'key_points', 'categories', 'would_recommend']
      }
    }
  }
});

const analysis = JSON.parse(response.choices[0].message.content!);
// Guaranteed structure with all fields

Streaming with Structured Outputs

Structured outputs work with streaming. The JSON is built incrementally and validated when complete.

streaming-structured.ts
const stream = await client.chat.completions.create({
  model: 'openai/gpt-4o',
  messages: [{ role: 'user', content: 'Generate a story outline' }],
  stream: true,
  response_format: {
    type: 'json_schema',
    json_schema: {
      name: 'story_outline',
      schema: {
        type: 'object',
        properties: {
          title: { type: 'string' },
          characters: {
            type: 'array',
            items: {
              type: 'object',
              properties: {
                name: { type: 'string' },
                role: { type: 'string' }
              },
              required: ['name', 'role']
            }
          },
          plot: { type: 'string' }
        },
        required: ['title', 'characters', 'plot']
      }
    }
  }
});

let content = '';
for await (const chunk of stream) {
  const delta = chunk.choices[0]?.delta?.content;
  if (delta) {
    content += delta;
    console.log('Partial:', content);
  }
}

// Final content is guaranteed valid JSON
const outline = JSON.parse(content);

curl Example

bash
curl -X POST https://www.superagentstack.com/api/v1/chat/completions \
  -H "Authorization: Bearer $OPENROUTER_KEY" \
  -H "superAgentKey: $SUPER_AGENT_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4o",
    "messages": [{"role": "user", "content": "Extract: John, 25, NYC"}],
    "response_format": {
      "type": "json_schema",
      "json_schema": {
        "name": "person",
        "strict": true,
        "schema": {
          "type": "object",
          "properties": {
            "name": {"type": "string"},
            "age": {"type": "number"},
            "city": {"type": "string"}
          },
          "required": ["name", "age", "city"]
        }
      }
    }
  }'

Model Support

✅ Fully Supported

  • • OpenAI GPT-4o, GPT-4o-mini
  • • Google Gemini 2.0 Flash
  • • Anthropic Claude 3.5 Sonnet
  • • Meta Llama 3.1 70B+

⚠️ Limited Support

  • • Smaller models may not follow complex schemas
  • • Some models only support simple JSON
  • • Check OpenRouter model pages for details

Best Practices

Keep Schemas Simple

Start with simple schemas and gradually add complexity. Very complex schemas may be harder for models to follow consistently.

Use Descriptions

Add clear descriptions to your schema properties. This helps the model understand what each field should contain.

Set Constraints

Use minimum, maximum, maxItems, and enumto constrain values and improve reliability.

Next Steps