# Structured outputs with open models on an OpenAI-compatible API
URL: https://docs.munito.ai/structured-outputs

The Munito AI API can make an open model answer with JSON that matches a JSON schema, or with any valid JSON object, through its OpenAI-compatible and Anthropic-compatible APIs.
Send `response_format` on Chat Completions, `text.format` on Responses, or `output_config.format` on Messages.

| API              | Field                  | Formats                              |
| ---------------- | ---------------------- | ------------------------------------ |
| Chat Completions | `response_format`      | `text`, `json_object`, `json_schema` |
| Responses        | `text.format`          | `text`, `json_object`, `json_schema` |
| Messages         | `output_config.format` | `json_schema`                        |

The OpenAI SDK uses the base URL `https://api.munito.ai/inference/v1`, and the Anthropic SDK uses `https://api.munito.ai/inference`. Both read the key from `MUNITO_API_KEY`.

## Support for each model [#support-for-each-model]

| Model                                  | `json_schema` | `json_object` |
| -------------------------------------- | ------------- | ------------- |
| `qwen/qwen3.8-27b`                     | Yes           | Yes           |
| `zai-org/glm-5.3-flash`                | Yes           | Yes           |
| `deepseek-ai/deepseek-v4-flash`        | Yes           | Yes           |
| `deepseek-ai/deepseek-v4.1-flash-1017` | Yes           | Yes           |
| `aleph-alpha/kolibri-1`                | Yes           | Yes           |
| `google/gemma-4-12b`                   | Yes           | Yes           |

## JSON schema on Chat Completions [#json-schema-on-chat-completions]

```bash
pip install openai
```

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

client = OpenAI(
    base_url="https://api.munito.ai/inference/v1",
    api_key=os.environ["MUNITO_API_KEY"],
)
schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string"},
        "date": {"type": "string"},
        "attendees": {"type": "array", "items": {"type": "string"}},
    },
    "required": ["name", "date", "attendees"],
    "additionalProperties": False,
}
response = client.chat.completions.create(
    model="qwen/qwen3.8-27b",
    messages=[
        {"role": "system", "content": "Extract the event from the text."},
        {"role": "user", "content": "Anna and Tom meet for the budget review on 14 November."},
    ],
    response_format={
        "type": "json_schema",
        "json_schema": {"name": "event", "schema": schema, "strict": True},
    },
    max_tokens=2048,
)
event = json.loads(response.choices[0].message.content)
print(event)
```

The model reasons first, and the reasoning goes to the `reasoning` field. Only the answer in `content` follows the schema.

## JSON mode on Chat Completions [#json-mode-on-chat-completions]

`json_object` makes the model answer with a valid JSON object, with no schema. Ask for JSON in the prompt and name the keys that you want.

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

client = OpenAI(
    base_url="https://api.munito.ai/inference/v1",
    api_key=os.environ["MUNITO_API_KEY"],
)
response = client.chat.completions.create(
    model="qwen/qwen3.8-27b",
    messages=[
        {"role": "user", "content": "Give the capital and the currency of Portugal as JSON with the keys capital and currency."}
    ],
    response_format={"type": "json_object"},
    max_tokens=2048,
)
print(json.loads(response.choices[0].message.content))
```

## JSON schema on Responses [#json-schema-on-responses]

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

client = OpenAI(
    base_url="https://api.munito.ai/inference/v1",
    api_key=os.environ["MUNITO_API_KEY"],
)
response = client.responses.create(
    model="qwen/qwen3.8-27b",
    input="Anna and Tom meet for the budget review on 14 November.",
    instructions="Extract the event from the text.",
    text={
        "format": {
            "type": "json_schema",
            "name": "event",
            "schema": {
                "type": "object",
                "properties": {"name": {"type": "string"}, "date": {"type": "string"}},
                "required": ["name", "date"],
                "additionalProperties": False,
            },
            "strict": True,
        }
    },
    max_output_tokens=2048,
)
print(json.loads(response.output_text))
```

## JSON schema on Messages [#json-schema-on-messages]

```bash
pip install anthropic
```

```python
import json
import os
from anthropic import Anthropic

client = Anthropic(
    base_url="https://api.munito.ai/inference",
    api_key=os.environ["MUNITO_API_KEY"],
)
message = client.messages.create(
    model="qwen/qwen3.8-27b",
    max_tokens=2048,
    messages=[{"role": "user", "content": "Where is the Eiffel Tower?"}],
    extra_body={
        "output_config": {
            "format": {
                "type": "json_schema",
                "schema": {
                    "type": "object",
                    "properties": {"city": {"type": "string"}, "country": {"type": "string"}},
                    "required": ["city", "country"],
                    "additionalProperties": False,
                }
            }
        }
    },
)
text = next(block.text for block in message.content if block.type == "text")
print(json.loads(text))
```

`output_config.format` takes only `type: "json_schema"` and a `schema` object. Another value returns `400`:

```json
{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "message": "'output_config.format' is not supported: use a supported JSON schema"
  }
}
```

## Errors and limits [#errors-and-limits]

- A format that the API does not know returns `400`, for example `response_format.type: Input should be 'text'`.
- A format that the model does not support returns `400` with `'response_format' is not supported: not available for this model`.
- The output stops at `max_tokens`. A cut answer is not valid JSON, and `finish_reason` is then `length`. Set `max_tokens` high enough for the reasoning and the JSON together.

See the [chat reference](https://docs.munito.ai/api/createChatCompletion), the [Responses reference](https://docs.munito.ai/api/createResponse) and the [Messages reference](https://docs.munito.ai/api/createMessage).
