# Structured outputs

> Constrain a response to a JSON schema.

Ask for JSON that matches a schema with `response_format`. This works on models that list `response_format` or `structured_outputs` in `supported_parameters`.

## Request a schema

**curl**

```bash
curl https://deference.si/v1/chat/completions \
  -H "Authorization: Bearer $DEFERENCE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-5.5",
    "messages": [{ "role": "user", "content": "Extract: Ada paid $12.40 on Oct 8." }],
    "response_format": {
      "type": "json_schema",
      "json_schema": {
        "name": "payment",
        "strict": true,
        "schema": {
          "type": "object",
          "properties": {
            "name": { "type": "string" },
            "amount_usd": { "type": "number" },
            "date": { "type": "string" }
          },
          "required": ["name", "amount_usd", "date"],
          "additionalProperties": false
        }
      }
    }
  }'
```

**Python**

```python
import json, os
from openai import OpenAI

client = OpenAI(base_url="https://deference.si/v1", api_key=os.environ["DEFERENCE_API_KEY"])

response = client.chat.completions.create(
    model="anthropic/claude-sonnet-5.5",
    messages=[{"role": "user", "content": "Extract: Ada paid $12.40 on Oct 8."}],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "payment",
            "strict": True,
            "schema": {
                "type": "object",
                "properties": {
                    "name": {"type": "string"},
                    "amount_usd": {"type": "number"},
                    "date": {"type": "string"},
                },
                "required": ["name", "amount_usd", "date"],
                "additionalProperties": False,
            },
        },
    },
)
print(json.loads(response.choices[0].message.content))
```

**TypeScript**

```typescript
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://deference.si/v1",
  apiKey: process.env.DEFERENCE_API_KEY,
});

const response = await client.chat.completions.create({
  model: "anthropic/claude-sonnet-5.5",
  messages: [{ role: "user", content: "Extract: Ada paid $12.40 on Oct 8." }],
  response_format: {
    type: "json_schema",
    json_schema: {
      name: "payment",
      strict: true,
      schema: {
        type: "object",
        properties: {
          name: { type: "string" },
          amount_usd: { type: "number" },
          date: { type: "string" },
        },
        required: ["name", "amount_usd", "date"],
        additionalProperties: false,
      },
    },
  },
});
console.log(JSON.parse(response.choices[0].message.content ?? "{}"));
```

## Check the result

The message `content` is a JSON string. Parse it, and validate it on your side. A response that stops early with `finish_reason: "length"` can be cut-off JSON, so raise `max_tokens` if parsing fails.

## Models without support

A model that does not support `response_format` ignores the field and answers in prose. Check `supported_parameters` first, or put the schema in the prompt and validate the result.
