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

# Structured outputs with JSON schema

> Generate type-safe JSON responses with guaranteed schema compliance. Use Zod or Pydantic for validated LLM outputs with full TypeScript/Python support.

**Use Cases**

* Extracting typed fields from unstructured text (invoices, emails, support tickets).
* Pipelines where downstream code requires a guaranteed JSON schema.
* Classification tasks with a controlled output set (enum values, boolean flags).
* Generating config objects or API payloads directly from natural language.

***

## Quick Start

Generate structured JSON responses with guaranteed schema compliance.

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST https://router.toqan.ai/eu/v3/router/responses \
  -H "Authorization: Bearer $TOQAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.6-sol",
    "input": "Extract info: John Doe, 30, john@example.com, knows Python and React",
    "text": {
      "format": {
        "type": "json_schema",
        "name": "user",
        "schema": {
          "type": "object",
          "properties": {
            "name": {"type": "string"},
            "age": {"type": "integer"},
            "email": {"type": "string"},
            "skills": {"type": "array", "items": {"type": "string"}}
          },
          "required": ["name", "age", "email", "skills"],
          "additionalProperties": false
        }
      }
    }
  }'
```

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";
import { z } from "zod";
import { zodTextFormat } from "openai/helpers/zod";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

const UserSchema = z.object({
  name: z.string(),
  age: z.number(),
  email: z.string(),
  skills: z.array(z.string()),
});

const response = await client.responses.parse({
  model: "openai/gpt-5.6-sol",
  input: "Extract info: John Doe, 30, john@example.com, knows Python and React",
  text: { format: zodTextFormat(UserSchema, "user") },
});

const user = response.output_parsed;
console.log(user.name);
console.log(user.skills);
```

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from openai import OpenAI
from pydantic import BaseModel
import os

client = OpenAI(
    api_key=os.environ.get("TOQAN_API_KEY"),
    base_url="https://router.toqan.ai/eu/v3/router",
)

class UserSchema(BaseModel):
    name: str
    age: int
    email: str
    skills: list[str]

response = client.responses.parse(
    model="openai/gpt-5.6-sol",
    input="Extract info: John Doe, 30, john@example.com, knows Python and React",
    text_format=UserSchema,
)

user = response.output_parsed
print(user.name)
print(user.skills)
```

```typescript TypeScript (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";
import { z } from "zod";
import { zodResponseFormat } from "openai/helpers/zod";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

const UserSchema = z.object({
  name: z.string(),
  age: z.number(),
  email: z.string(),
  skills: z.array(z.string()),
});

const response = await client.chat.completions.parse({
  model: "openai/gpt-5.6-sol",
  messages: [
    {
      role: "user",
      content: "Extract info: John Doe, 30, john@example.com, knows Python and React",
    },
  ],
  response_format: zodResponseFormat(UserSchema, "user"),
});

const user = response.choices[0].message.parsed;
console.log(user.name);
console.log(user.skills);
```

## Configuration Options

### Response Format Types

| Type | Description |
| - | - |
| `"text"` | Default response format for text responses |
| `"json_object"` | Basic JSON output (no schema validation) |
| `"json_schema"` | Structured JSON with schema validation |

### Text Mode (Default)

| Parameter | Type | Description |
| - | - | - |
| `type` | `"text"` | Default response format for text outputs |

### JSON Schema Mode

| Parameter | Type | Description |
| - | - | - |
| `type` | `"json_schema"` | Enable schema validation |
| `json_schema.name` | string | Schema name/identifier |
| `json_schema.schema` | object | JSON Schema definition |
| `json_schema.strict` | boolean | Follow the exact schema. Defaults to `false`. Only a subset of JSON Schema is supported when `true`. |

### Simple JSON Mode

| Parameter | Type | Description |
| - | - | - |
| `type` | `"json_object"` | Basic JSON output (no schema) |

## Schema Examples

### Simple Data Extraction

```json JSON theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "type": "json_schema",
  "json_schema": {
    "name": "contact_info",
    "schema": {
      "type": "object",
      "properties": {
        "name": { "type": "string" },
        "email": { "type": "string", "format": "email" },
        "phone": { "type": "string" },
        "company": { "type": "string" }
      },
      "required": ["name", "email"]
    }
  }
}
```

### Complex Nested Structure

```json JSON theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "type": "json_schema",
  "json_schema": {
    "name": "product_analysis",
    "schema": {
      "type": "object",
      "properties": {
        "product": {
          "type": "object",
          "properties": {
            "name": { "type": "string" },
            "price": { "type": "number" },
            "category": { "type": "string" }
          }
        },
        "features": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": { "type": "string" },
              "importance": { "type": "integer", "minimum": 1, "maximum": 5 }
            }
          }
        },
        "summary": { "type": "string" }
      },
      "required": ["product", "features", "summary"]
    }
  }
}
```

## Code examples

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST https://router.toqan.ai/eu/v3/router/responses \
  -H "Authorization: Bearer $TOQAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.6-sol",
    "input": "Extract user information from: John Doe, 30 years old, john@example.com, Software Engineer",
    "text": {
      "format": {
        "type": "json_schema",
        "name": "user_info",
        "schema": {
          "type": "object",
          "properties": {
            "name": {"type": "string"},
            "age": {"type": "integer"},
            "email": {"type": "string"},
            "occupation": {"type": "string"}
          },
          "required": ["name", "age", "email", "occupation"],
          "additionalProperties": false
        }
      }
    }
  }'
```

