Structured output
response_format on /v1/chat/completions asks the model for JSON:
response_format |
Reply |
|---|---|
{"type": "json_schema", "json_schema": {...}} |
JSON that follows your schema |
{"type": "json_object"} |
Some valid JSON object (JSON mode); describe the shape you want in the prompt |
Models: the models marked “json” on the models page support
it (every chat model except meta-llama/llama-4-maverick). On other models
the field may be ignored, so validate the reply.
JSON Schema
Section titled “JSON Schema”curl https://api.thetoken.dev/v1/chat/completions \ -H "Authorization: Bearer $TOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "openai/gpt-oss-120b", "messages": [{"role": "user", "content": "Extract: Sara, 34, lives in Jeddah."}], "response_format": { "type": "json_schema", "json_schema": { "name": "person", "strict": true, "schema": { "type": "object", "properties": { "name": {"type": "string"}, "age": {"type": "integer"}, "city": {"type": "string"} }, "required": ["name", "age", "city"], "additionalProperties": false } } } }'import jsonimport osfrom openai import OpenAI
client = OpenAI(base_url="https://api.thetoken.dev/v1", api_key=os.environ["TOKEN_API_KEY"])
schema = { "type": "object", "properties": { "name": {"type": "string"}, "age": {"type": "integer"}, "city": {"type": "string"}, }, "required": ["name", "age", "city"], "additionalProperties": False,}
response = client.chat.completions.create( model="openai/gpt-oss-120b", messages=[{"role": "user", "content": "Extract: Sara, 34, lives in Jeddah."}], response_format={"type": "json_schema", "json_schema": {"name": "person", "strict": True, "schema": schema}},)person = json.loads(response.choices[0].message.content)print(person["name"], person["age"], person["city"])import OpenAI from 'openai'
const client = new OpenAI({ baseURL: 'https://api.thetoken.dev/v1', apiKey: process.env.TOKEN_API_KEY })
const response = await client.chat.completions.create({ model: 'openai/gpt-oss-120b', messages: [{ role: 'user', content: 'Extract: Sara, 34, lives in Jeddah.' }], response_format: { type: 'json_schema', json_schema: { name: 'person', strict: true, schema: { type: 'object', properties: { name: { type: 'string' }, age: { type: 'integer' }, city: { type: 'string' } }, required: ['name', 'age', 'city'], additionalProperties: false, }, }, },})const person = JSON.parse(response.choices[0].message.content ?? '{}')console.log(person)The reply’s content is a JSON string:
{"name": "Sara", "age": 34, "city": "Jeddah"}JSON mode
Section titled “JSON mode”curl https://api.thetoken.dev/v1/chat/completions \ -H "Authorization: Bearer $TOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "deepseek/deepseek-v4.1-flash", "messages": [ {"role": "system", "content": "Reply with a JSON object with keys \"sentiment\" and \"score\"."}, {"role": "user", "content": "The delivery was late but the support team was great."} ], "response_format": {"type": "json_object"} }'Good to know
Section titled “Good to know”- A reply cut off by
max_tokens(finish_reason: "length") is incomplete JSON. Leave room for reasoning models, which think before they answer. - On the Responses API, the same option is
text.format({"type": "json_schema", ...}), as in OpenAI’s API.