# Structured Output

Structured Outputs ensure model responses conform to predefined formats, enabling type-safe, predictable integration with your applications.

## What are Structured Outputs?

Instead of parsing free-form text, Structured Outputs guarantee the model returns data in a specific format you define—whether simple JSON or complex schemas with nested objects and arrays.


```
Standard Output: Structured Output:
------------------- ---------------------
"The user is 25 {
years old and "name": "Alice",
lives in Paris." "age": 25,
 "location": "Paris"
 }
```

## Quick Start

Get started with JSON mode in 3 simple steps:


```python
import requests
import os

# 1. Set output_mode to "json"
response = requests.post(
 "https://api.aitronos.com/v1/model/response",
 headers={"X-API-Key": os.environ['FREDDY_API_KEY']},
 json={
 "organization_id": "org_abc123",
 "model": "gpt-4o",
 "output_mode": "json", # Enable JSON mode
 "inputs": [{
 "role": "user",
 "content": "Extract the product name, price, and rating from: 'iPhone 15 Pro - $999 - 4.5 stars'"
 }]
 }
)

# 2. Get guaranteed valid JSON
result = response.json()
data = result["output"][0]["content"][0]["text"]

# 3. Parse and use
import json
product = json.loads(data)
print(f"Product: {product['name']}, Price: {product['price']}")
```

That's it! The model returns valid JSON every time.

## Output Modes

### 1. **`text` Mode** (Default)

Standard free-form text responses.


```json
{
 "outputMode": "text",
 "inputs": [
 {"role": "user", "content": "What is Python?"}
 ]
}
```

**Response:**


```
Python is a high-level, interpreted programming language...
```

**Use when:**

- Natural conversation
- Creative writing
- Open-ended queries


### 2. **`json` Mode**

Forces the model to return valid JSON. The model determines the structure based on your prompt.


```json
{
 "organization_id": "org_abc123",
 "model": "gpt-4o",
 "output_mode": "json",
 "inputs": [
 {
 "role": "user",
 "content": "Extract name, age, and city from: 'Alice is 25 and lives in Paris'"
 }
 ]
}
```

**Response:**


```json
{
 "name": "Alice",
 "age": 25,
 "city": "Paris"
}
```

**Key features:**

- **Guarantees valid JSON** - No parsing errors
- **Flexible structure** - Model decides format based on context
- **No schema required** - Just set the mode
- **Prompt-driven** - Describe desired structure in your prompt


**Use when:**

- Need valid JSON but structure varies by request
- Quick prototyping and experimentation
- Structure is implied by prompt context
- Building dynamic responses where schema isn't fixed


**Example use cases:**


```python
# Dynamic data extraction
response = requests.post(
 "https://api.aitronos.com/v1/model/response",
 headers={"X-API-Key": api_key},
 json={
 "organization_id": "org_abc123",
 "model": "gpt-4o",
 "output_mode": "json",
 "inputs": [{
 "role": "user",
 "content": "Analyze this product review and return sentiment, key points, and rating: 'Great product! Fast shipping. Would buy again. 5 stars.'"
 }]
 }
)

# Returns flexible JSON like:
# {
# "sentiment": "positive",
# "key_points": ["great product", "fast shipping", "would repurchase"],
# "rating": 5,
# "recommendation": "highly recommended"
# }
```

### 3. **`json_schema` Mode**

Most powerful option - define exact structure using JSON Schema. The model **guarantees** output matching your schema.


```json
{
 "organization_id": "org_abc123",
 "model": "gpt-4o",
 "output_mode": "json_schema",
 "json_schema": {
 "id": "user_profile_v1",
 "description": "User profile extraction schema",
 "strict": true,
 "schema": {
 "type": "object",
 "properties": {
 "name": {"type": "string"},
 "age": {"type": "integer"},
 "city": {"type": "string"}
 },
 "required": ["name", "age", "city"],
 "additionalProperties": false
 }
 },
 "inputs": [
 {
 "role": "user",
 "content": "Extract: 'Alice is 25 and lives in Paris'"
 }
 ]
}
```

**Response (guaranteed structure):**


```json
{
 "name": "Alice",
 "age": 25,
 "city": "Paris"
}
```

**Key features:**

- **100% schema compliance** - No exceptions, guaranteed structure
- **Type safety** - Integers are integers, strings are strings, no type coercion
- **Validation** - Required fields always present, no missing data
- **Predictable** - Same structure every time, perfect for automation
- **Multiple schemas** - Provide multiple schemas; model selects appropriate one