```bash cURL (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST https://router.toqan.ai/eu/v3/router/chat/completions \
  -H "Authorization: Bearer $TOQAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.6-sol",
    "messages": [
      {
        "role": "user",
        "content": "Extract user information from: John Doe, 30 years old, john@example.com, Software Engineer"
      }
    ],
    "response_format": {
      "type": "json_schema",
      "json_schema": {
        "name": "user_info",
        "schema": {
          "type": "object",
          "properties": {
            "name": {"type": "string"},
            "age": {"type": "integer"},
            "email": {"type": "string"},
            "occupation": {"type": "string"}
          },
          "required": ["name", "age", "email", "occupation"]
        }
      }
    }
  }'
```

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";
import { z } from "zod";
import { zodTextFormat } from "openai/helpers/zod";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

const UserInfoSchema = z.object({
  name: z.string(),
  age: z.number(),
  email: z.string(),
  occupation: z.string(),
});

const response = await client.responses.parse({
  model: "openai/gpt-5.6-sol",
  input: "Extract user information from: John Doe, 30 years old, john@example.com, Software Engineer",
  text: { format: zodTextFormat(UserInfoSchema, "user_info") },
});

const user = response.output_parsed;
console.log(`Name: ${user.name}`);
console.log(`Occupation: ${user.occupation}`);
```

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from openai import OpenAI
from pydantic import BaseModel
import os

client = OpenAI(
    api_key=os.environ.get("TOQAN_API_KEY"),
    base_url="https://router.toqan.ai/eu/v3/router",
)

class UserInfo(BaseModel):
    name: str
    age: int
    email: str
    occupation: str

response = client.responses.parse(
    model="openai/gpt-5.6-sol",
    input="Extract user information from: John Doe, 30 years old, john@example.com, Software Engineer",
    text_format=UserInfo,
)

user = response.output_parsed
print(f"Name: {user.name}")
print(f"Occupation: {user.occupation}")
```

```typescript TypeScript (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";
import { z } from "zod";
import { zodResponseFormat } from "openai/helpers/zod";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

const UserInfoSchema = z.object({
  name: z.string(),
  age: z.number(),
  email: z.string(),
  occupation: z.string(),
});

const response = await client.chat.completions.parse({
  model: "openai/gpt-5.6-sol",
  messages: [
    {
      role: "user",
      content: "Extract user information from: John Doe, 30 years old, john@example.com, Software Engineer",
    },
  ],
  response_format: zodResponseFormat(UserInfoSchema, "user_info"),
});

const user = response.choices[0].message.parsed;
console.log(`Name: ${user.name}`);
console.log(`Occupation: ${user.occupation}`);
```

