GUIDES
Get JSON your app can use.
Request JSON output or a defined schema from a compatible model.
Choose the output format
Select a model whose page lists structured output support. For Chat Completions, response_format controls the format. json_object requests valid JSON; json_schema supplies a schema. Support depends on the model.
For JSON object mode, explicitly ask for JSON in your messages. For schema mode, define the required fields and validate the parsed result in your application.
{
"model": "gpt-4o-mini",
"messages": [
{
"role": "user",
"content": "Return a JSON object with name and age for Alex, who is 28."
}
],
"response_format": {
"type": "json_object"
},
"max_tokens": 256
}A complete schema example
Install the SDK and set TOKELY_API_KEY using Quickstart. Save the following code as structured.py and run python3 structured.py. It prints a Python object such as {'name': 'Alex', 'age': 28}.
import json
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["TOKELY_API_KEY"],
base_url="https://api.tokely.me/v1",
)
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{
"role": "user",
"content": "Extract the name and age: Alex is 28 years old.",
}],
response_format={
"type": "json_schema",
"json_schema": {
"name": "person",
"strict": True,
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"},
},
"required": ["name", "age"],
"additionalProperties": False,
},
},
},
max_tokens=256,
)
message = response.choices[0].message
if message.refusal:
raise ValueError(message.refusal)
if response.choices[0].finish_reason != "stop" or not message.content:
raise ValueError("No complete JSON response; check the output budget")
person = json.loads(message.content)
print(person)Handle incomplete output
Check for a model refusal, an incomplete finish reason and missing content before parsing. A token limit can truncate JSON. Handle parsing and validation failures in your app instead of using an incomplete value.
Responses uses text.format rather than response_format. The request schema differs between endpoints; use an enabled model that supports the selected format.
{
"text": {
"format": {
"type": "json_schema",
"name": "person",
"strict": true,
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "integer"
}
},
"required": [
"name",
"age"
],
"additionalProperties": false
}
}
}
}