**Use when:**

- Type safety is critical for your application
- Integrating with typed languages (TypeScript, Go, Rust, Java)
- Direct database insertions without validation
- Production API responses requiring consistency
- Compliance and audit requirements


## JSON Schema

### Basic Schema Example


```json
{
 "id": "simple_schema",
 "schema": {
 "type": "object",
 "properties": {
 "task": {"type": "string"},
 "completed": {"type": "boolean"},
 "priority": {"type": "integer", "minimum": 1, "maximum": 5}
 },
 "required": ["task", "completed"]
 }
}
```

### Supported Types

#### Primitives


```json
{
 "type": "object",
 "properties": {
 "text": {"type": "string"},
 "count": {"type": "integer"},
 "price": {"type": "number"},
 "active": {"type": "boolean"},
 "data": {"type": "null"}
 }
}
```

#### Arrays


```json
{
 "type": "object",
 "properties": {
 "tags": {
 "type": "array",
 "items": {"type": "string"}
 },
 "scores": {
 "type": "array",
 "items": {"type": "integer"},
 "minItems": 1,
 "maxItems": 10
 }
 }
}
```

#### Nested Objects


```json
{
 "type": "object",
 "properties": {
 "user": {
 "type": "object",
 "properties": {
 "name": {"type": "string"},
 "email": {"type": "string", "format": "email"}
 },
 "required": ["name", "email"]
 }
 }
}
```

#### Enums


```json
{
 "type": "object",
 "properties": {
 "status": {
 "type": "string",
 "enum": ["pending", "in_progress", "completed", "failed"]
 },
 "priority": {
 "type": "string",
 "enum": ["low", "medium", "high"]
 }
 }
}
```

### Advanced Schema Features

#### Constraints


```json
{
 "type": "object",
 "properties": {
 "username": {
 "type": "string",
 "minLength": 3,
 "maxLength": 20,
 "pattern": "^[a-zA-Z0-9_]+$"
 },
 "age": {
 "type": "integer",
 "minimum": 0,
 "maximum": 120
 },
 "email": {
 "type": "string",
 "format": "email"
 },
 "website": {
 "type": "string",
 "format": "uri"
 }
 }
}
```

#### Optional vs Required


```json
{
 "type": "object",
 "properties": {
 "id": {"type": "string"}, // Required (in required array)
 "name": {"type": "string"}, // Required
 "description": {"type": "string"} // Optional (not in required array)
 },
 "required": ["id", "name"],
 "additionalProperties": false // Reject unknown properties
}
```

#### Complex Example: E-commerce Order


```json
{
 "id": "order_schema_v2",
 "strict": true,
 "schema": {
 "type": "object",
 "properties": {
 "orderId": {"type": "string"},
 "customer": {
 "type": "object",
 "properties": {
 "name": {"type": "string"},
 "email": {"type": "string", "format": "email"},
 "address": {
 "type": "object",
 "properties": {
 "street": {"type": "string"},
 "city": {"type": "string"},
 "zipCode": {"type": "string"}
 },
 "required": ["street", "city", "zipCode"]
 }
 },
 "required": ["name", "email", "address"]
 },
 "items": {
 "type": "array",
 "items": {
 "type": "object",
 "properties": {
 "productId": {"type": "string"},
 "name": {"type": "string"},
 "quantity": {"type": "integer", "minimum": 1},
 "price": {"type": "number", "minimum": 0}
 },
 "required": ["productId", "name", "quantity", "price"]
 },
 "minItems": 1
 },
 "total": {"type": "number", "minimum": 0},
 "status": {
 "type": "string",
 "enum": ["pending", "processing", "shipped", "delivered", "cancelled"]
 }
 },
 "required": ["orderId", "customer", "items", "total", "status"],
 "additionalProperties": false
 }
}
```

## Use Cases

### 1. Data Extraction

Extract structured information from unstructured text:


```python
response = requests.post(
 'https://api.aitronos.com/v1/model/response',
 json={
 "model": "gpt-4o",
 "outputMode": "json_schema",
 "jsonSchema": {
 "id": "contact_extraction",
 "schema": {
 "type": "object",
 "properties": {
 "name": {"type": "string"},
 "email": {"type": "string"},
 "phone": {"type": "string"},
 "company": {"type": "string"}
 },
 "required": ["name"]
 }
 },
 "inputs": [{
 "role": "user",
 "content": "Extract contact: John Doe, john@example.com, works at Acme Corp"
 }]
 }
)
```