```python Python (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
from openai import OpenAI
from pydantic import BaseModel
import os

client = OpenAI(
    api_key=os.environ.get("TOQAN_API_KEY"),
    base_url="https://router.toqan.ai/eu/v3/router",
)

class UserInfo(BaseModel):
    name: str
    age: int
    email: str
    occupation: str

response = client.chat.completions.parse(
    model="openai/gpt-5.6-sol",
    messages=[
        {
            "role": "user",
            "content": "Extract user information from: John Doe, 30 years old, john@example.com, Software Engineer",
        }
    ],
    response_format=UserInfo,
)

user = response.choices[0].message.parsed
print(f"Name: {user.name}")
print(f"Occupation: {user.occupation}")
```

## Common Use Cases

> [!NOTE]
>
> The examples in this section use the Chat Completions endpoint. Structured outputs work identically with the Responses API: use `responses.create()` with `text: { format: { type: "json_schema", ... } }` instead of `response_format`.

### Data Extraction

```python Python (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
from openai import OpenAI
from pydantic import BaseModel
from typing import List
import os

client = OpenAI(
    api_key=os.environ.get("TOQAN_API_KEY"),
    base_url="https://router.toqan.ai/eu/v3/router",
)

class LineItem(BaseModel):
    description: str
    quantity: int
    unit_price: float
    total: float

class InvoiceData(BaseModel):
    invoice_number: str
    date: str
    vendor: str
    total_amount: float
    line_items: List[LineItem]

response = client.chat.completions.parse(
    model="openai/gpt-5.6-sol",
    messages=[{
        "role": "user",
        "content": "Extract invoice data from this text: [invoice text]"
    }],
    response_format=InvoiceData
)
```

### Content Analysis

```typescript TypeScript (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";
import { z } from "zod";
import { zodResponseFormat } from "openai/helpers/zod";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

const SentimentSchema = z.object({
  sentiment: z.enum(["positive", "negative", "neutral"]),
  confidence: z.number().min(0).max(1),
  key_phrases: z.array(z.string()),
  summary: z.string(),
});

const response = await client.chat.completions.parse({
  model: "openai/gpt-5.6-sol",
  messages: [
    {
      role: "user",
      content: "Analyze sentiment of this review: [review text]",
    },
  ],
  response_format: zodResponseFormat(SentimentSchema, "sentiment_analysis"),
});
```

### Form Generation

```python Python (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
from openai import OpenAI
from pydantic import BaseModel, Field
from typing import List
import os

client = OpenAI(
    api_key=os.environ.get("TOQAN_API_KEY"),
    base_url="https://router.toqan.ai/eu/v3/router",
)

class SurveyQuestion(BaseModel):
    question: str
    type: str
    options: List[str]

class SurveyForm(BaseModel):
    title: str
    description: str
    questions: List[SurveyQuestion] = Field(
        ...,
        description="List of survey questions with type and options"
    )
    estimated_duration: int = Field(description="Minutes to complete")

response = client.chat.completions.parse(
    model="openai/gpt-5.6-sol",
    messages=[{
        "role": "user",
        "content": "Create a customer satisfaction survey for a restaurant"
    }],
    response_format=SurveyForm
)
```

## Advanced Patterns

### Conditional Schemas

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { z } from "zod";

const ResponseSchema = z.discriminatedUnion("type", [
  z.object({
    type: z.literal("success"),
    data: z.object({
      result: z.string(),
      metadata: z.record(z.any()),
    }),
  }),
  z.object({
    type: z.literal("error"),
    error: z.object({
      code: z.string(),
      message: z.string(),
    }),
  }),
]);
```

### Dynamic Schema Generation

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from typing import List

def create_schema_for_fields(fields: List[str]):
    properties = {}
    for field in fields:
        properties[field] = {"type": "string"}

    return {
        "type": "object",
        "properties": properties,
        "required": fields
    }

# Generate schema based on user input
fields = ["name", "email", "department"]
schema = create_schema_for_fields(fields)
```

### Validation and Error Handling

```python Python (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
from openai import OpenAI
from pydantic import BaseModel
import os

client = OpenAI(
    api_key=os.environ.get("TOQAN_API_KEY"),
    base_url="https://router.toqan.ai/eu/v3/router",
)

prompt = "Extract the following information: John Doe is 30 years old."

class MySchema(BaseModel):
    name: str
    age: int

try:
    response = client.chat.completions.parse(
        model="openai/gpt-5.6-sol",
        messages=[{"role": "user", "content": prompt}],
        response_format=MySchema
    )

    if response.choices[0].message.parsed:
        data = response.choices[0].message.parsed
        # Process validated data
    else:
        # Handle parsing failure
        print("Failed to parse response")

except Exception as e:
    print(f"Error: {e}")
    # Fallback to regular completion
```

