Get JSON that matches your JSON schema from open models, through the OpenAI Chat Completions and Responses APIs and the Anthropic Messages API.
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
| 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
pip install openaiimport 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_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.
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
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
pip install anthropicimport 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:
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "'output_config.format' is not supported: use a supported JSON schema"
}
}Errors and limits
- A format that the API does not know returns
400, for exampleresponse_format.type: Input should be 'text'. - A format that the model does not support returns
400with'response_format' is not supported: not available for this model. - The output stops at
max_tokens. A cut answer is not valid JSON, andfinish_reasonis thenlength. Setmax_tokenshigh enough for the reasoning and the JSON together.
See the chat reference, the Responses reference and the Messages reference.
LightOnOCR-2-1B
Convert PDFs and images to Markdown with LightOnOCR-2-1B, served in the EU and US: its model ID, prices and a code example.
Tool calling
Function calling with open models. Define tools, control tool_choice, handle parallel calls and send the results back with the OpenAI or Anthropic SDK.