### 2. API Response Generation

Generate API-ready responses:


```javascript
const response = await fetch('/v1/model/response', {
 method: 'POST',
 body: JSON.stringify({
 model: 'gpt-4o',
 outputMode: 'json_schema',
 jsonSchema: {
 id: 'api_response',
 schema: {
 type: 'object',
 properties: {
 success: { type: 'boolean' },
 data: {
 type: 'object',
 properties: {
 userId: { type: 'string' },
 message: { type: 'string' }
 }
 },
 error: {
 type: 'object',
 properties: {
 code: { type: 'string' },
 message: { type: 'string' }
 }
 }
 },
 required: ['success']
 }
 },
 inputs: [{
 role: 'user',
 texts: [{ text: 'Generate success response for user creation' }]
 }]
 })
});
```

### 3. Database Record Generation

Create type-safe database entries:


```python
# Generate database record
schema = {
 "id": "user_record",
 "schema": {
 "type": "object",
 "properties": {
 "id": {"type": "string"},
 "username": {"type": "string"},
 "email": {"type": "string", "format": "email"},
 "role": {"type": "string", "enum": ["user", "admin", "moderator"]},
 "created_at": {"type": "string", "format": "date-time"},
 "active": {"type": "boolean"}
 },
 "required": ["id", "username", "email", "role", "active"]
 }
}

result = generate_response(outputMode="json_schema", jsonSchema=schema)

# Direct database insertion (no validation needed!)
db.users.insert_one(result)
```

### 4. TypeScript Integration

Generate type-safe responses for TypeScript:


```typescript
// Define TypeScript interface
interface UserProfile {
 id: string;
 name: string;
 age: number;
 email: string;
 interests: string[];
}

// Matching JSON Schema
const schema = {
 id: 'user_profile',
 schema: {
 type: 'object',
 properties: {
 id: { type: 'string' },
 name: { type: 'string' },
 age: { type: 'integer' },
 email: { type: 'string', format: 'email' },
 interests: { type: 'array', items: { type: 'string' } }
 },
 required: ['id', 'name', 'age', 'email', 'interests']
 }
};

// API call with type safety
const response = await createResponse({
 outputMode: 'json_schema',
 jsonSchema: schema,
 inputs: [...]
});

const user: UserProfile = response.output[0].content[0].data; // Type-safe!
```

## Comparison: JSON vs JSON Schema

| Feature | `json` Mode | `json_schema` Mode |
|  --- | --- | --- |
| **Valid JSON** | Guaranteed | Guaranteed |
| **Structure control** | Model decides | You define exactly |
| **Type enforcement** | Best effort | Strict (int vs string) |
| **Required fields** | May be missing | Always present |
| **Schema validation** | None | 100% compliant |
| **Setup complexity** | Simple (just set mode) | Requires schema definition |
| **Flexibility** | Adapts to context | Fixed structure |
| **Use case** | Prototyping, dynamic | Production, type-safe |
| **Performance** | Fast | Slightly slower (~5-10%) |


## When to Use Each Mode

### Use `json` Mode When:

**Prototyping** - Quick experiments without schema overhead
**Dynamic structures** - Output format varies by request
**Exploratory analysis** - Discovering what structure works best
**Flexible responses** - Model adapts structure to content
**Simple extraction** - Basic data extraction tasks

**Example scenarios:**

- Analyzing customer feedback (structure varies by feedback type)
- Extracting entities from diverse documents
- Building chatbots with dynamic response formats
- Quick data transformations


### Use `json_schema` Mode When:

**Production systems** - Type safety prevents runtime errors
**Database operations** - Direct insertion without validation
**API integrations** - Consistent structure for downstream systems
**Typed languages** - TypeScript, Go, Rust, Java integration
**Compliance** - Audit trails require predictable formats
**Critical data** - Financial, medical, legal applications

**Example scenarios:**

- E-commerce order processing
- Medical record extraction
- Financial transaction parsing
- CRM data synchronization
- Automated report generation


## Real-World Examples

### Example 1: Customer Support Ticket Analysis (JSON Mode)