## Best Practices

**Schema design:**

* Use descriptive field names.
* Add field descriptions for better results.
* Mark essential fields as required.
* Use appropriate data types and constraints.

**Error handling:**

```typescript TypeScript (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";
import { z } from "zod";
import { zodResponseFormat } from "openai/helpers/zod";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

const parseWithFallback = async (prompt: string, schema: z.ZodTypeAny) => {
  try {
    const response = await client.chat.completions.parse({
      model: "openai/gpt-5.6-sol",
      messages: [{ role: "user", content: prompt }],
      response_format: zodResponseFormat(schema, "data"),
    });

    return response.choices[0].message.parsed;
  } catch (error) {
    console.warn("Structured parsing failed, trying JSON mode");

    // Fallback to basic JSON mode
    const fallback = await client.chat.completions.create({
      model: "openai/gpt-5.6-sol",
      messages: [
        {
          role: "user",
          content: `${prompt}\n\nRespond with valid JSON only.`,
        },
      ],
      response_format: { type: "json_object" },
    });

    const content = fallback.choices[0].message.content;
    if (!content) throw new Error("Empty fallback response");
    return JSON.parse(content);
  }
};
```

**Performance optimization:**

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
# Cache schemas for reuse
schema_cache = {}

def create_schema(schema_name): ...  # replace with your schema factory

def get_cached_schema(schema_name):
    if schema_name not in schema_cache:
        schema_cache[schema_name] = create_schema(schema_name)
    return schema_cache[schema_name]
```

## Troubleshooting

**Schema validation fails**

* Simplify complex nested structures.
* Ensure required fields are clearly specified.
* Check field types match expected data.
* Add field descriptions for clarity.

**Inconsistent outputs**

* Use more specific prompts.
* Add examples in the prompt.
* Lower the temperature (0 to 0.3) for more consistent output.
* Switch to a more capable model.

**Performance issues**

* Reduce schema complexity.
* Cache schema definitions.
* Use appropriate models for task complexity.
* Consider breaking large schemas into smaller ones.

## Limitations

| Limitation | Impact | Workaround |
| - | - | - |
| **Schema complexity** | Large schemas may fail | Break into smaller schemas |
| **Model support** | Not all models support schemas | Use JSON mode as fallback |
| **Nested depth** | Deep nesting may cause issues | Flatten structures when possible |
| **Array validation** | Complex array items challenging | Simplify item schemas |
| **Performance cost** | Schema validation adds latency | Cache and optimize schemas |

## Integration Examples

### Database Integration

```python Python (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
from openai import OpenAI
from pydantic import BaseModel
from typing import Optional
from datetime import datetime
import os

client = OpenAI(
    api_key=os.environ.get("TOQAN_API_KEY"),
    base_url="https://router.toqan.ai/eu/v3/router",
)

class DatabaseRecord(BaseModel):
    id: Optional[int] = None
    name: str
    email: str
    created_at: Optional[datetime] = None

# Generate structured data
response = client.chat.completions.parse(
    model="openai/gpt-5.6-sol",
    messages=[{"role": "user", "content": "Create user record"}],
    response_format=DatabaseRecord
)

# Direct database insertion (example using SQLAlchemy)
record = response.choices[0].message.parsed
# session.add(record)
# session.commit()
```

### API Integration

```typescript TypeScript (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";
import { z } from "zod";
import { zodResponseFormat } from "openai/helpers/zod";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

const ApiResponseSchema = z.object({
  status: z.enum(["success", "error"]),
  data: z.string(),
  message: z.string().nullable().optional(),
});

const generateApiResponse = async (query) => {
  const response = await client.chat.completions.parse({
    model: "openai/gpt-5.6-sol",
    messages: [{ role: "user", content: query }],
    response_format: zodResponseFormat(ApiResponseSchema, "api_response"),
  });

  // Return structured API response
  return response.choices[0].message.parsed;
};
```


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