```python
import requests
import os

# Analyze support tickets with flexible structure
response = requests.post(
 "https://api.aitronos.com/v1/model/response",
 headers={"X-API-Key": os.environ['FREDDY_API_KEY']},
 json={
 "organization_id": "org_abc123",
 "model": "gpt-4o",
 "output_mode": "json",
 "inputs": [{
 "role": "user",
 "content": """Analyze this support ticket and extract key information:

 Subject: Login issues on mobile app
 From: john@example.com
 Message: I can't log into the iOS app. It keeps saying 'invalid credentials'
 but I'm sure my password is correct. This started yesterday after the update.

 Return JSON with: issue_type, priority, affected_platform, user_email,
 suggested_solution, and any other relevant fields."""
 }]
 }
)

result = response.json()
ticket_data = json.loads(result["output"][0]["content"][0]["text"])

# Model returns flexible structure:
# {
# "issue_type": "authentication",
# "priority": "high",
# "affected_platform": "iOS",
# "user_email": "john@example.com",
# "suggested_solution": "Password reset or cache clear",
# "started_after": "app update",
# "error_message": "invalid credentials"
# }
```

### Example 2: E-commerce Order Processing (JSON Schema Mode)


```python
# Define strict schema for order processing
order_schema = {
 "id": "order_processing_v1",
 "description": "E-commerce order extraction schema",
 "strict": True,
 "schema": {
 "type": "object",
 "properties": {
 "order_id": {"type": "string"},
 "customer": {
 "type": "object",
 "properties": {
 "name": {"type": "string"},
 "email": {"type": "string", "format": "email"},
 "phone": {"type": "string"}
 },
 "required": ["name", "email"]
 },
 "items": {
 "type": "array",
 "items": {
 "type": "object",
 "properties": {
 "product_id": {"type": "string"},
 "name": {"type": "string"},
 "quantity": {"type": "integer", "minimum": 1},
 "price": {"type": "number", "minimum": 0}
 },
 "required": ["product_id", "name", "quantity", "price"]
 },
 "minItems": 1
 },
 "total": {"type": "number", "minimum": 0},
 "shipping_address": {
 "type": "object",
 "properties": {
 "street": {"type": "string"},
 "city": {"type": "string"},
 "state": {"type": "string"},
 "zip": {"type": "string"}
 },
 "required": ["street", "city", "state", "zip"]
 }
 },
 "required": ["order_id", "customer", "items", "total", "shipping_address"],
 "additionalProperties": False
 }
}

response = requests.post(
 "https://api.aitronos.com/v1/model/response",
 headers={"X-API-Key": os.environ['FREDDY_API_KEY']},
 json={
 "organization_id": "org_abc123",
 "model": "gpt-4o",
 "output_mode": "json_schema",
 "json_schema": order_schema,
 "inputs": [{
 "role": "user",
 "content": """Extract order details from this email:

 Order #12345
 Customer: Jane Smith (jane@example.com, 555-0123)
 Items:
 - Product A123: Wireless Mouse x2 @ $29.99 each
 - Product B456: USB Cable x1 @ $9.99
 Total: $69.97
 Ship to: 123 Main St, Springfield, IL 62701"""
 }]
 }
)

# Guaranteed structure - safe for direct database insertion
order_data = json.loads(response.json()["output"][0]["content"][0]["text"])
db.orders.insert_one(order_data) # No validation needed!
```

### Example 3: Resume Parsing (JSON Mode)


```javascript
// Parse resumes with flexible structure
const response = await fetch('https://api.aitronos.com/v1/model/response', {
 method: 'POST',
 headers: {
 'X-API-Key': process.env.FREDDY_API_KEY,
 'Content-Type': 'application/json'
 },
 body: JSON.stringify({
 organization_id: 'org_abc123',
 model: 'gpt-4o',
 output_mode: 'json',
 inputs: [{
 role: 'user',
 texts: [{
 text: `Parse this resume and extract all relevant information in JSON format:

 John Doe
 Software Engineer
 john.doe@email.com | (555) 123-4567 | linkedin.com/in/johndoe

 EXPERIENCE
 Senior Developer at Tech Corp (2020-2023)
 - Led team of 5 developers
 - Built microservices architecture
 - Increased performance by 40%

 EDUCATION
 BS Computer Science, MIT (2016-2020)

 SKILLS
 Python, JavaScript, AWS, Docker, Kubernetes`
 }]
 }]
 })
});

const result = await response.json();
const resume = JSON.parse(result.response[0].text);

// Model adapts structure to resume content:
// {
// "name": "John Doe",
// "title": "Software Engineer",
// "contact": {
// "email": "john.doe@email.com",
// "phone": "(555) 123-4567",
// "linkedin": "linkedin.com/in/johndoe"
// },
// "experience": [...],
// "education": [...],
// "skills": [...]
// }
```

## Best Practices

### DO

- **Use `json_schema` for production** - Type safety prevents runtime errors
- **Use `json` for prototyping** - Faster iteration without schema overhead
- **Version schema IDs** - `user_profile_v2` for tracking changes
- **Set `additionalProperties: false`** - Reject unexpected fields in schemas
- **Use enums for fixed values** - Ensures valid options (status, priority, etc.)
- **Document your schemas** - Add descriptions for maintainability
- **Test schemas** - Validate with sample prompts before deployment
- **Describe desired structure in prompts** - For JSON mode, be explicit about fields


### DON'T

- **Over-constrain schemas** - Too strict may fail to generate
- **Use `json` mode for typed systems** - Use `json_schema` for type safety
- **Forget required fields** - Model won't generate without them
- **Nest too deeply** - Keep schemas under 5 levels deep
- **Skip ID fields** - Always provide schema IDs for caching
- **Mix modes** - Choose one approach per use case
- **Ignore validation errors** - Always handle schema validation failures


## Troubleshooting

### Schema Validation Errors


```json
{
 "error": {
 "type": "invalid_request_error",
 "message": "Invalid JSON Schema: property 'age' must be of type 'integer'",
 "code": "invalid_schema"
 }
}
```

**Solution:** Validate your schema against JSON Schema Draft 2020-12 specification.

### Missing Required Fields


```json
{
 "error": {
 "type": "invalid_request_error",
 "message": "jsonSchema is required when outputMode is 'json_schema'",
 "code": "missing_parameter",
 "param": "jsonSchema"
 }
}
```

**Solution:** Always provide `jsonSchema` when using `json_schema` mode.

### Schema Too Complex

If the model struggles to generate output matching a complex schema:

- Simplify nested structures
- Remove overly strict constraints
- Split into multiple requests
- Use `strict: false` for best-effort compliance


## FAQ

**Q: Can I use `json` mode without a schema?**
A: Yes! `json` mode returns valid JSON without requiring a schema. Just set `output_mode: "json"` and describe the desired structure in your prompt.

**Q: What's the difference between `json` and `json_schema` mode?**
A: `json` mode guarantees valid JSON but lets the model decide the structure. `json_schema` mode enforces an exact structure you define. Use `json` for flexibility, `json_schema` for type safety.

**Q: Will JSON mode always return valid JSON?**
A: Yes, both `json` and `json_schema` modes guarantee syntactically valid JSON that can be parsed without errors.

**Q: What JSON Schema version is supported?**
A: JSON Schema Draft 2020-12.

**Q: Is `json_schema` mode slower than `json` mode?**
A: Slightly (~5-10%), but negligible compared to the value of guaranteed structure and type safety.

**Q: Can the model fail to generate valid output?**
A: With `strict: true`, the model always produces valid schema-compliant output. With `strict: false`, it makes best effort. In `json` mode, the model always returns valid JSON.

**Q: How do I handle optional fields?**
A: In `json_schema` mode, don't include them in the `required` array. In `json` mode, mention in your prompt which fields are optional.

**Q: Can I use multiple schemas in one request?**
A: Yes! Provide multiple schemas in the `json_schema` parameter. The model will select the most appropriate one based on context.

**Q: What happens if my prompt conflicts with the schema?**
A: The schema takes precedence. The model will always conform to the schema structure, even if the prompt suggests otherwise.

**Q: Can I use JSON mode with streaming?**
A: Yes, both `json` and `json_schema` modes work with streaming. The JSON will be streamed incrementally.

**Q: How do I debug schema validation errors?**
A: Check that your schema follows JSON Schema Draft 2020-12 specification. Use online validators like jsonschemavalidator.net to test your schema.

**Related:**

- [Create Model Response](/docs/api-reference/responses/create) - API reference
- [Function Calling](/docs/documentation/core-concepts/function-calling) - Structured tool outputs
- [Best Practices](/docs/documentation/best-practices) - Optimization tips